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 = {}
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,)