def __init__(self, settings=None, template=None): Generator.__init__(self) if settings is not None and not isinstance(settings, dict): raise TypeError('settings must be a dict') self._settings = settings if template is not None and not isinstance(template, str): raise TypeError('template must be a str') self._template = template
def __init__( self, cpp_exception_includes_definition=None, cpp_exception_parent_class_qname='::thryft::Exception', cpp_service_includes_definition=None, cpp_service_parent_class_qname='::thryft::Service', ): Generator.__init__(self) self.__cpp_exception_includes_definition = cpp_exception_includes_definition if cpp_exception_includes_definition is not None else tuple() self.__cpp_exception_parent_class_qname = cpp_exception_parent_class_qname self.__cpp_service_includes_definition = cpp_service_includes_definition if cpp_service_includes_definition is not None else tuple() self.__cpp_service_parent_class_qname = cpp_service_parent_class_qname
def __init__( self, default_methods=False, exception_type_extends_default='org.thryft.ThryftException', function_overloads=False, mutable_compound_types=False, namespace_prefix=None, thrift_id_java_type='short', write_field_metadata=True, **kwds ): Generator.__init__(self, **kwds) self.__default_methods = default_methods self.__exception_type_extends_default = exception_type_extends_default self.__function_overloads = function_overloads self.__mutable_compound_types = mutable_compound_types self.__namespace_prefix = namespace_prefix self.__thrift_id_java_type = thrift_id_java_type self.__write_field_metadata = write_field_metadata
def _compile_thrift_file(self, thrift_file_path, document_root_dir_path=None, generator=None, out=None): try: for i in xrange(2): if generator is not None: gen = generator.__class__.__name__ gen = gen[:gen.index('Generator')] gen = decamelize(gen) if len(self.__gen) > 0 and gen not in self.__gen: return else: generator = Generator() try: document = \ self.__compiler.compile( document_root_dir_path=document_root_dir_path, generator=generator, thrift_file_path=thrift_file_path, ) except (ScanException, CompileException): if self.__debug: raise if i == 0: logging.basicConfig(level=logging.DEBUG) continue # Try again with debugging on else: raise if out is not None: document.save(out) elif isinstance(generator, LintGenerator): document.lint() return document except: logging.error("exception compiling %s", thrift_file_path) raise
def __init__(self, ts_out_dir_path, ts_share_dir_path, **kwds): Generator.__init__(self, **kwds) self.__ts_out_dir_path = ts_out_dir_path self.__ts_share_dir_path = ts_share_dir_path
def __init__(self, package_name): Generator.__init__(self) self.__package_name = package_name
class __AstVisitor(object): __ROOT_GENERATOR = Generator() def __init__(self, compiler, generator, include_dir_paths): object.__init__(self) self.__compiler = compiler self.__generator = generator self.__include_dir_paths = include_dir_paths self.__scope_stack = [] self.__type_cache = {} def __construct(self, class_name, **kwds): if len(self.__scope_stack) > 0: parent = self.__scope_stack[-1] else: parent = self.__generator kwds['parent'] = parent annotations = kwds.get('annotations') name = kwds.get('name') if annotations is None: native = False elif name is None: native = False else: native = False for annotation in annotations: if annotation == 'native': native = True break if native: for scope in reversed(self.__scope_stack): if not isinstance(scope, Document): continue document = scope overrides_module_file_path = os.path.splitext( document.path)[0] + '.py' if not os.path.isfile(overrides_module_file_path): continue overrides_module_dir_path, overrides_module_file_name = \ os.path.split(overrides_module_file_path) overrides_module_name = \ os.path.splitext(overrides_module_file_name)[0] try: overrides_module = \ imp.load_module( overrides_module_name, *imp.find_module( overrides_module_name, [overrides_module_dir_path] ) ) except ImportError: logging.error("error importing overrides module %s", overrides_module_file_path, exc_info=True) continue # Find an override implementation corresponding to our generator # For example, find JavaDateTime by looking in the module for a # class that inherits JavaNativeType. # The first_bases algorithm below covers the case where we want # JavaDateTime but the generator gave us something that itself # inherits from JavaStructType e.g., SubJavaStructType. # In this case there is no SubJavaDateTime(SubJavaStructType), so # we need to consider SubJavaStructType's parent (JavaStructType) # and look for a subclass of that. root_construct_class = getattr(self.__ROOT_GENERATOR, 'NativeType') generator_construct_class = getattr( self.__generator, 'NativeType') parent_construct_classes = [generator_construct_class] def __get_first_bases(class_, first_bases): if len(class_.__bases__) == 0: return first_base = class_.__bases__[0] if first_base is object or first_base is root_construct_class: return if first_base.__name__[0] != '_': first_bases.append(first_base) __get_first_bases(first_base, first_bases) __get_first_bases(generator_construct_class, parent_construct_classes) for parent_construct_class in parent_construct_classes: for attr in dir(overrides_module): value = getattr(overrides_module, attr) if isclass(value) and \ issubclass(value, parent_construct_class) and \ value != parent_construct_class: return getattr(overrides_module, attr)(**kwds) # logging.warn("could not find override class for %s in %s" % (default_construct_class.__name__, overrides_module_name)) return getattr(self.__generator, class_name)(**kwds) def visit_annotation_node(self, annotation_node): return annotation_node.value def __visit_annotation_nodes(self, annotation_nodes): if annotation_nodes is None: return {} return dict((annotation_node.name, annotation_node.accept(self)) for annotation_node in annotation_nodes) def visit_base_type_node(self, base_type_node): try: return self.__type_cache[base_type_node.name] except: base_type = getattr(self.__generator, base_type_node.name.capitalize() + 'Type')(name=base_type_node.name) self.__type_cache[base_type_node.name] = base_type return base_type def visit_bool_literal_node(self, bool_literal_node): return bool_literal_node.value def __visit_compound_type_node(self, construct_class_name, compound_type_node): compound_type = \ self.__construct( construct_class_name, annotations=self.__visit_annotation_nodes(compound_type_node.annotations), doc=self.__visit_doc_node(compound_type_node.doc), name=compound_type_node.name ) if isinstance(compound_type, NativeType): return compound_type self.__scope_stack.append(compound_type) # Insert the compound type into the type_map here to allow recursive # definitions self.__type_cache[compound_type.thrift_qname()] = compound_type if construct_class_name == 'EnumType': have_enumerator_with_value = False for enumerator_node in compound_type_node.enumerators: if enumerator_node.value is not None: have_enumerator_with_value = True elif have_enumerator_with_value: raise CompileException( "%s has mix of enumerators with and without values, must be one or the other" % compound_type_node.name, ast_node=compound_type_node) for enumerator_i, enumerator_node in enumerate( compound_type_node.enumerators): if enumerator_node.value is None: value = enumerator_i else: assert isinstance(enumerator_node.value, Ast.IntLiteralNode), type( enumerator_node.value) value = enumerator_node.value.value compound_type.enumerators.append( self.__construct( 'Field', annotations=self.__visit_annotation_nodes( enumerator_node.annotations), doc=self.__visit_doc_node(enumerator_node.doc), id=enumerator_i, name=enumerator_node.name, type=Ast.BaseTypeNode('i32').accept(self), value=value)) else: for field in compound_type_node.fields: compound_type.fields.append(field.accept(self)) self.__scope_stack.pop(-1) return compound_type def visit_const_node(self, const_node): return \ self.__construct( 'Const', annotations=self.__visit_annotation_nodes(const_node.annotations), doc=self.__visit_doc_node(const_node.doc), name=const_node.name, type=const_node.type.accept(self), value=const_node.value.accept(self) ) def __visit_doc_node(self, doc_node): if doc_node is not None: return doc_node.text else: return None def visit_document_node(self, document_node): document = self.__construct('Document', path=document_node.path) self.__scope_stack.append(document) for header_node in document_node.headers: document.headers.append(header_node.accept(self)) for definition_node in document_node.definitions: document.definitions.append(definition_node.accept(self)) self.__scope_stack.pop(-1) return document def visit_enum_type_node(self, enum_node): return self.__visit_compound_type_node('EnumType', enum_node) def visit_exception_type_node(self, exception_type_node): return self.__visit_compound_type_node('ExceptionType', exception_type_node) def visit_field_node(self, field_node): return \ self.__construct( 'Field', annotations=self.__visit_annotation_nodes(field_node.annotations), doc=self.__visit_doc_node(field_node.doc), id=field_node.id, name=field_node.name, required=field_node.required, type=field_node.type.accept(self), value=field_node.value ) def visit_float_literal_node(self, float_literal_node): return float_literal_node.value def visit_function_node(self, function_node): function = \ self.__construct( 'Function', annotations=self.__visit_annotation_nodes(function_node.annotations), doc=self.__visit_doc_node(function_node.doc), name=function_node.name, oneway=function_node.oneway ) self.__scope_stack.append(function) for parameter_node in function_node.parameters: function.parameters.append(parameter_node.accept(self)) if function_node.return_field is not None: function.return_field = function_node.return_field.accept(self) for throws_node in function_node.throws: function.throws.append(throws_node.accept(self)) self.__scope_stack.pop(-1) return function def visit_include_node(self, include_node): include_dir_paths = list(self.__include_dir_paths) for scope in reversed(self.__scope_stack): if isinstance(scope, Document): include_dir_paths.append(os.path.dirname(scope.path)) break include_file_relpath = include_node.path.replace('/', os.path.sep) for include_dir_path in include_dir_paths: include_file_path = os.path.join(include_dir_path, include_file_relpath) if os.path.exists(include_file_path): include_file_path = os.path.abspath(include_file_path) included_document = self.__compiler.compile( (include_file_path, ), generator=self.__generator)[0] include = \ self.__construct( 'Include', annotations=self.__visit_annotation_nodes(include_node.annotations), doc=self.__visit_doc_node(include_node.doc), document=included_document, path=include_file_relpath ) for definition in included_document.definitions: if isinstance(definition, _Type): self.__type_cache[ definition.thrift_qname()] = definition elif isinstance(definition, Typedef): self.__type_cache[definition.thrift_qname( )] = definition # .type return include raise CompileException("include path not found: %s" % include_file_relpath, ast_node=include_node) def visit_int_literal_node(self, int_literal_node): return int_literal_node.value def visit_list_literal_node(self, list_literal_node): return tuple( element_value.accept(self) for element_value in list_literal_node.value) def visit_list_type_node(self, list_type_node): return self.__visit_sequence_type_node('ListType', list_type_node) def visit_map_literal_node(self, map_literal_node): return dict((key_value.accept(self), value_value.accept(self)) for key_value, value_value in map_literal_node.value.iteritems()) def visit_map_type_node(self, map_type_node): try: return self.__type_cache[map_type_node.name] except: map_type = self.__construct( 'MapType', key_type=map_type_node.key_type.accept(self), value_type=map_type_node.value_type.accept(self)) self.__type_cache[map_type_node.name] = map_type return map_type def visit_namespace_node(self, namespace_node): return \ self.__construct( 'Namespace', annotations=self.__visit_annotation_nodes(namespace_node.annotations), doc=self.__visit_doc_node(namespace_node.doc), name=namespace_node.name, scope=namespace_node.scope ) def __visit_sequence_type_node(self, construct_class_name, sequence_type_node): try: return self.__type_cache[sequence_type_node.name] except: sequence_type = self.__construct( construct_class_name, element_type=sequence_type_node.element_type.accept(self)) self.__type_cache[sequence_type_node.name] = sequence_type return sequence_type def visit_service_node(self, service_node): service = \ self.__construct( 'Service', annotations=self.__visit_annotation_nodes(service_node.annotations), doc=self.__visit_doc_node(service_node.doc), name=service_node.name ) self.__scope_stack.append(service) for function_node in service_node.functions: service.functions.append(function_node.accept(self)) self.__scope_stack.pop(-1) return service def visit_set_type_node(self, set_type_node): return self.__visit_sequence_type_node('SetType', set_type_node) def visit_string_literal_node(self, string_literal_node): return string_literal_node.value def visit_struct_type_node(self, struct_type_node): return \ self.__visit_compound_type_node( 'StructType', struct_type_node, ) def visit_type_node(self, type_node): try: try: return self.__type_cache[type_node.qname] except KeyError: if type_node.qname == type_node.name: document = self.__scope_stack[0] return self.__type_cache[document.name + '.' + type_node.qname] else: raise except KeyError: raise CompileException("unrecognized type '%s'" % type_node.qname, ast_node=type_node) def visit_typedef_node(self, typedef_node): typedef = \ self.__construct( 'Typedef', annotations=self.__visit_annotation_nodes(typedef_node.annotations), doc=self.__visit_doc_node(typedef_node.doc), name=typedef_node.name, type=typedef_node.type.accept(self) ) self.__type_cache[typedef.thrift_qname()] = typedef.type return typedef
def __init__(self, import_base): Generator.__init__(self) self.__import_base = import_base
def __init__(self, default_methods=False, function_overloads=False, mutable_compound_types=False, namespace_prefix=None, **kwds): Generator.__init__(self, **kwds) self.__default_methods = default_methods self.__function_overloads = function_overloads self.__mutable_compound_types = mutable_compound_types self.__namespace_prefix = namespace_prefix
def __init__(self, match_namespace_to_path=True, **kwds): Generator.__init__(self, **kwds) self._match_namespace_to_path = match_namespace_to_path
def __init__(self, **kwds): Generator.__init__(self, **kwds) self.ts_out_dir_path = None