blob: f40cecc9e2cb7220eb32146833a9400e292ef594 [file] [log] [blame]
Rich Lanea06d0c32013-03-25 08:52:03 -07001# Copyright 2013, Big Switch Networks, Inc.
2#
3# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
4# the following special exception:
5#
6# LOXI Exception
7#
8# As a special exception to the terms of the EPL, you may distribute libraries
9# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
10# that copyright and licensing notices generated by LoxiGen are not altered or removed
11# from the LoxiGen Libraries and the notice provided below is (i) included in
12# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
13# documentation for the LoxiGen Libraries, if distributed in binary form.
14#
15# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
16#
17# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
18# a copy of the EPL at:
19#
20# http://www.eclipse.org/legal/epl-v10.html
21#
22# Unless required by applicable law or agreed to in writing, software
23# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
24# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
25# EPL for the specific language governing permissions and limitations
26# under the EPL.
27
28"""
29Python backend for LOXI
30
31This language specific file defines a dictionary 'targets' that
32defines the generated files and the functions used to generate them.
33
34For each generated file there is a generate_* function in py_gen.codegen
35and a Tenjin template under py_gen/templates.
36
37Target directory structure:
38 pyloxi:
39 loxi:
40 __init__.py
41 of10:
42 __init__.py
43 action.py # Action classes
44 common.py # Structs shared by multiple messages
45 const.py # OpenFlow constants
46 message.py # Message classes
47 util.py # Utility functions
Rich Lanea22233e2013-04-25 13:18:41 -070048 of11: ... # (code generation incomplete)
Rich Lanee02314c2013-05-02 16:42:04 -070049 instruction.py # Instruction classes
Rich Lanea22233e2013-04-25 13:18:41 -070050 of12: ... # (code generation incomplete)
Rich Laneea693752013-03-18 11:05:45 -070051 oxm.py # OXM classes
Rich Lanea22233e2013-04-25 13:18:41 -070052 of13: ... # (code generation incomplete)
Rich Laned82c0a62013-05-02 15:40:35 -070053 meter_band.py # Meter band classes
Rich Lanea06d0c32013-03-25 08:52:03 -070054
55The user will add the pyloxi directory to PYTHONPATH. Then they can
56"import loxi" or "import loxi.of10". The idiomatic import is
57"import loxi.of10 as ofp". The protocol modules (e.g. of10) import
58all of their submodules, so the user can access "ofp.message" without
59further imports. The protocol modules also import the constants from
60the const module directly into their namespace so the user can access
61"ofp.OFPP_NONE".
62"""
63
Rich Laneda5446f2013-11-10 17:21:48 -080064import os
Andreas Wundsam5630c422013-11-15 13:43:11 -080065from loxi_globals import OFVersions
66import loxi_globals
Rich Laneda5446f2013-11-10 17:21:48 -080067import loxi_utils.loxi_utils as loxi_utils
Rich Lanea06d0c32013-03-25 08:52:03 -070068import py_gen
69import py_gen.util
70import py_gen.codegen
Andreas Wundsam5420b952013-11-15 13:41:01 -080071import template_utils
Rich Lanea06d0c32013-03-25 08:52:03 -070072
73versions = {
74 1: "of10",
Jonathan Stout3edbac92013-04-05 11:30:49 -040075 2: "of11",
76 3: "of12",
Rich Lane3f075972013-03-15 22:56:29 -070077 4: "of13",
Rich Lanea06d0c32013-03-25 08:52:03 -070078}
79
80prefix = 'pyloxi/loxi'
81
Rich Laneea693752013-03-18 11:05:45 -070082modules = {
83 1: ["action", "common", "const", "message", "util"],
Rich Lanee02314c2013-05-02 16:42:04 -070084 2: ["action", "common", "const", "instruction", "message", "util"],
85 3: ["action", "common", "const", "instruction", "message", "oxm", "util"],
86 4: ["action", "common", "const", "instruction", "message", "meter_band", "oxm", "util"],
Rich Laneea693752013-03-18 11:05:45 -070087}
Rich Lanea06d0c32013-03-25 08:52:03 -070088
89def make_gen(name, version):
90 fn = getattr(py_gen.codegen, "generate_" + name)
91 return lambda out, name: fn(out, name, version)
92
93def static(template_name):
94 return lambda out, name: py_gen.util.render_template(out, template_name)
95
96targets = {
97 prefix+'/__init__.py': static('toplevel_init.py'),
98 prefix+'/pp.py': static('pp.py'),
Rich Lane15cbe842013-04-26 16:04:11 -070099 prefix+'/generic_util.py': static('generic_util.py'),
Rich Lanea06d0c32013-03-25 08:52:03 -0700100}
101
102for version, subdir in versions.items():
103 targets['%s/%s/__init__.py' % (prefix, subdir)] = make_gen('init', version)
Rich Laneea693752013-03-18 11:05:45 -0700104 for module in modules[version]:
Rich Lanea06d0c32013-03-25 08:52:03 -0700105 filename = '%s/%s/%s.py' % (prefix, subdir, module)
Andreas Wundsam5630c422013-11-15 13:43:11 -0800106 targets[filename] = make_gen(module, OFVersions.from_wire(version))
Rich Laneda5446f2013-11-10 17:21:48 -0800107
Andreas Wundsam5420b952013-11-15 13:41:01 -0800108def generate(install_dir):
Rich Lanefa931272013-11-10 17:43:50 -0800109 py_gen.codegen.init()
Rich Laneda5446f2013-11-10 17:21:48 -0800110 for (name, fn) in targets.items():
Andreas Wundsam5420b952013-11-15 13:41:01 -0800111 with template_utils.open_output(install_dir, name) as outfile:
Rich Laneda5446f2013-11-10 17:21:48 -0800112 fn(outfile, os.path.basename(name))