| #!/usr/bin/env python3 |
| # Copyright 2021 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Generate mojo connectivity test code.""" |
| |
| import json |
| import os |
| from pathlib import Path |
| |
| # pylint: disable=import-error, no-name-in-module |
| import jinja2 |
| from generators import mojom_cpp_generator |
| from mojom.generate import generator as mojom_generator |
| from mojom.generate import module as mojom_module |
| # pylint: enable=import-error, no-name-in-module |
| |
| from chromite.lib import commandline |
| |
| TEMPLATES_PATH = Path(Path(os.path.realpath(__file__)).parent, 'templates') |
| |
| |
| class Generator: |
| """Generates bindings code for c++.""" |
| |
| def __init__(self, mojom, mojo_root, output_dir, generator_overrides): |
| self._output_dir = output_dir |
| self._mojom = os.path.relpath(mojom, mojo_root) |
| self._generator_overrides = generator_overrides |
| |
| self._module = None |
| self._LoadModule() |
| |
| self._env = None |
| self._SetUpEnv() |
| |
| def _LoadModule(self): |
| module_path = Path(self._output_dir, f'{self._mojom}-module') |
| with module_path.open('rb') as f: |
| self._module = mojom_module.Module.Load(f) |
| self._module.Stylize(mojom_generator.Stylizer()) |
| |
| def _GetFullMojomNameForKind(self, kind): |
| return self._env.filters['get_full_mojom_name_for_kind'](kind) |
| |
| def _IsGeneratorOverrideKind(self, kind): |
| return (hasattr(kind, 'name') and self._GetFullMojomNameForKind(kind) |
| in self._generator_overrides) |
| |
| def _GetGeneratorOverrideType(self, kind): |
| if not self._IsGeneratorOverrideKind(kind): |
| return None |
| return self._generator_overrides[self._GetFullMojomNameForKind( |
| kind)]['generator_typename'] |
| |
| def _SetUpEnv(self): |
| self._env = jinja2.Environment( |
| loader=jinja2.FileSystemLoader(TEMPLATES_PATH)) |
| generator = mojom_cpp_generator.Generator(self._module) |
| self._env.filters.update(generator.GetFilters()) |
| self._env.filters.update({ |
| 'generator_override_type': self._GetGeneratorOverrideType, |
| }) |
| self._env.tests.update({ |
| 'PendingRemoteKind': mojom_module.IsPendingRemoteKind, |
| 'PendingReceiverKind': mojom_module.IsPendingReceiverKind, |
| 'StructKind': mojom_module.IsStructKind, |
| 'UnionKind': mojom_module.IsUnionKind, |
| 'EnumKind': mojom_module.IsEnumKind, |
| 'ArrayKind': mojom_module.IsArrayKind, |
| 'MapKind': mojom_module.IsMapKind, |
| 'GenericHandleKind': mojom_module.IsGenericHandleKind, |
| 'GeneratorOverrideKind': self._IsGeneratorOverrideKind, |
| }) |
| |
| def _GenerateFile(self, suffix, args): |
| data = self._env.get_template(f'{suffix}.j2').render(**args) |
| output_file = Path(self._output_dir, f'{self._mojom}-{suffix}') |
| output_file.write_text(data) |
| |
| def Generate(self): |
| extra_headers = [] |
| for override in self._generator_overrides.values(): |
| extra_headers += override['generator_headers'] |
| args = { |
| 'module': self._module, |
| 'namespaces_as_array': self._module.mojom_namespace.split('.'), |
| 'extra_headers': extra_headers, |
| } |
| self._GenerateFile('connectivity-forward.h', args) |
| self._GenerateFile('connectivity.h', args) |
| self._GenerateFile('connectivity.cc', args) |
| |
| |
| def Generate(mojoms, mojo_root, output_dir, generator_overrides_files): |
| """Parses arguments and generates bindings code for c++.""" |
| generator_overrides = {} |
| for f in generator_overrides_files: |
| override = json.loads(Path(f).read_bytes()) |
| generator_overrides.update(override.get('c++', {})) |
| |
| for mojom in mojoms: |
| Generator(mojom, mojo_root, output_dir, generator_overrides).Generate() |
| |
| |
| def GetParser(): |
| """Returns an argument parser.""" |
| parser = commandline.ArgumentParser(description=__doc__) |
| parser.add_argument( |
| '--mojo-root', required=True, help='Root of the mojo files.') |
| parser.add_argument( |
| '--output-dir', |
| required=True, |
| help='Path for mojo generated code. ' |
| 'Must be the same as the mojo bindings output dir.') |
| parser.add_argument( |
| '--mojom-file-list', help='Mojom filenames passed as a file.') |
| parser.add_argument( |
| '--mojoms', default=[], nargs='+', help='Mojom filenames.') |
| parser.add_argument( |
| '--generator-overrides', |
| default=[], |
| nargs='+', |
| help='The json config of the generator overrides.') |
| return parser |
| |
| |
| def main(argv): |
| parser = GetParser() |
| opts = parser.parse_args(argv) |
| if opts.mojom_file_list: |
| opts.mojoms.extend( |
| Path(opts.mojom_file_list).read_text(encoding='utf-8').split()) |
| |
| opts.Freeze() |
| |
| if not opts.mojoms: |
| raise parser.error('Must list at least one mojom file via --mojoms or ' |
| '--mojom-file-list') |
| |
| Generate(opts.mojoms, opts.mojo_root, opts.output_dir, |
| opts.generator_overrides) |
| |
| |
| if __name__ == '__main__': |
| commandline.ScriptWrapperMain(lambda _: main) |