blob: 062a64de9b3fc5ce9235640b4f93161a85cfaaaa [file] [log] [blame]
# Prototype of an Intermediate Object model for the java code generator
# A lot of this stuff could/should probably be merged with the python utilities
import of_g
import os
import pdb
import re
import loxi_front_end.type_maps as type_maps
import loxi_utils.loxi_utils as utils
import py_gen.util as py_utils
import java_gen.java_utils as java_utils
ignore_fields = ['version', 'xid', 'length', 'type' ]
protected_fields = ['version', 'length']
class JavaOFVersion(object):
""" Models a version of OpenFlow. contains methods to convert the internal
Loxi version to a java constant / a string """
def __init__(self, int_version):
self.int_version = int(int_version)
@property
def of_version(self):
return "1" + str(int(self.int_version) - 1)
@property
def constant_version(self):
return "OF_" + self.of_version
def __str__(self):
return of_g.param_version_names[self.int_version]
class JavaProperty(object):
""" Models a property (member) of an openflow class. """
def __init__(self, msg, java_type, c_type, name, c_name):
self.msg = msg
self.java_type = java_type
self.c_type = c_type
self.name = name
self.c_name = c_name
@property
def title_name(self):
return self.name[0].upper() + self.name[1:]
@property
def constant_name(self):
return self.c_name.upper()
@property
def default_name(self):
return "DEFAULT_"+self.constant_name
@property
def default_value(self):
java_type = self.java_type.public_type;
if re.match(r'List.*', java_type):
return "Collections.emptyList()"
elif java_type == "boolean":
return "false";
elif java_type in ("byte", "char", "short", "int", "long"):
return "({0}) 0".format(java_type);
else:
return "null";
@property
def is_pad(self):
return self.c_name.startswith("pad")
@property
def length(self):
count, base = utils.type_dec_to_count_base(self.c_type)
return of_g.of_base_types[base]['bytes'] * count
@staticmethod
def for_field(msg, field, c_name=None):
if not c_name:
c_name = field['name']
name = java_utils.name_c_to_camel(c_name)
java_type = java_utils.convert_to_jtype(msg.c_name, c_name, field['m_type'])
c_type = field['m_type']
return JavaProperty(msg, java_type, c_type, name, c_name)
@property
def is_universal(self):
for version in of_g.unified[self.msg.c_name]:
if version == 'union' or version =='object_id':
continue
if 'use_version' in of_g.unified[self.msg.c_name][version]:
continue
if not self.c_name in (f['name'] for f in of_g.unified[self.msg.c_name][version]['members']):
return False
return True
class JavaOFMessage(object):
""" Models an OpenFlow Message class """
def __init__(self, c_name):
self.c_name = c_name
self.interface_name = java_utils.name_c_to_caps_camel(c_name)
self.builder_name = self.interface_name + "Builder"
self.constant_name = c_name.upper().replace("OF_", "")
def min_length(self, version):
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
def is_fixed_length(self, version):
return (self.c_name, version.int_version) in of_g.is_fixed_length
def class_name_for_version(self, version):
return self.interface_name + "Ver"+version.of_version
def all_properties(self, skip_pads=True):
if 'union' in of_g.unified[self.c_name]:
props = []
fields = of_g.unified[self.c_name]['union']
for field_name in sorted( fields.keys(), key=lambda k: fields[k]['memid']):
if field_name in ignore_fields:
continue
if skip_pads and field_name.startswith("pad"):
continue
java_property = JavaProperty.for_field(self, fields[field_name], c_name=field_name)
props.append(java_property)
return props
else:
return []
def all_versions(self):
return [ JavaOFVersion(int_version)
for int_version in of_g.unified[self.c_name]
if int_version != 'union' and int_version != 'object_id' ]
def property_in_version(self, prop, version):
if self.version_is_inherited(version):
version = self.inherited_from(version)
if 'members' not in of_g.unified[self.c_name][version.int_version]:
return False
return prop.c_name in (member['name'] for member in of_g.unified[self.c_name][version.int_version]['members'])
def properties_for_version(self, version, skip_pads=True):
props = []
if self.version_is_inherited(version):
version = self.inherited_from(version)
for field in of_g.unified[self.c_name][version.int_version]['members']:
if field['name'] in ignore_fields:
continue
if skip_pads and field['name'].startswith("pad"):
continue
java_property = JavaProperty.for_field(self, field, c_name=field['name'])
props.append(java_property)
return props
def version_is_inherited(self, version):
return 'use_version' in of_g.unified[self.c_name][version.int_version]
def inherited_from(self, version):
return JavaOFVersion(of_g.unified[self.c_name][version.int_version]['use_version'])
@property
def is_virtual(self):
return type_maps.class_is_virtual(self.c_name)
@property
def is_extension(self):
return type_maps.message_is_extension(self.c_name, -1)
def wire_type(self, version):
try:
return py_utils.primary_wire_type(self.c_name, version.int_version)
except ValueError, e:
return -1