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
Example #2
0
 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
Example #3
0
 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
Example #4
0
 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
Example #5
0
    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
Example #6
0
 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
Example #7
0
 def __init__(self, package_name):
     Generator.__init__(self)
     self.__package_name = package_name
Example #8
0
    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
Example #9
0
 def __init__(self, import_base):
     Generator.__init__(self)
     self.__import_base = import_base
Example #10
0
 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
Example #11
0
 def __init__(self, match_namespace_to_path=True, **kwds):
     Generator.__init__(self, **kwds)
     self._match_namespace_to_path = match_namespace_to_path
Example #12
0
 def __init__(self, **kwds):
     Generator.__init__(self, **kwds)
     self.ts_out_dir_path = None