Example #1
0
 def __init__(self, model_registry=None):
     self.model_registry = model_registry
     if self.model_registry is None:
         from unimodel.model import ModelRegistry
         self.model_registry = ModelRegistry()
     self._spec_cache = {}
     self.tuple_type_cache = {}
Example #2
0
class ThriftSpecFactory(object):

    def __init__(self, model_registry=None):
        self.model_registry = model_registry
        if self.model_registry is None:
            from unimodel.model import ModelRegistry
            self.model_registry = ModelRegistry()
        self._spec_cache = {}
        self.tuple_type_cache = {}

    def get_spec(self, struct_class):
        if struct_class not in self._spec_cache:
            self._spec_cache[
                struct_class] = self.get_spec_for_struct(struct_class)
        return self._spec_cache[struct_class]

    def get_spec_for_struct(self, struct_class):
        field_list = sorted(
            struct_class.get_field_definitions(),
            key=lambda x: x.field_id)
        thrift_spec = [None]
        # save the spec to cache so recurisve data structures work.
        self._spec_cache[struct_class] = thrift_spec
        for f in field_list:
            thrift_spec.append(self.get_spec_for_field(f))
        return thrift_spec

    def get_tuple_type_parameter(self, field_type):
        # tuple_id =
        #    (implementation_class, self.get_spec(implementation_class))
        ta = ThriftTupleAdapter(Field(field_type), None)
        return (ta.tuple_struct_class, self.get_spec(ta.tuple_struct_class))


    def get_spec_type_parameter(self, field_type):
        """ Returns value 3 of the element
            in thrift_spec which defines this field. """
        # tuples are encoded as structs
        if isinstance(field_type, types.Tuple):
            return self.get_tuple_type_parameter(field_type)
        # structs are a special case
        if isinstance(field_type, types.Struct):
            interface_class = field_type.get_python_type()
            implementation_class = self.model_registry.lookup(interface_class)
            return (implementation_class, self.get_spec(implementation_class))
        # If there are no type parameters, return None
        if not field_type.type_parameters:
            return None
        # lists, sets, maps
        spec_list = []
        for t in field_type.type_parameters:
            # for each type_parameter, first add the type's id
            spec_list.append(get_backend_type("thrift", t.type_id))
            # then the type's parameters
            spec_list.append(self.get_spec_type_parameter(t))
        return spec_list

    def get_spec_for_field(self, field):
        return (
            field.field_id,
            get_backend_type("thrift", field.field_type.type_id),
            field.field_name,
            self.get_spec_type_parameter(field.field_type),
            field.default,)