class ObjectiveCGenerator(Generator): '''Objective-C code generator.''' @classmethod def create_cli(cls): return ObjectiveCGeneratorCli() def __init__(self, out, prefixes=None): '''Create a new generator.''' super(ObjectiveCGenerator, self).__init__(out) self.prefix_mapper = PrefixMapper(prefixes) self.filters = _ObjectiveCFilters(self.prefix_mapper) self.templates = Templates(__file__, filters=self.filters) def generate(self, package): '''Generate a package source code.''' for module in package.modules: for definition in module.definitions: self._generate_header(definition) self._generate_impl(definition) self._generate_package(package) def _generate_header(self, definition): '''Generate a definition header file.''' code = self.templates.render(HEADER_TEMPLATE, definition=definition) filename = '%s.h' % self.filters.objc_name(definition) self.write_file(filename, code) return code def _generate_impl(self, definition): '''Generate a definition implementation file.''' code = self.templates.render(IMPL_TEMPLATE, definition=definition) filename = '%s.m' % self.filters.objc_name(definition) self.write_file(filename, code) return code def _generate_package(self, package): '''Generate a package file which groups all headers.''' code = self.templates.render(PACKAGE_TEMPLATE, package=package) names = set() for module in package.modules: for definition in module.definitions: names.add(self.filters.objc_name(definition).lower()) # Generate a unique package file name. name = package.name while name in names: name += '_package' # Convert it into a CamelCase string. name = name.title().replace('_', '') # Write the package header file. filename = '%s.h' % name self.write_file(filename, code) return code
class ExampleGenerator(Generator): """Example generator template.""" @classmethod def create_cli(cls): """Create and return a generator command-line interface.""" return ExampleGeneratorCli() def __init__(self, out, module_names=None, prefixes=None): """Create a new generator.""" super(ExampleGenerator, self).__init__(out) self.module_mapper = ModuleMapper(module_names) self.prefix_mapper = PrefixMapper(prefixes) # Generator filters available in jinja templates. self.filters = ExampleFilters(self.module_mapper, self.prefix_mapper) # Jinja templates relative to this file. self.templates = Templates(__file__, filters=self.filters) def generate(self, package): """Generate a package source code.""" for module in package.modules: for definition in module.definitions: code = self._generate_definition(definition) filename = self._definition_filename(definition) self.write_file(filename, code) code = self.templates.render(MODULE_TEMPLATE, module=module) filename = self._module_filename(module) self.write_file(filename, code) def _generate_definition(self, definition): if definition.is_enum: return self.templates.render(ENUM_TEMPLATE, enum=definition) elif definition.is_message: return self.templates.render(MESSAGE_TEMPLATE, message=definition) elif definition.is_interface: return self.templates.render(INTERFACE_TEMPLATE, interface=definition) raise ValueError("Unsupported definition %r" % definition) def _definition_filename(self, definition): dirname = self._module_directory(definition.module) name = self.filters.example_name(definition) return "%s/%s.json" % (dirname, name) def _module_directory(self, module): """Return a module directory name from a module.fullname.""" name = self.filters.example_module(module) return name.replace(".", "/") def _module_filename(self, module): """Return a module filename.""" dirname = self._module_directory(module) return "%s.json" % dirname
class JavaGenerator(Generator): '''Java code generator.''' @classmethod def create_cli(cls): return JavaGeneratorCli() def __init__(self, out, module_names=None, prefixes=None): super(JavaGenerator, self).__init__(out) self.module_mapper = ModuleMapper(module_names) self.prefix_mapper = PrefixMapper(prefixes) self.filters = _JavaFilters(self.module_mapper, self.prefix_mapper) self.templates = Templates(__file__, filters=self.filters) def generate(self, package): for module in package.modules: for def0 in module.definitions: self._write(def0) def _write(self, def0): # Render the code. code = self._render(def0) # Create module directories. package_path = self._package_path(def0) mkdir_p(package_path) # Write a file. path = self._file_path(def0) with io.open(path, 'wt', encoding=UTF8) as f: f.write(code) logging.debug('Created %s', path) def _render(self, def0): if def0.is_enum: return self.templates.render(ENUM_TEMPLATE, enum=def0, generated_by=GENERATED_BY) elif def0.is_message: return self.templates.render(MESSAGE_TEMPLATE, message=def0, generated_by=GENERATED_BY) elif def0.is_interface: return self.templates.render(INTERFACE_TEMPLATE, interface=def0, generated_by=GENERATED_BY) raise ValueError('Unsupported definition %r' % def0) def _package_path(self, def0): package = self.filters.jpackage(def0.module) dirs = package.split('.') return os.path.join(self.out, os.path.join(*dirs)) def _file_path(self, def0): dirname = self._package_path(def0) filename = '%s.java' % self.filters.jname(def0) return os.path.join(dirname, filename)
def __init__(self, out, prefixes=None): '''Create a new generator.''' super(ObjectiveCGenerator, self).__init__(out) self.prefix_mapper = PrefixMapper(prefixes) self.filters = _ObjectiveCFilters(self.prefix_mapper) self.templates = Templates(__file__, filters=self.filters)
def __init__(self, out, module_names=None, prefixes=None): super(JavaGenerator, self).__init__(out) self.module_mapper = ModuleMapper(module_names) self.prefix_mapper = PrefixMapper(prefixes) self.filters = _JavaFilters(self.module_mapper, self.prefix_mapper) self.templates = Templates(__file__, filters=self.filters)
def __init__(self, out, module_names=None, prefixes=None): """Create a new generator.""" super(ExampleGenerator, self).__init__(out) self.module_mapper = ModuleMapper(module_names) self.prefix_mapper = PrefixMapper(prefixes) # Generator filters available in jinja templates. self.filters = ExampleFilters(self.module_mapper, self.prefix_mapper) # Jinja templates relative to this file. self.templates = Templates(__file__, filters=self.filters)
def __init__(self, out, module_names=None, **kwargs): super(PythonGenerator, self).__init__(out, module_names=module_names, **kwargs) self.filters = _PythonFilters(self.module_mapper) self.templates = Templates(__file__, filters=self.filters)
class PythonGenerator(Generator): '''Python code generator, supports module names, does not support prefixes.''' def __init__(self, out, module_names=None, **kwargs): super(PythonGenerator, self).__init__(out, module_names=module_names, **kwargs) self.filters = _PythonFilters(self.module_mapper) self.templates = Templates(__file__, filters=self.filters) def generate(self, package): # In python __init__.py is required when there are submodules in a module. # mycompany => mycompany/__init__.py # mycompany.service => mycompany/service/__init__.py # mycompany.service.client => mycompany/service/client.py # Calculate __init__ modules. modules = list(package.modules) init_names = self._init_modules([module.name for module in modules]) # Write python modules. for module in modules: name = module.name code = self._render_module(module) is_init_module = name in init_names init_names.discard(name) filename = self._filename(name, is_init_module) self._write_file(filename, code) # Write non-existent __init__.py files. for name in init_names: filename = self._filename(name, is_init_module=True) if not os.path.exists(filename): self._write_file(filename, INIT_FILE_CONTENT) def _render_module(self, module): # Render module definitions. definitions = [self._render_definition(d) for d in module.definitions] # Render the module. return self.templates.render(MODULE_TEMPLATE, imported_modules=module.imported_modules, definitions=definitions, generated_by=GENERATED_BY) def _render_definition(self, def0): tname = DEFINITION_TEMPLATES.get(def0.type) if not tname: raise ValueError('Unsupported definition %r' % def0) try: self.filters.current_module = def0.module if def0.is_enum: return self.templates.render(tname, enum=def0) elif def0.is_message: return self.templates.render(tname, message=def0) else: return self.templates.render(tname, interface=def0) finally: self.filters.current_module = None def _filename(self, module_name, is_init_module=False): path = self.filters.pymodule_name(module_name) path = os.path.join(self.out, path.replace('.', '/')) if is_init_module: return path + '/__init__.py' else: return path + '.py' def _init_modules(self, module_names): result = set() for name in module_names: if '.' not in name: continue parts = name.split('.')[:-1] while parts: init_module = '.'.join(parts) result.add(init_module) parts.pop() return result def _write_file(self, filename, content): dirname = os.path.dirname(filename) mkdir_p(dirname) with io.open(filename, 'wt', encoding=UTF8) as f: f.write(content) logging.debug('Created %s', filename)
class PythonGenerator(Generator): '''Python code generator.''' @classmethod def create_cli(cls): return PythonGeneratorCli() def __init__(self, out, module_names=None): super(PythonGenerator, self).__init__(out) self.module_mapper = ModuleMapper(module_names) self.filters = _PythonFilters(self.module_mapper) self.templates = Templates(__file__, filters=self.filters) def generate(self, package): self._generate_modules(package.modules) self._generate_init_files(package.modules) def _generate_modules(self, modules): for module in modules: code = self._render_module(module) filename = self._filename(module) self.write_file(filename, code) def _generate_init_files(self, modules): for module in modules: filename = self._init_filename(module) filepath = os.path.join(self.out, filename) if not os.path.exists(filepath): self.write_file(filename, '# encoding: utf-8') def _render_module(self, module): # Render module definitions. definitions = [self._render_definition(d) for d in module.definitions] # Render the module. return self.templates.render(MODULE_TEMPLATE, imported_modules=module.imported_modules, definitions=definitions, generated_by=GENERATED_BY) def _render_definition(self, def0): tname = DEFINITION_TEMPLATES.get(def0.type) if not tname: raise ValueError('Unsupported definition %r' % def0) template = self.templates.get(tname) try: self.filters.current_module = def0.module if def0.is_enum: return template.render(enum=def0) elif def0.is_message: return template.render(message=def0) else: return template.render(interface=def0) finally: self.filters.current_module = None def _filename(self, module): path = self.filters.pymodule(module) return path.replace('.', '/') + '.py' def _init_filename(self, module): filename = self._filename(module) path = os.path.dirname(filename) return os.path.join(path, '__init__.py')