blob: 062a64de9b3fc5ce9235640b4f93161a85cfaaaa [file] [log] [blame]
Andreas Wundsam40e14f72013-05-06 14:49:08 -07001# Prototype of an Intermediate Object model for the java code generator
2# A lot of this stuff could/should probably be merged with the python utilities
3
4import of_g
5import os
6import pdb
7import re
8
9import loxi_front_end.type_maps as type_maps
10import loxi_utils.loxi_utils as utils
11import py_gen.util as py_utils
12
13import java_gen.java_utils as java_utils
14ignore_fields = ['version', 'xid', 'length', 'type' ]
15
16protected_fields = ['version', 'length']
17
18class JavaOFVersion(object):
19 """ Models a version of OpenFlow. contains methods to convert the internal
20 Loxi version to a java constant / a string """
21 def __init__(self, int_version):
22 self.int_version = int(int_version)
23
24 @property
25 def of_version(self):
26 return "1" + str(int(self.int_version) - 1)
27
28 @property
29 def constant_version(self):
30 return "OF_" + self.of_version
31
32 def __str__(self):
33 return of_g.param_version_names[self.int_version]
34
35class JavaProperty(object):
36 """ Models a property (member) of an openflow class. """
37 def __init__(self, msg, java_type, c_type, name, c_name):
38 self.msg = msg
39 self.java_type = java_type
40 self.c_type = c_type
41 self.name = name
42 self.c_name = c_name
43
44 @property
45 def title_name(self):
46 return self.name[0].upper() + self.name[1:]
47
48 @property
49 def constant_name(self):
50 return self.c_name.upper()
51
52 @property
53 def default_name(self):
54 return "DEFAULT_"+self.constant_name
55
56 @property
57 def default_value(self):
58 java_type = self.java_type.public_type;
59
60 if re.match(r'List.*', java_type):
61 return "Collections.emptyList()"
62 elif java_type == "boolean":
63 return "false";
64 elif java_type in ("byte", "char", "short", "int", "long"):
65 return "({0}) 0".format(java_type);
66 else:
67 return "null";
68
69 @property
70 def is_pad(self):
71 return self.c_name.startswith("pad")
72
73 @property
74 def length(self):
75 count, base = utils.type_dec_to_count_base(self.c_type)
76 return of_g.of_base_types[base]['bytes'] * count
77
78 @staticmethod
79 def for_field(msg, field, c_name=None):
80 if not c_name:
81 c_name = field['name']
82
83 name = java_utils.name_c_to_camel(c_name)
84 java_type = java_utils.convert_to_jtype(msg.c_name, c_name, field['m_type'])
85 c_type = field['m_type']
86 return JavaProperty(msg, java_type, c_type, name, c_name)
87
88 @property
89 def is_universal(self):
90 for version in of_g.unified[self.msg.c_name]:
91 if version == 'union' or version =='object_id':
92 continue
93 if 'use_version' in of_g.unified[self.msg.c_name][version]:
94 continue
95
96 if not self.c_name in (f['name'] for f in of_g.unified[self.msg.c_name][version]['members']):
97 return False
98 return True
99
100class JavaOFMessage(object):
101 """ Models an OpenFlow Message class """
102 def __init__(self, c_name):
103 self.c_name = c_name
104 self.interface_name = java_utils.name_c_to_caps_camel(c_name)
105 self.builder_name = self.interface_name + "Builder"
106 self.constant_name = c_name.upper().replace("OF_", "")
107
108 def min_length(self, version):
109 return of_g.base_length[(self.c_name, version.int_version)] if (self.c_name, version.int_version) in of_g.base_length else -1
110
111 def is_fixed_length(self, version):
112 return (self.c_name, version.int_version) in of_g.is_fixed_length
113
114 def class_name_for_version(self, version):
115 return self.interface_name + "Ver"+version.of_version
116
117
118 def all_properties(self, skip_pads=True):
119 if 'union' in of_g.unified[self.c_name]:
120 props = []
121 fields = of_g.unified[self.c_name]['union']
122 for field_name in sorted( fields.keys(), key=lambda k: fields[k]['memid']):
123 if field_name in ignore_fields:
124 continue
125 if skip_pads and field_name.startswith("pad"):
126 continue
127
128 java_property = JavaProperty.for_field(self, fields[field_name], c_name=field_name)
129 props.append(java_property)
130 return props
131 else:
132 return []
133
134 def all_versions(self):
135 return [ JavaOFVersion(int_version)
136 for int_version in of_g.unified[self.c_name]
137 if int_version != 'union' and int_version != 'object_id' ]
138
139 def property_in_version(self, prop, version):
140 if self.version_is_inherited(version):
141 version = self.inherited_from(version)
142
143 if 'members' not in of_g.unified[self.c_name][version.int_version]:
144 return False
145 return prop.c_name in (member['name'] for member in of_g.unified[self.c_name][version.int_version]['members'])
146
147 def properties_for_version(self, version, skip_pads=True):
148 props = []
149 if self.version_is_inherited(version):
150 version = self.inherited_from(version)
151
152 for field in of_g.unified[self.c_name][version.int_version]['members']:
153 if field['name'] in ignore_fields:
154 continue
155 if skip_pads and field['name'].startswith("pad"):
156 continue
157
158 java_property = JavaProperty.for_field(self, field, c_name=field['name'])
159 props.append(java_property)
160 return props
161
162 def version_is_inherited(self, version):
163 return 'use_version' in of_g.unified[self.c_name][version.int_version]
164
165 def inherited_from(self, version):
166 return JavaOFVersion(of_g.unified[self.c_name][version.int_version]['use_version'])
167
168 @property
169 def is_virtual(self):
170 return type_maps.class_is_virtual(self.c_name)
171
172 @property
173 def is_extension(self):
174 return type_maps.message_is_extension(self.c_name, -1)
175
176 def wire_type(self, version):
177 try:
178 return py_utils.primary_wire_type(self.c_name, version.int_version)
179 except ValueError, e:
180 return -1