From 82ba73535c0966e8ae8fb50db1ea23534d827717 Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Tue, 8 Sep 2020 20:47:19 +0900 Subject: utils: ipc: import mojo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Import mojo from the Chromium repository, so that we can use it for generating code for the IPC mechanism. The commit from which this was taken is: a079161ec8c6907b883f9cb84fc8c4e7896cb1d0 "Add PPAPI constructs for sending focus object to PdfAccessibilityTree" This tree has been pruned to remove directories that didn't have any necessary code: - mojo/* except for mojo/public - mojo core, docs, and misc files - mojo/public/* except for mojo/public/{tools,LICENSE} - language bindings for IPC, tests, and some mojo internals - mojo/public/tools/{fuzzers,chrome_ipc} - mojo/public/tools/bindings/generators - code generation for other languages No files were modified. Signed-off-by: Paul Elder Acked-by: Laurent Pinchart Acked-by: Niklas Söderlund Acked-by: Kieran Bingham --- .../tools/bindings/generate_type_mappings.py | 187 +++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100755 utils/ipc/mojo/public/tools/bindings/generate_type_mappings.py (limited to 'utils/ipc/mojo/public/tools/bindings/generate_type_mappings.py') diff --git a/utils/ipc/mojo/public/tools/bindings/generate_type_mappings.py b/utils/ipc/mojo/public/tools/bindings/generate_type_mappings.py new file mode 100755 index 00000000..64ca048f --- /dev/null +++ b/utils/ipc/mojo/public/tools/bindings/generate_type_mappings.py @@ -0,0 +1,187 @@ +#!/usr/bin/env python +# Copyright 2016 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Generates a JSON typemap from its command-line arguments and dependencies. + +Each typemap should be specified in an command-line argument of the form +key=value, with an argument of "--start-typemap" preceding each typemap. + +For example, +generate_type_mappings.py --output=foo.typemap --start-typemap \\ + public_headers=foo.h traits_headers=foo_traits.h \\ + type_mappings=mojom.Foo=FooImpl + +generates a foo.typemap containing +{ + "c++": { + "mojom.Foo": { + "typename": "FooImpl", + "traits_headers": [ + "foo_traits.h" + ], + "public_headers": [ + "foo.h" + ] + } + } +} + +Then, +generate_type_mappings.py --dependency foo.typemap --output=bar.typemap \\ + --start-typemap public_headers=bar.h traits_headers=bar_traits.h \\ + type_mappings=mojom.Bar=BarImpl + +generates a bar.typemap containing +{ + "c++": { + "mojom.Bar": { + "typename": "BarImpl", + "traits_headers": [ + "bar_traits.h" + ], + "public_headers": [ + "bar.h" + ] + }, + "mojom.Foo": { + "typename": "FooImpl", + "traits_headers": [ + "foo_traits.h" + ], + "public_headers": [ + "foo.h" + ] + } + } +} +""" + +import argparse +import json +import os +import re +import sys + +sys.path.insert( + 0, + os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "mojom")) + +from mojom.generate.generator import WriteFile + +def ReadTypemap(path): + with open(path) as f: + return json.load(f)['c++'] + + +def ParseTypemapArgs(args): + typemaps = [s for s in '\n'.join(args).split('--start-typemap\n') if s] + result = {} + for typemap in typemaps: + result.update(ParseTypemap(typemap)) + return result + + +def LoadCppTypemapConfig(path): + configs = {} + with open(path) as f: + for config in json.load(f): + for entry in config['types']: + configs[entry['mojom']] = { + 'typename': entry['cpp'], + 'public_headers': config.get('traits_headers', []), + 'traits_headers': config.get('traits_private_headers', []), + 'copyable_pass_by_value': entry.get('copyable_pass_by_value', + False), + 'force_serialize': entry.get('force_serialize', False), + 'hashable': entry.get('hashable', False), + 'move_only': entry.get('move_only', False), + 'nullable_is_same_type': entry.get('nullable_is_same_type', False), + 'non_copyable_non_movable': False, + } + return configs + + +def ParseTypemap(typemap): + values = {'type_mappings': [], 'public_headers': [], 'traits_headers': []} + for line in typemap.split('\n'): + if not line: + continue + key, _, value = line.partition('=') + values[key].append(value.lstrip('/')) + result = {} + mapping_pattern = \ + re.compile(r"""^([^=]+) # mojom type + = + ([^[]+) # native type + (?:\[([^]]+)\])?$ # optional attribute in square brackets + """, re.X) + for typename in values['type_mappings']: + match_result = mapping_pattern.match(typename) + assert match_result, ( + "Cannot parse entry in the \"type_mappings\" section: %s" % typename) + + mojom_type = match_result.group(1) + native_type = match_result.group(2) + attributes = [] + if match_result.group(3): + attributes = match_result.group(3).split(',') + + assert mojom_type not in result, ( + "Cannot map multiple native types (%s, %s) to the same mojom type: %s" % + (result[mojom_type]['typename'], native_type, mojom_type)) + + result[mojom_type] = { + 'public_headers': values['public_headers'], + 'traits_headers': values['traits_headers'], + 'typename': native_type, + + # Attributes supported for individual mappings. + 'copyable_pass_by_value': 'copyable_pass_by_value' in attributes, + 'force_serialize': 'force_serialize' in attributes, + 'hashable': 'hashable' in attributes, + 'move_only': 'move_only' in attributes, + 'non_copyable_non_movable': 'non_copyable_non_movable' in attributes, + 'nullable_is_same_type': 'nullable_is_same_type' in attributes, + } + return result + + +def main(): + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--dependency', + type=str, + action='append', + default=[], + help=('A path to another JSON typemap to merge into the output. ' + 'This may be repeated to merge multiple typemaps.')) + parser.add_argument( + '--cpp-typemap-config', + type=str, + action='store', + dest='cpp_config_path', + help=('A path to a single JSON-formatted typemap config as emitted by' + 'GN when processing a mojom_cpp_typemap build rule.')) + parser.add_argument('--output', + type=str, + required=True, + help='The path to which to write the generated JSON.') + params, typemap_params = parser.parse_known_args() + typemaps = ParseTypemapArgs(typemap_params) + if params.cpp_config_path: + typemaps.update(LoadCppTypemapConfig(params.cpp_config_path)) + missing = [path for path in params.dependency if not os.path.exists(path)] + if missing: + raise IOError('Missing dependencies: %s' % ', '.join(missing)) + for path in params.dependency: + typemaps.update(ReadTypemap(path)) + + WriteFile(json.dumps({'c++': typemaps}, indent=2), params.output) + + +if __name__ == '__main__': + main() -- cgit v1.2.1