summaryrefslogtreecommitdiff
path: root/utils/ipc/mojo/public/tools/bindings
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2024-08-08 18:13:00 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2024-08-15 23:59:08 +0300
commit50c92cc7e2924009ecab3e4004448b01d687707c (patch)
treec22b49816a3c79dae4727780962aa0928df42b52 /utils/ipc/mojo/public/tools/bindings
parentd3bf27180ef1d91b86b7b87a2378e559eaff5455 (diff)
meson: Move all code generation scripts to utils/codegen/
We have multiple code generation scripts in utils/, mixed with other miscellaneous utilities, as well as a larger code base based on mojom in utils/ipc/. To make code sharing easier between the generator scripts, without creating a mess in the utils/ directory, move all the code generation code to utils/codegen/. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Diffstat (limited to 'utils/ipc/mojo/public/tools/bindings')
-rw-r--r--utils/ipc/mojo/public/tools/bindings/BUILD.gn131
-rw-r--r--utils/ipc/mojo/public/tools/bindings/README.md1014
-rw-r--r--utils/ipc/mojo/public/tools/bindings/checks/__init__.py0
-rw-r--r--utils/ipc/mojo/public/tools/bindings/checks/mojom_attributes_check.py170
-rw-r--r--utils/ipc/mojo/public/tools/bindings/checks/mojom_attributes_check_unittest.py194
-rw-r--r--utils/ipc/mojo/public/tools/bindings/checks/mojom_definitions_check.py34
-rw-r--r--utils/ipc/mojo/public/tools/bindings/checks/mojom_interface_feature_check.py62
-rw-r--r--utils/ipc/mojo/public/tools/bindings/checks/mojom_interface_feature_check_unittest.py173
-rw-r--r--utils/ipc/mojo/public/tools/bindings/checks/mojom_restrictions_check.py102
-rw-r--r--utils/ipc/mojo/public/tools/bindings/checks/mojom_restrictions_checks_unittest.py254
-rwxr-xr-xutils/ipc/mojo/public/tools/bindings/concatenate-files.py55
-rwxr-xr-xutils/ipc/mojo/public/tools/bindings/concatenate_and_replace_closure_exports.py75
-rw-r--r--utils/ipc/mojo/public/tools/bindings/gen_data_files_list.py48
-rwxr-xr-xutils/ipc/mojo/public/tools/bindings/generate_type_mappings.py135
-rwxr-xr-xutils/ipc/mojo/public/tools/bindings/minify_with_terser.py47
-rw-r--r--utils/ipc/mojo/public/tools/bindings/mojom.gni2118
-rwxr-xr-xutils/ipc/mojo/public/tools/bindings/mojom_bindings_generator.py424
-rw-r--r--utils/ipc/mojo/public/tools/bindings/mojom_bindings_generator_unittest.py62
-rwxr-xr-xutils/ipc/mojo/public/tools/bindings/validate_typemap_config.py58
19 files changed, 0 insertions, 5156 deletions
diff --git a/utils/ipc/mojo/public/tools/bindings/BUILD.gn b/utils/ipc/mojo/public/tools/bindings/BUILD.gn
deleted file mode 100644
index eeca73ea..00000000
--- a/utils/ipc/mojo/public/tools/bindings/BUILD.gn
+++ /dev/null
@@ -1,131 +0,0 @@
-# Copyright 2016 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//mojo/public/tools/bindings/mojom.gni")
-import("//third_party/jinja2/jinja2.gni")
-
-action("precompile_templates") {
- sources = mojom_generator_sources
- sources += [
- "$mojom_generator_root/generators/cpp_templates/cpp_macros.tmpl",
- "$mojom_generator_root/generators/cpp_templates/enum_macros.tmpl",
- "$mojom_generator_root/generators/cpp_templates/enum_serialization_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/feature_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/feature_definition.tmpl",
- "$mojom_generator_root/generators/cpp_templates/interface_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/interface_definition.tmpl",
- "$mojom_generator_root/generators/cpp_templates/interface_feature_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/interface_macros.tmpl",
- "$mojom_generator_root/generators/cpp_templates/interface_proxy_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/interface_request_validator_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/interface_response_validator_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/interface_stub_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/module-features.h.tmpl",
- "$mojom_generator_root/generators/cpp_templates/module-forward.h.tmpl",
- "$mojom_generator_root/generators/cpp_templates/module-import-headers.h.tmpl",
- "$mojom_generator_root/generators/cpp_templates/module-params-data.h.tmpl",
- "$mojom_generator_root/generators/cpp_templates/module-shared-internal.h.tmpl",
- "$mojom_generator_root/generators/cpp_templates/module-shared-message-ids.h.tmpl",
- "$mojom_generator_root/generators/cpp_templates/module-shared.cc.tmpl",
- "$mojom_generator_root/generators/cpp_templates/module-shared.h.tmpl",
- "$mojom_generator_root/generators/cpp_templates/module-test-utils.h.tmpl",
- "$mojom_generator_root/generators/cpp_templates/module.cc.tmpl",
- "$mojom_generator_root/generators/cpp_templates/module.h.tmpl",
- "$mojom_generator_root/generators/cpp_templates/struct_data_view_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/struct_data_view_definition.tmpl",
- "$mojom_generator_root/generators/cpp_templates/struct_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/struct_definition.tmpl",
- "$mojom_generator_root/generators/cpp_templates/struct_macros.tmpl",
- "$mojom_generator_root/generators/cpp_templates/struct_serialization_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/struct_traits_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/struct_traits_definition.tmpl",
- "$mojom_generator_root/generators/cpp_templates/struct_unserialized_message_context.tmpl",
- "$mojom_generator_root/generators/cpp_templates/union_data_view_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/union_data_view_definition.tmpl",
- "$mojom_generator_root/generators/cpp_templates/union_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/union_definition.tmpl",
- "$mojom_generator_root/generators/cpp_templates/union_serialization_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/union_traits_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/union_traits_definition.tmpl",
- "$mojom_generator_root/generators/cpp_templates/validation_macros.tmpl",
- "$mojom_generator_root/generators/cpp_templates/wrapper_class_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/wrapper_class_definition.tmpl",
- "$mojom_generator_root/generators/cpp_templates/wrapper_class_template_definition.tmpl",
- "$mojom_generator_root/generators/cpp_templates/wrapper_union_class_declaration.tmpl",
- "$mojom_generator_root/generators/cpp_templates/wrapper_union_class_definition.tmpl",
- "$mojom_generator_root/generators/cpp_templates/wrapper_union_class_template_definition.tmpl",
- "$mojom_generator_root/generators/java_templates/constant_definition.tmpl",
- "$mojom_generator_root/generators/java_templates/constants.java.tmpl",
- "$mojom_generator_root/generators/java_templates/data_types_definition.tmpl",
- "$mojom_generator_root/generators/java_templates/enum.java.tmpl",
- "$mojom_generator_root/generators/java_templates/enum_definition.tmpl",
- "$mojom_generator_root/generators/java_templates/header.java.tmpl",
- "$mojom_generator_root/generators/java_templates/interface.java.tmpl",
- "$mojom_generator_root/generators/java_templates/interface_definition.tmpl",
- "$mojom_generator_root/generators/java_templates/interface_internal.java.tmpl",
- "$mojom_generator_root/generators/java_templates/struct.java.tmpl",
- "$mojom_generator_root/generators/java_templates/union.java.tmpl",
- "$mojom_generator_root/generators/js_templates/enum_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/fuzzing.tmpl",
- "$mojom_generator_root/generators/js_templates/interface_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/enum_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/enum_definition_for_module.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/interface_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/interface_definition_for_module.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/module_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/mojom-lite.js.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/mojom.m.js.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/struct_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/struct_definition_for_module.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/union_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/union_definition_for_module.tmpl",
- "$mojom_generator_root/generators/js_templates/module.amd.tmpl",
- "$mojom_generator_root/generators/js_templates/module_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/struct_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/union_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/validation_macros.tmpl",
- "$mojom_generator_root/generators/mojolpm_templates/mojolpm.cc.tmpl",
- "$mojom_generator_root/generators/mojolpm_templates/mojolpm.h.tmpl",
- "$mojom_generator_root/generators/mojolpm_templates/mojolpm.proto.tmpl",
- "$mojom_generator_root/generators/mojolpm_templates/mojolpm_from_proto_macros.tmpl",
- "$mojom_generator_root/generators/mojolpm_templates/mojolpm_macros.tmpl",
- "$mojom_generator_root/generators/mojolpm_templates/mojolpm_to_proto_macros.tmpl",
- "$mojom_generator_root/generators/mojolpm_templates/mojolpm_traits_specialization_macros.tmpl",
- "$mojom_generator_root/generators/ts_templates/enum_definition.tmpl",
- "$mojom_generator_root/generators/ts_templates/interface_definition.tmpl",
- "$mojom_generator_root/generators/ts_templates/module_definition.tmpl",
- "$mojom_generator_root/generators/ts_templates/struct_definition.tmpl",
- "$mojom_generator_root/generators/ts_templates/union_definition.tmpl",
- ]
- script = mojom_generator_script
-
- inputs = jinja2_sources
- outputs = [
- "$target_gen_dir/cpp_templates.zip",
- "$target_gen_dir/java_templates.zip",
- "$target_gen_dir/js_templates.zip",
- "$target_gen_dir/mojolpm_templates.zip",
- "$target_gen_dir/ts_templates.zip",
- ]
- args = [
- "-o",
- rebase_path(target_gen_dir, root_build_dir),
- "--use_bundled_pylibs",
- "precompile",
- ]
-}
-
-group("tests") {
- data = [
- mojom_generator_script,
- "checks/mojom_attributes_check_unittest.py",
- "checks/mojom_interface_feature_check_unittest.py",
- "checks/mojom_restrictions_checks_unittest.py",
- "mojom_bindings_generator_unittest.py",
- "//tools/diagnosis/crbug_1001171.py",
- "//third_party/markupsafe/",
- ]
- data += mojom_generator_sources
- data += jinja2_sources
-}
diff --git a/utils/ipc/mojo/public/tools/bindings/README.md b/utils/ipc/mojo/public/tools/bindings/README.md
deleted file mode 100644
index b27b2d01..00000000
--- a/utils/ipc/mojo/public/tools/bindings/README.md
+++ /dev/null
@@ -1,1014 +0,0 @@
-# Mojom Interface Definition Language (IDL)
-This document is a subset of the [Mojo documentation](/mojo/README.md).
-
-[TOC]
-
-## Overview
-
-Mojom is the IDL for Mojo interfaces. Given a `.mojom` file, the
-[bindings
-generator](https://cs.chromium.org/chromium/src/mojo/public/tools/bindings/) can
-output bindings for any supported language: **C++**, **JavaScript**, or
-**Java**.
-
-For a trivial example consider the following hypothetical Mojom file we write to
-`//services/widget/public/mojom/frobinator.mojom`:
-
-```
-module widget.mojom;
-
-interface Frobinator {
- Frobinate();
-};
-```
-
-This defines a single [interface](#Interfaces) named `Frobinator` in a
-[module](#Modules) named `widget.mojom` (and thus fully qualified in Mojom as
-`widget.mojom.Frobinator`.) Note that many interfaces and/or other types of
-definitions (structs, enums, *etc.*) may be included in a single Mojom file.
-
-If we add a corresponding GN target to
-`//services/widget/public/mojom/BUILD.gn`:
-
-```
-import("mojo/public/tools/bindings/mojom.gni")
-
-mojom("mojom") {
- sources = [
- "frobinator.mojom",
- ]
-}
-```
-
-and then build this target:
-
-```
-ninja -C out/r services/widget/public/mojom
-```
-
-we'll find several generated sources in our output directory:
-
-```
-out/r/gen/services/widget/public/mojom/frobinator.mojom.cc
-out/r/gen/services/widget/public/mojom/frobinator.mojom.h
-out/r/gen/services/widget/public/mojom/frobinator.mojom-shared.h
-etc...
-```
-
-Each of these generated source modules includes a set of definitions
-representing the Mojom contents in C++. You can also build or depend on suffixed
-target names to get bindings for other languages. For example,
-
-```
-ninja -C out/r services/widget/public/mojom:mojom_js
-ninja -C out/r services/widget/public/mojom:mojom_java
-```
-
-would generate JavaScript and Java bindings respectively, in the same generated
-output directory.
-
-For more details regarding the generated
-outputs please see
-[documentation for individual target languages](#Generated-Code-For-Target-Languages).
-
-## Mojom Syntax
-
-Mojom IDL allows developers to define **structs**, **unions**, **interfaces**,
-**constants**, and **enums**, all within the context of a **module**. These
-definitions are used to generate code in the supported target languages at build
-time.
-
-Mojom files may **import** other Mojom files in order to reference their
-definitions.
-
-### Primitive Types
-Mojom supports a few basic data types which may be composed into structs or used
-for message parameters.
-
-| Type | Description
-|-------------------------------|-------------------------------------------------------|
-| `bool` | Boolean type (`true` or `false`.)
-| `int8`, `uint8` | Signed or unsigned 8-bit integer.
-| `int16`, `uint16` | Signed or unsigned 16-bit integer.
-| `int32`, `uint32` | Signed or unsigned 32-bit integer.
-| `int64`, `uint64` | Signed or unsigned 64-bit integer.
-| `float`, `double` | 32- or 64-bit floating point number.
-| `string` | UTF-8 encoded string.
-| `array<T>` | Array of any Mojom type *T*; for example, `array<uint8>` or `array<array<string>>`.
-| `array<T, N>` | Fixed-length array of any Mojom type *T*. The parameter *N* must be an integral constant.
-| `map<S, T>` | Associated array mapping values of type *S* to values of type *T*. *S* may be a `string`, `enum`, or numeric type.
-| `handle` | Generic Mojo handle. May be any type of handle, including a wrapped native platform handle.
-| `handle<message_pipe>` | Generic message pipe handle.
-| `handle<shared_buffer>` | Shared buffer handle.
-| `handle<data_pipe_producer>` | Data pipe producer handle.
-| `handle<data_pipe_consumer>` | Data pipe consumer handle.
-| `handle<platform>` | A native platform/OS handle.
-| *`pending_remote<InterfaceType>`* | Any user-defined Mojom interface type. This is sugar for a strongly-typed message pipe handle which should eventually be used to make outgoing calls on the interface.
-| *`pending_receiver<InterfaceType>`* | A pending receiver for any user-defined Mojom interface type. This is sugar for a more strongly-typed message pipe handle which is expected to receive request messages and should therefore eventually be bound to an implementation of the interface.
-| *`pending_associated_remote<InterfaceType>`* | An associated interface handle. See [Associated Interfaces](#Associated-Interfaces)
-| *`pending_associated_receiver<InterfaceType>`* | A pending associated receiver. See [Associated Interfaces](#Associated-Interfaces)
-| *T*? | An optional (nullable) value. Primitive numeric types (integers, floats, booleans, and enums) are not nullable. All other types are nullable.
-
-### Modules
-
-Every Mojom file may optionally specify a single **module** to which it belongs.
-
-This is used strictly for aggregating all defined symbols therein within a
-common Mojom namespace. The specific impact this has on generated bindings code
-varies for each target language. For example, if the following Mojom is used to
-generate bindings:
-
-```
-module business.stuff;
-
-interface MoneyGenerator {
- GenerateMoney();
-};
-```
-
-Generated C++ bindings will define a class interface `MoneyGenerator` in the
-`business::stuff` namespace, while Java bindings will define an interface
-`MoneyGenerator` in the `org.chromium.business.stuff` package. JavaScript
-bindings at this time are unaffected by module declarations.
-
-**NOTE:** By convention in the Chromium codebase, **all** Mojom files should
-declare a module name with at least (and preferably exactly) one top-level name
-as well as an inner `mojom` module suffix. *e.g.*, `chrome.mojom`,
-`business.mojom`, *etc.*
-
-This convention makes it easy to tell which symbols are generated by Mojom when
-reading non-Mojom code, and it also avoids namespace collisions in the fairly
-common scenario where you have a real C++ or Java `Foo` along with a
-corresponding Mojom `Foo` for its serialized representation.
-
-### Imports
-
-If your Mojom references definitions from other Mojom files, you must **import**
-those files. Import syntax is as follows:
-
-```
-import "services/widget/public/mojom/frobinator.mojom";
-```
-
-Import paths are always relative to the top-level directory.
-
-Note that circular imports are **not** supported.
-
-### Structs
-
-Structs are defined using the **struct** keyword, and they provide a way to
-group related fields together:
-
-``` cpp
-struct StringPair {
- string first;
- string second;
-};
-```
-
-Struct fields may be comprised of any of the types listed above in the
-[Primitive Types](#Primitive-Types) section.
-
-Default values may be specified as long as they are constant:
-
-``` cpp
-struct Request {
- int32 id = -1;
- string details;
-};
-```
-
-What follows is a fairly
-comprehensive example using the supported field types:
-
-``` cpp
-struct StringPair {
- string first;
- string second;
-};
-
-enum AnEnum {
- kYes,
- kNo
-};
-
-interface SampleInterface {
- DoStuff();
-};
-
-struct AllTheThings {
- // Note that these types can never be marked nullable!
- bool boolean_value;
- int8 signed_8bit_value = 42;
- uint8 unsigned_8bit_value;
- int16 signed_16bit_value;
- uint16 unsigned_16bit_value;
- int32 signed_32bit_value;
- uint32 unsigned_32bit_value;
- int64 signed_64bit_value;
- uint64 unsigned_64bit_value;
- float float_value_32bit;
- double float_value_64bit;
- AnEnum enum_value = AnEnum.kYes;
-
- // Strings may be nullable.
- string? maybe_a_string_maybe_not;
-
- // Structs may contain other structs. These may also be nullable.
- StringPair some_strings;
- StringPair? maybe_some_more_strings;
-
- // In fact structs can also be nested, though in practice you must always make
- // such fields nullable -- otherwise messages would need to be infinitely long
- // in order to pass validation!
- AllTheThings? more_things;
-
- // Arrays may be templated over any Mojom type, and are always nullable:
- array<int32> numbers;
- array<int32>? maybe_more_numbers;
-
- // Arrays of arrays of arrays... are fine.
- array<array<array<AnEnum>>> this_works_but_really_plz_stop;
-
- // The element type may be nullable if it's a type which is allowed to be
- // nullable.
- array<AllTheThings?> more_maybe_things;
-
- // Fixed-size arrays get some extra validation on the receiving end to ensure
- // that the correct number of elements is always received.
- array<uint64, 2> uuid;
-
- // Maps follow many of the same rules as arrays. Key types may be any
- // non-handle, non-collection type, and value types may be any supported
- // struct field type. Maps may also be nullable.
- map<string, int32> one_map;
- map<AnEnum, string>? maybe_another_map;
- map<StringPair, AllTheThings?>? maybe_a_pretty_weird_but_valid_map;
- map<StringPair, map<int32, array<map<string, string>?>?>?> ridiculous;
-
- // And finally, all handle types are valid as struct fields and may be
- // nullable. Note that interfaces and interface requests (the "Foo" and
- // "Foo&" type syntax respectively) are just strongly-typed message pipe
- // handles.
- handle generic_handle;
- handle<data_pipe_consumer> reader;
- handle<data_pipe_producer>? maybe_writer;
- handle<shared_buffer> dumping_ground;
- handle<message_pipe> raw_message_pipe;
- pending_remote<SampleInterface>? maybe_a_sample_interface_client_pipe;
- pending_receiver<SampleInterface> non_nullable_sample_pending_receiver;
- pending_receiver<SampleInterface>? nullable_sample_pending_receiver;
- pending_associated_remote<SampleInterface> associated_interface_client;
- pending_associated_receiver<SampleInterface> associated_pending_receiver;
- pending_associated_receiver<SampleInterface>? maybe_another_pending_receiver;
-};
-```
-
-For details on how all of these different types translate to usable generated
-code, see
-[documentation for individual target languages](#Generated-Code-For-Target-Languages).
-
-### Unions
-
-Mojom supports tagged unions using the **union** keyword. A union is a
-collection of fields which may take the value of any single one of those fields
-at a time. Thus they provide a way to represent a variant value type while
-minimizing storage requirements.
-
-Union fields may be of any type supported by [struct](#Structs) fields. For
-example:
-
-```cpp
-union ExampleUnion {
- string str;
- StringPair pair;
- int64 id;
- array<uint64, 2> guid;
- SampleInterface iface;
-};
-```
-
-For details on how unions like this translate to generated bindings code, see
-[documentation for individual target languages](#Generated-Code-For-Target-Languages).
-
-### Enumeration Types
-
-Enumeration types may be defined using the **enum** keyword either directly
-within a module or nested within the namespace of some struct or interface:
-
-```
-module business.mojom;
-
-enum Department {
- kSales = 0,
- kDev,
-};
-
-struct Employee {
- enum Type {
- kFullTime,
- kPartTime,
- };
-
- Type type;
- // ...
-};
-```
-
-C++ constant-style enum value names are preferred as specified in the
-[Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html#Enumerator_Names).
-
-Similar to C-style enums, individual values may be explicitly assigned within an
-enum definition. By default, values are based at zero and increment by
-1 sequentially.
-
-The effect of nested definitions on generated bindings varies depending on the
-target language. See [documentation for individual target languages](#Generated-Code-For-Target-Languages).
-
-### Constants
-
-Constants may be defined using the **const** keyword either directly within a
-module or nested within the namespace of some struct or interface:
-
-```
-module business.mojom;
-
-const string kServiceName = "business";
-
-struct Employee {
- const uint64 kInvalidId = 0;
-
- enum Type {
- kFullTime,
- kPartTime,
- };
-
- uint64 id = kInvalidId;
- Type type;
-};
-```
-
-The effect of nested definitions on generated bindings varies depending on the
-target language. See [documentation for individual target languages](#Generated-Code-For-Target-Languages).
-
-### Features
-
-Features can be declared with a `name` and `default_state` and can be attached
-in mojo to interfaces or methods using the `RuntimeFeature` attribute. If the
-feature is disabled at runtime, the method will crash and the interface will
-refuse to be bound / instantiated. Features cannot be serialized to be sent over
-IPC at this time.
-
-```
-module experimental.mojom;
-
-feature kUseElevators {
- const string name = "UseElevators";
- const bool default_state = false;
-}
-
-[RuntimeFeature=kUseElevators]
-interface Elevator {
- // This interface cannot be bound or called if the feature is disabled.
-}
-
-interface Building {
- // This method cannot be called if the feature is disabled.
- [RuntimeFeature=kUseElevators]
- CallElevator(int floor);
-
- // This method can be called.
- RingDoorbell(int volume);
-}
-```
-
-### Interfaces
-
-An **interface** is a logical bundle of parameterized request messages. Each
-request message may optionally define a parameterized response message. Here's
-an example to define an interface `Foo` with various kinds of requests:
-
-```
-interface Foo {
- // A request which takes no arguments and expects no response.
- MyMessage();
-
- // A request which has some arguments and expects no response.
- MyOtherMessage(string name, array<uint8> bytes);
-
- // A request which expects a single-argument response.
- MyMessageWithResponse(string command) => (bool success);
-
- // A request which expects a response with multiple arguments.
- MyMessageWithMoarResponse(string a, string b) => (int8 c, int8 d);
-};
-```
-
-Anything which is a valid struct field type (see [Structs](#Structs)) is also a
-valid request or response argument type. The type notation is the same for both.
-
-### Attributes
-
-Mojom definitions may have their meaning altered by **attributes**, specified
-with a syntax similar to Java or C# attributes. There are a handle of
-interesting attributes supported today.
-
-* **`[Sync]`**:
- The `Sync` attribute may be specified for any interface method which expects a
- response. This makes it so that callers of the method can wait synchronously
- for a response. See [Synchronous
- Calls](/mojo/public/cpp/bindings/README.md#Synchronous-Calls) in the C++
- bindings documentation. Note that sync methods are only actually synchronous
- when called from C++.
-
-* **`[NoInterrupt]`**:
- When a thread is waiting for a reply to a `Sync` message, it's possible to be
- woken up to dispatch other unrelated incoming `Sync` messages. This measure
- helps to avoid deadlocks. If a `Sync` message is also marked as `NoInterrupt`
- however, this behavior is disabled: instead the calling thread will only wake
- up for the precise message being waited upon. This attribute must be used with
- extreme caution, because it can lead to deadlocks otherwise.
-
-* **`[Default]`**:
- The `Default` attribute may be used to specify an enumerator value or union
- field that will be used if an `Extensible` enumeration or union does not
- deserialize to a known value on the receiver side, i.e. the sender is using a
- newer version of the enum or union. This allows unknown values to be mapped to
- a well-defined value that can be appropriately handled.
-
- Note: The `Default` field for a union must be of nullable or integral type.
- When a union is defaulted to this field, the field takes on the default value
- for its type: null for nullable types, and zero/false for integral types.
-
-* **`[Extensible]`**:
- The `Extensible` attribute may be specified for any enum or union definition.
- For enums, this essentially disables builtin range validation when receiving
- values of the enum type in a message, allowing older bindings to tolerate
- unrecognized values from newer versions of the enum.
-
- If an enum value within an extensible enum definition is affixed with the
- `Default` attribute, out-of-range values for the enum will deserialize to that
- default value. Only one enum value may be designated as the `Default`.
-
- Similarly, a union marked `Extensible` will deserialize to its `Default` field
- when an unrecognized field is received. Extensible unions MUST specify exactly
- one `Default` field, and the field must be of nullable or integral type. When
- defaulted to this field, the value is always null/zero/false as appropriate.
-
- An `Extensible` enumeration REQUIRES that a `Default` value be specified,
- so all new extensible enums should specify one.
-
-* **`[Native]`**:
- The `Native` attribute may be specified for an empty struct declaration to
- provide a nominal bridge between Mojo IPC and legacy `IPC::ParamTraits` or
- `IPC_STRUCT_TRAITS*` macros. See [Repurposing Legacy IPC
- Traits](/docs/mojo_ipc_conversion.md#repurposing-and-invocations) for more
- details. Note support for this attribute is strictly limited to C++ bindings
- generation.
-
-* **`[MinVersion=N]`**:
- The `MinVersion` attribute is used to specify the version at which a given
- field, enum value, interface method, or method parameter was introduced.
- See [Versioning](#Versioning) for more details. `MinVersion` does not apply
- to interfaces, structs or enums, but to the fields of those types.
- `MinVersion` is not a module-global value, but it is ok to pretend it is by
- skipping versions when adding fields or parameters.
-
-* **`[Stable]`**:
- The `Stable` attribute specifies that a given mojom type or interface
- definition can be considered stable over time, meaning it is safe to use for
- things like persistent storage or communication between independent
- version-skewed binaries. Stable definitions may only depend on builtin mojom
- types or other stable definitions, and changes to such definitions MUST
- preserve backward-compatibility through appropriate use of versioning.
- Backward-compatibility of changes is enforced in the Chromium tree using a
- strict presubmit check. See [Versioning](#Versioning) for more details on
- backward-compatibility constraints.
-
-* **`[Uuid=<UUID>]`**:
- Specifies a UUID to be associated with a given interface. The UUID is intended
- to remain stable across all changes to the interface definition, including
- name changes. The value given for this attribute should be a standard UUID
- string representation as specified by RFC 4122. New UUIDs can be generated
- with common tools such as `uuidgen`.
-
-* **`[RuntimeFeature=feature]`**
- The `RuntimeFeature` attribute should reference a mojo `feature`. If this
- feature is enabled (e.g. using `--enable-features={feature.name}`) then the
- interface behaves entirely as expected. If the feature is not enabled the
- interface cannot be bound to a concrete receiver or remote - attempting to do
- so will result in the receiver or remote being reset() to an unbound state.
- Note that this is a different concept to the build-time `EnableIf` directive.
- `RuntimeFeature` is currently only supported for C++ bindings and has no
- effect for, say, Java or TypeScript bindings (see https://crbug.com/1278253).
-
-* **`[EnableIf=value]`**:
- The `EnableIf` attribute is used to conditionally enable definitions when the
- mojom is parsed. If the `mojom` target in the GN file does not include the
- matching `value` in the list of `enabled_features`, the definition will be
- disabled. This is useful for mojom definitions that only make sense on one
- platform. Note that the `EnableIf` attribute can only be set once per
- definition and cannot be set at the same time as `EnableIfNot`. Also be aware
- that only one condition can be tested, `EnableIf=value,xyz` introduces a new
- `xyz` attribute. `xyz` is not part of the `EnableIf` condition that depends
- only on the feature `value`. Complex conditions can be introduced via
- enabled_features in `build.gn` files.
-
-* **`[EnableIfNot=value]`**:
- The `EnableIfNot` attribute is used to conditionally enable definitions when
- the mojom is parsed. If the `mojom` target in the GN file includes the
- matching `value` in the list of `enabled_features`, the definition will be
- disabled. This is useful for mojom definitions that only make sense on all but
- one platform. Note that the `EnableIfNot` attribute can only be set once per
- definition and cannot be set at the same time as `EnableIf`.
-
-* **`[ServiceSandbox=value]`**:
- The `ServiceSandbox` attribute is used in Chromium to tag which sandbox a
- service hosting an implementation of interface will be launched in. This only
- applies to `C++` bindings. `value` should match a constant defined in an
- imported `sandbox.mojom.Sandbox` enum (for Chromium this is
- `//sandbox/policy/mojom/sandbox.mojom`), such as `kService`.
-
-* **`[RequireContext=enum]`**:
- The `RequireContext` attribute is used in Chromium to tag interfaces that
- should be passed (as remotes or receivers) only to privileged process
- contexts. The process context must be an enum that is imported into the
- mojom that defines the tagged interface. `RequireContext` may be used in
- future to DCHECK or CHECK if remotes are made available in contexts that
- conflict with the one provided in the interface definition. Process contexts
- are not the same as the sandbox a process is running in, but will reflect
- the set of capabilities provided to the service.
-
-* **`[AllowedContext=enum]`**:
- The `AllowedContext` attribute is used in Chromium to tag methods that pass
- remotes or receivers of interfaces that are marked with a `RequireContext`
- attribute. The enum provided on the method must be equal or better (lower
- numerically) than the one required on the interface being passed. At present
- failing to specify an adequate `AllowedContext` value will cause mojom
- generation to fail at compile time. In future DCHECKs or CHECKs might be
- added to enforce that method is only called from a process context that meets
- the given `AllowedContext` value. The enum must of the same type as that
- specified in the interface's `RequireContext` attribute. Adding an
- `AllowedContext` attribute to a method is a strong indication that you need
- a detailed security review of your design - please reach out to the security
- team.
-
-* **`[SupportsUrgent]`**:
- The `SupportsUrgent` attribute is used in conjunction with
- `mojo::UrgentMessageScope` in Chromium to tag messages as having high
- priority. The IPC layer notifies the underlying scheduler upon both receiving
- and processing an urgent message. At present, this attribute only affects
- channel associated messages in the renderer process.
-
-## Generated Code For Target Languages
-
-When the bindings generator successfully processes an input Mojom file, it emits
-corresponding code for each supported target language. For more details on how
-Mojom concepts translate to a given target language, please refer to the
-bindings API documentation for that language:
-
-* [C++ Bindings](/mojo/public/cpp/bindings/README.md)
-* [JavaScript Bindings](/mojo/public/js/README.md)
-* [Java Bindings](/mojo/public/java/bindings/README.md)
-
-## Message Validation
-
-Regardless of target language, all interface messages are validated during
-deserialization before they are dispatched to a receiving implementation of the
-interface. This helps to ensure consistent validation across interfaces without
-leaving the burden to developers and security reviewers every time a new message
-is added.
-
-If a message fails validation, it is never dispatched. Instead a **connection
-error** is raised on the binding object (see
-[C++ Connection Errors](/mojo/public/cpp/bindings/README.md#Connection-Errors),
-[Java Connection Errors](/mojo/public/java/bindings/README.md#Connection-Errors),
-or
-[JavaScript Connection Errors](/mojo/public/js/README.md#Connection-Errors) for
-details.)
-
-Some baseline level of validation is done automatically for primitive Mojom
-types.
-
-### Non-Nullable Objects
-
-Mojom fields or parameter values (*e.g.*, structs, interfaces, arrays, *etc.*)
-may be marked nullable in Mojom definitions (see
-[Primitive Types](#Primitive-Types).) If a field or parameter is **not** marked
-nullable but a message is received with a null value in its place, that message
-will fail validation.
-
-### Enums
-
-Enums declared in Mojom are automatically validated against the range of legal
-values. For example if a Mojom declares the enum:
-
-``` cpp
-enum AdvancedBoolean {
- kTrue = 0,
- kFalse = 1,
- kFileNotFound = 2,
-};
-```
-
-and a message is received with the integral value 3 (or anything other than 0,
-1, or 2) in place of some `AdvancedBoolean` field or parameter, the message will
-fail validation.
-
-*** note
-NOTE: It's possible to avoid this type of validation error by explicitly marking
-an enum as [Extensible](#Attributes) if you anticipate your enum being exchanged
-between two different versions of the binding interface. See
-[Versioning](#Versioning).
-***
-
-### Other failures
-
-There are a host of internal validation errors that may occur when a malformed
-message is received, but developers should not be concerned with these
-specifically; in general they can only result from internal bindings bugs,
-compromised processes, or some remote endpoint making a dubious effort to
-manually encode their own bindings messages.
-
-### Custom Validation
-
-It's also possible for developers to define custom validation logic for specific
-Mojom struct types by exploiting the
-[type mapping](/mojo/public/cpp/bindings/README.md#Type-Mapping) system for C++
-bindings. Messages rejected by custom validation logic trigger the same
-validation failure behavior as the built-in type validation routines.
-
-## Associated Interfaces
-
-As mentioned in the [Primitive Types](#Primitive-Types) section above, pending_remote
-and pending_receiver fields and parameters may be marked as `associated`. This
-essentially means that they are piggy-backed on some other interface's message
-pipe.
-
-Because individual interface message pipes operate independently there can be no
-relative ordering guarantees among them. Associated interfaces are useful when
-one interface needs to guarantee strict FIFO ordering with respect to one or
-more other interfaces, as they allow interfaces to share a single pipe.
-
-Currently associated interfaces are only supported in generated C++ bindings.
-See the documentation for
-[C++ Associated Interfaces](/mojo/public/cpp/bindings/README.md#Associated-Interfaces).
-
-## Versioning
-
-### Overview
-
-*** note
-**NOTE:** You don't need to worry about versioning if you don't care about
-backwards compatibility. Today, all parts of the Chrome browser are
-updated atomically and there is not yet any possibility of any two
-Chrome processes communicating with two different versions of any given Mojom
-interface. On Chrome OS, there are several places where versioning is required.
-For example,
-[ARC++](https://developer.android.com/chrome-os/intro)
-uses versioned mojo to send IPC to the Android container.
-Likewise, the
-[Lacros](/docs/lacros.md)
-browser uses versioned mojo to talk to the ash system UI.
-***
-
-Services extend their interfaces to support new features over time, and clients
-want to use those new features when they are available. If services and clients
-are not updated at the same time, it's important for them to be able to
-communicate with each other using different snapshots (versions) of their
-interfaces.
-
-This document shows how to extend Mojom interfaces in a backwards-compatible
-way. Changing interfaces in a non-backwards-compatible way is not discussed,
-because in that case communication between different interface versions is
-impossible anyway.
-
-### Versioned Structs
-
-You can use the `MinVersion` [attribute](#Attributes) to indicate from which
-version a struct field is introduced. Assume you have the following struct:
-
-``` cpp
-struct Employee {
- uint64 employee_id;
- string name;
-};
-```
-
-and you would like to add birthday and nickname fields. You can add them as
-optional types with a `MinVersion` like so:
-
-``` cpp
-struct Employee {
- uint64 employee_id;
- string name;
- [MinVersion=1] Date? birthday;
- [MinVersion=1] string? nickname;
-};
-```
-
-*** note
-**NOTE:** Mojo object or handle types added with a `MinVersion` **MUST** be
-optional (nullable) or primitive. See [Primitive Types](#Primitive-Types) for
-details on nullable values.
-***
-
-By default, fields belong to version 0. New fields must be appended to the
-struct definition (*i.e*., existing fields must not change **ordinal value**)
-with the `MinVersion` attribute set to a number greater than any previous
-existing versions.
-
-The value of `MinVersion` is unrelated to ordinals. The choice of a particular
-version number is arbitrary. All its usage means is that a field isn't present
-before the numbered version.
-
-*** note
-**NOTE:** do not change existing fields in versioned structs, as this is
-not backwards-compatible. Instead, rename the old field to make its
-deprecation clear and add a new field with a new `MinVersion` number.
-***
-
-**Ordinal value** refers to the relative positional layout of a struct's fields
-(and an interface's methods) when encoded in a message. Implicitly, ordinal
-numbers are assigned to fields according to lexical position. In the example
-above, `employee_id` has an ordinal value of 0 and `name` has an ordinal value
-of 1.
-
-Ordinal values can be specified explicitly using `**@**` notation, subject to
-the following hard constraints:
-
-* For any given struct or interface, if any field or method explicitly specifies
- an ordinal value, all fields or methods must explicitly specify an ordinal
- value.
-* For an *N*-field struct, the set of explicitly assigned ordinal values must be
- limited to the range *[0, N-1]*. Structs should include placeholder fields
- to fill the ordinal positions of removed fields (for example "Unused_Field"
- or "RemovedField", etc).
-
-You may reorder fields, but you must ensure that the ordinal values of existing
-fields remain unchanged. For example, the following struct remains
-backwards-compatible:
-
-``` cpp
-struct Employee {
- uint64 employee_id@0;
- [MinVersion=1] Date? birthday@2;
- string name@1;
- [MinVersion=1] string? nickname@3;
-};
-```
-
-### Versioned Interfaces
-
-There are two dimensions on which an interface can be extended
-
-**Appending New Parameters To Existing Methods**
-: Parameter lists are treated as structs internally, so all the rules of
- versioned structs apply to method parameter lists. The only difference is
- that the version number is scoped to the whole interface rather than to any
- individual parameter list.
-
-``` cpp
-// Old version:
-interface HumanResourceDatabase {
- QueryEmployee(uint64 id) => (Employee? employee);
-};
-
-// New version:
-interface HumanResourceDatabase {
- QueryEmployee(uint64 id, [MinVersion=1] bool retrieve_finger_print)
- => (Employee? employee,
- [MinVersion=1] array<uint8>? finger_print);
-};
-```
-
-Similar to [versioned structs](#Versioned-Structs), when you pass the parameter
-list of a request or response method to a destination using an older version of
-an interface, unrecognized fields are silently discarded.
-
- Please note that adding a response to a message which did not previously
- expect a response is a not a backwards-compatible change.
-
-**Appending New Methods**
-: Similarly, you can reorder methods with explicit ordinal values as long as
- the ordinal values of existing methods are unchanged.
-
-For example:
-
-``` cpp
-// Old version:
-interface HumanResourceDatabase {
- QueryEmployee(uint64 id) => (Employee? employee);
-};
-
-// New version:
-interface HumanResourceDatabase {
- QueryEmployee(uint64 id) => (Employee? employee);
-
- [MinVersion=1]
- AttachFingerPrint(uint64 id, array<uint8> finger_print)
- => (bool success);
-};
-```
-
-If a method call is not recognized, it is considered a validation error and the
-receiver will close its end of the interface pipe. For example, if a client on
-version 1 of the above interface sends an `AttachFingerPrint` request to an
-implementation of version 0, the client will be disconnected.
-
-Bindings target languages that support versioning expose means to query or
-assert the remote version from a client handle (*e.g.*, an
-`mojo::Remote<T>` in C++ bindings.)
-
-See
-[C++ Versioning Considerations](/mojo/public/cpp/bindings/README.md#Versioning-Considerations)
-and
-[Java Versioning Considerations](/mojo/public/java/bindings/README.md#Versioning-Considerations)
-
-### Versioned Enums
-
-**By default, enums are non-extensible**, which means that generated message
-validation code does not expect to see new values in the future. When an unknown
-value is seen for a non-extensible enum field or parameter, a validation error
-is raised.
-
-If you want an enum to be extensible in the future, you can apply the
-`[Extensible]` [attribute](#Attributes):
-
-``` cpp
-[Extensible]
-enum Department {
- kSales,
- kDev,
-};
-```
-
-And later you can extend this enum without breaking backwards compatibility:
-
-``` cpp
-[Extensible]
-enum Department {
- kSales,
- kDev,
- [MinVersion=1] kResearch,
-};
-```
-
-*** note
-**NOTE:** For versioned enum definitions, the use of a `[MinVersion]` attribute
-is strictly for documentation purposes. It has no impact on the generated code.
-***
-
-With extensible enums, bound interface implementations may receive unknown enum
-values and will need to deal with them gracefully. See
-[C++ Versioning Considerations](/mojo/public/cpp/bindings/README.md#Versioning-Considerations)
-for details.
-
-### Renaming versioned structs
-It's possible to rename versioned structs by using the `[RenamedFrom]` attribute.
-RenamedFrom
-
-``` cpp
-module asdf.mojom;
-
-// Old version:
-[Stable]
-struct OldStruct {
-};
-
-// New version:
-[Stable, RenamedFrom="asdf.mojom.OldStruct"]
-struct NewStruct {
-};
-```
-
-## Component targets
-
-If there are multiple components depending on the same mojom target within one binary,
-the target will need to be defined as `mojom_component` instead of `mojom`.
-Since `mojom` targets are generated `source_set` targets and `mojom_component` targets
-are generated `component` targets, you would use `mojom_component` in the same cases
-where you would use `component` for non-mojom files.
-*** note
-**NOTE**: by default, components for both blink and non-blink bindings are generated.
-Use the `disable_variants` target parameter to generate only non-blink bindings.
-You can also generate a `source_set` for one of the variants by defining
-[export_*](https://source.chromium.org/chromium/chromium/src/+/main:mojo/public/tools/bindings/mojom.gni;drc=739b9fbce50310c1dd2b59c279cd90a9319cb6e8;l=318)
-parameters for the `mojom_component` target.
-***
-
-## Grammar Reference
-
-Below is the (BNF-ish) context-free grammar of the Mojom language:
-
-```
-MojomFile = StatementList
-StatementList = Statement StatementList | Statement
-Statement = ModuleStatement | ImportStatement | Definition
-
-ModuleStatement = AttributeSection "module" Identifier ";"
-ImportStatement = "import" StringLiteral ";"
-Definition = Struct Union Interface Enum Feature Const
-
-AttributeSection = <empty> | "[" AttributeList "]"
-AttributeList = <empty> | NonEmptyAttributeList
-NonEmptyAttributeList = Attribute
- | Attribute "," NonEmptyAttributeList
-Attribute = Name
- | Name "=" Name
- | Name "=" Literal
-
-Struct = AttributeSection "struct" Name "{" StructBody "}" ";"
- | AttributeSection "struct" Name ";"
-StructBody = <empty>
- | StructBody Const
- | StructBody Enum
- | StructBody StructField
-StructField = AttributeSection TypeSpec Name Ordinal Default ";"
-
-Union = AttributeSection "union" Name "{" UnionBody "}" ";"
-UnionBody = <empty> | UnionBody UnionField
-UnionField = AttributeSection TypeSpec Name Ordinal ";"
-
-Interface = AttributeSection "interface" Name "{" InterfaceBody "}" ";"
-InterfaceBody = <empty>
- | InterfaceBody Const
- | InterfaceBody Enum
- | InterfaceBody Method
-Method = AttributeSection Name Ordinal "(" ParameterList ")" Response ";"
-ParameterList = <empty> | NonEmptyParameterList
-NonEmptyParameterList = Parameter
- | Parameter "," NonEmptyParameterList
-Parameter = AttributeSection TypeSpec Name Ordinal
-Response = <empty> | "=>" "(" ParameterList ")"
-
-TypeSpec = TypeName "?" | TypeName
-TypeName = BasicTypeName
- | Array
- | FixedArray
- | Map
- | InterfaceRequest
-BasicTypeName = Identifier | "associated" Identifier | HandleType | NumericType
-NumericType = "bool" | "int8" | "uint8" | "int16" | "uint16" | "int32"
- | "uint32" | "int64" | "uint64" | "float" | "double"
-HandleType = "handle" | "handle" "<" SpecificHandleType ">"
-SpecificHandleType = "message_pipe"
- | "shared_buffer"
- | "data_pipe_consumer"
- | "data_pipe_producer"
- | "platform"
-Array = "array" "<" TypeSpec ">"
-FixedArray = "array" "<" TypeSpec "," IntConstDec ">"
-Map = "map" "<" Identifier "," TypeSpec ">"
-InterfaceRequest = Identifier "&" | "associated" Identifier "&"
-
-Ordinal = <empty> | OrdinalValue
-
-Default = <empty> | "=" Constant
-
-Enum = AttributeSection "enum" Name "{" NonEmptyEnumValueList "}" ";"
- | AttributeSection "enum" Name "{" NonEmptyEnumValueList "," "}" ";"
-NonEmptyEnumValueList = EnumValue | NonEmptyEnumValueList "," EnumValue
-EnumValue = AttributeSection Name
- | AttributeSection Name "=" Integer
- | AttributeSection Name "=" Identifier
-
-; Note: `feature` is a weak keyword and can appear as, say, a struct field name.
-Feature = AttributeSection "feature" Name "{" FeatureBody "}" ";"
- | AttributeSection "feature" Name ";"
-FeatureBody = <empty>
- | FeatureBody FeatureField
-FeatureField = AttributeSection TypeSpec Name Default ";"
-
-Const = "const" TypeSpec Name "=" Constant ";"
-
-Constant = Literal | Identifier ";"
-
-Identifier = Name | Name "." Identifier
-
-Literal = Integer | Float | "true" | "false" | "default" | StringLiteral
-
-Integer = IntConst | "+" IntConst | "-" IntConst
-IntConst = IntConstDec | IntConstHex
-
-Float = FloatConst | "+" FloatConst | "-" FloatConst
-
-; The rules below are for tokens matched strictly according to the given regexes
-
-Identifier = /[a-zA-Z_][0-9a-zA-Z_]*/
-IntConstDec = /0|(1-9[0-9]*)/
-IntConstHex = /0[xX][0-9a-fA-F]+/
-OrdinalValue = /@(0|(1-9[0-9]*))/
-FloatConst = ... # Imagine it's close enough to C-style float syntax.
-StringLiteral = ... # Imagine it's close enough to C-style string literals, including escapes.
-```
-
-## Additional Documentation
-
-[Mojom Message Format](https://docs.google.com/document/d/13pv9cFh5YKuBggDBQ1-AL8VReF-IYpFOFpRfvWFrwio/edit)
-: Describes the wire format used by Mojo bindings interfaces over message
- pipes.
-
-[Input Format of Mojom Message Validation Tests](https://docs.google.com/document/d/1-y-2IYctyX2NPaLxJjpJfzVNWCC2SR2MJAD9MpIytHQ/edit)
-: Describes a text format used to facilitate bindings message validation
- tests.
diff --git a/utils/ipc/mojo/public/tools/bindings/checks/__init__.py b/utils/ipc/mojo/public/tools/bindings/checks/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/utils/ipc/mojo/public/tools/bindings/checks/__init__.py
+++ /dev/null
diff --git a/utils/ipc/mojo/public/tools/bindings/checks/mojom_attributes_check.py b/utils/ipc/mojo/public/tools/bindings/checks/mojom_attributes_check.py
deleted file mode 100644
index e6e4f2c9..00000000
--- a/utils/ipc/mojo/public/tools/bindings/checks/mojom_attributes_check.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright 2022 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Validate mojo attributes are allowed in Chrome before generation."""
-
-import mojom.generate.check as check
-import mojom.generate.module as module
-
-_COMMON_ATTRIBUTES = {
- 'EnableIf',
- 'EnableIfNot',
-}
-
-# For struct, union & parameter lists.
-_COMMON_FIELD_ATTRIBUTES = _COMMON_ATTRIBUTES | {
- 'MinVersion',
- 'RenamedFrom',
-}
-
-# Note: `Default`` goes on the default _value_, not on the enum.
-# Note: [Stable] without [Extensible] is not allowed.
-_ENUM_ATTRIBUTES = _COMMON_ATTRIBUTES | {
- 'Extensible',
- 'Native',
- 'Stable',
- 'RenamedFrom',
- 'Uuid',
-}
-
-# TODO(crbug.com/1234883) MinVersion is not needed for EnumVal.
-_ENUMVAL_ATTRIBUTES = _COMMON_ATTRIBUTES | {
- 'Default',
- 'MinVersion',
-}
-
-_INTERFACE_ATTRIBUTES = _COMMON_ATTRIBUTES | {
- 'RenamedFrom',
- 'RequireContext',
- 'RuntimeFeature',
- 'ServiceSandbox',
- 'Stable',
- 'Uuid',
-}
-
-_METHOD_ATTRIBUTES = _COMMON_ATTRIBUTES | {
- 'AllowedContext',
- 'MinVersion',
- 'NoInterrupt',
- 'RuntimeFeature',
- 'SupportsUrgent',
- 'Sync',
- 'UnlimitedSize',
-}
-
-_MODULE_ATTRIBUTES = _COMMON_ATTRIBUTES | {
- 'JavaConstantsClassName',
- 'JavaPackage',
-}
-
-_PARAMETER_ATTRIBUTES = _COMMON_FIELD_ATTRIBUTES
-
-_STRUCT_ATTRIBUTES = _COMMON_ATTRIBUTES | {
- 'CustomSerializer',
- 'JavaClassName',
- 'Native',
- 'Stable',
- 'RenamedFrom',
- 'Uuid',
-}
-
-_STRUCT_FIELD_ATTRIBUTES = _COMMON_FIELD_ATTRIBUTES
-
-_UNION_ATTRIBUTES = _COMMON_ATTRIBUTES | {
- 'Extensible',
- 'Stable',
- 'RenamedFrom',
- 'Uuid',
-}
-
-_UNION_FIELD_ATTRIBUTES = _COMMON_FIELD_ATTRIBUTES | {
- 'Default',
-}
-
-# TODO(https://crbug.com/1193875) empty this set and remove the allowlist.
-_STABLE_ONLY_ALLOWLISTED_ENUMS = {
- 'crosapi.mojom.OptionalBool',
- 'crosapi.mojom.TriState',
-}
-
-
-class Check(check.Check):
- def __init__(self, *args, **kwargs):
- super(Check, self).__init__(*args, **kwargs)
-
- def _Respell(self, allowed, attribute):
- for a in allowed:
- if a.lower() == attribute.lower():
- return f" - Did you mean: {a}?"
- return ""
-
- def _CheckAttributes(self, context, allowed, attributes):
- if not attributes:
- return
- for attribute in attributes:
- if not attribute in allowed:
- # Is there a close misspelling?
- hint = self._Respell(allowed, attribute)
- raise check.CheckException(
- self.module,
- f"attribute {attribute} not allowed on {context}{hint}")
-
- def _CheckEnumAttributes(self, enum):
- if enum.attributes:
- self._CheckAttributes("enum", _ENUM_ATTRIBUTES, enum.attributes)
- if 'Stable' in enum.attributes and not 'Extensible' in enum.attributes:
- full_name = f"{self.module.mojom_namespace}.{enum.mojom_name}"
- if full_name not in _STABLE_ONLY_ALLOWLISTED_ENUMS:
- raise check.CheckException(
- self.module,
- f"[Extensible] required on [Stable] enum {full_name}")
- for enumval in enum.fields:
- self._CheckAttributes("enum value", _ENUMVAL_ATTRIBUTES,
- enumval.attributes)
-
- def _CheckInterfaceAttributes(self, interface):
- self._CheckAttributes("interface", _INTERFACE_ATTRIBUTES,
- interface.attributes)
- for method in interface.methods:
- self._CheckAttributes("method", _METHOD_ATTRIBUTES, method.attributes)
- for param in method.parameters:
- self._CheckAttributes("parameter", _PARAMETER_ATTRIBUTES,
- param.attributes)
- if method.response_parameters:
- for param in method.response_parameters:
- self._CheckAttributes("parameter", _PARAMETER_ATTRIBUTES,
- param.attributes)
- for enum in interface.enums:
- self._CheckEnumAttributes(enum)
-
- def _CheckModuleAttributes(self):
- self._CheckAttributes("module", _MODULE_ATTRIBUTES, self.module.attributes)
-
- def _CheckStructAttributes(self, struct):
- self._CheckAttributes("struct", _STRUCT_ATTRIBUTES, struct.attributes)
- for field in struct.fields:
- self._CheckAttributes("struct field", _STRUCT_FIELD_ATTRIBUTES,
- field.attributes)
- for enum in struct.enums:
- self._CheckEnumAttributes(enum)
-
- def _CheckUnionAttributes(self, union):
- self._CheckAttributes("union", _UNION_ATTRIBUTES, union.attributes)
- for field in union.fields:
- self._CheckAttributes("union field", _UNION_FIELD_ATTRIBUTES,
- field.attributes)
-
- def CheckModule(self):
- """Note that duplicate attributes are forbidden at the parse phase.
- We also do not need to look at the types of any parameters, as they will be
- checked where they are defined. Consts do not have attributes so can be
- skipped."""
- self._CheckModuleAttributes()
- for interface in self.module.interfaces:
- self._CheckInterfaceAttributes(interface)
- for enum in self.module.enums:
- self._CheckEnumAttributes(enum)
- for struct in self.module.structs:
- self._CheckStructAttributes(struct)
- for union in self.module.unions:
- self._CheckUnionAttributes(union)
diff --git a/utils/ipc/mojo/public/tools/bindings/checks/mojom_attributes_check_unittest.py b/utils/ipc/mojo/public/tools/bindings/checks/mojom_attributes_check_unittest.py
deleted file mode 100644
index f1a50a4a..00000000
--- a/utils/ipc/mojo/public/tools/bindings/checks/mojom_attributes_check_unittest.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# Copyright 2022 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-import mojom.generate.check as check
-from mojom_bindings_generator import LoadChecks, _Generate
-from mojom_parser_test_case import MojomParserTestCase
-
-
-class FakeArgs:
- """Fakes args to _Generate - intention is to do just enough to run checks"""
-
- def __init__(self, tester, files=None):
- """ `tester` is MojomParserTestCase for paths.
- `files` will have tester path added."""
- self.checks_string = 'attributes'
- self.depth = tester.GetPath('')
- self.filelist = None
- self.filename = [tester.GetPath(x) for x in files]
- self.gen_directories = tester.GetPath('gen')
- self.generators_string = ''
- self.import_directories = []
- self.output_dir = tester.GetPath('out')
- self.scrambled_message_id_salt_paths = None
- self.typemaps = []
- self.variant = 'none'
-
-
-class MojoBindingsCheckTest(MojomParserTestCase):
- def _ParseAndGenerate(self, mojoms):
- self.ParseMojoms(mojoms)
- args = FakeArgs(self, files=mojoms)
- _Generate(args, {})
-
- def _testValid(self, filename, content):
- self.WriteFile(filename, content)
- self._ParseAndGenerate([filename])
-
- def _testThrows(self, filename, content, regexp):
- mojoms = []
- self.WriteFile(filename, content)
- mojoms.append(filename)
- with self.assertRaisesRegexp(check.CheckException, regexp):
- self._ParseAndGenerate(mojoms)
-
- def testLoads(self):
- """Validate that the check is registered under the expected name."""
- check_modules = LoadChecks('attributes')
- self.assertTrue(check_modules['attributes'])
-
- def testNoAnnotations(self):
- # Undecorated mojom should be fine.
- self._testValid(
- "a.mojom", """
- module a;
- struct Bar { int32 a; };
- enum Hello { kValue };
- union Thingy { Bar b; Hello hi; };
- interface Foo {
- Foo(int32 a, Hello hi, Thingy t) => (Bar b);
- };
- """)
-
- def testValidAnnotations(self):
- # Obviously this is meaningless and won't generate, but it should pass
- # the attribute check's validation.
- self._testValid(
- "a.mojom", """
- [JavaConstantsClassName="FakeClass",JavaPackage="org.chromium.Fake"]
- module a;
- [Stable, Extensible]
- enum Hello { [Default] kValue, kValue2, [MinVersion=2] kValue3 };
- [Native]
- enum NativeEnum {};
- [Stable,Extensible]
- union Thingy { Bar b; [Default]int32 c; Hello hi; };
-
- [Stable,RenamedFrom="module.other.Foo",
- Uuid="4C178401-4B07-4C2E-9255-5401A943D0C7"]
- struct Structure { Hello hi; };
-
- [ServiceSandbox=Hello.kValue,RequireContext=Hello.kValue,Stable,
- Uuid="2F17D7DD-865A-4B1C-9394-9C94E035E82F"]
- interface Foo {
- [AllowedContext=Hello.kValue]
- Foo@0(int32 a) => (int32 b);
- [MinVersion=2,Sync,UnlimitedSize,NoInterrupt]
- Bar@1(int32 b, [MinVersion=2]Structure? s) => (bool c);
- };
-
- [RuntimeFeature=test.mojom.FeatureName]
- interface FooFeatureControlled {};
-
- interface FooMethodFeatureControlled {
- [RuntimeFeature=test.mojom.FeatureName]
- MethodWithFeature() => (bool c);
- };
- """)
-
- def testWrongModuleStable(self):
- contents = """
- // err: module cannot be Stable
- [Stable]
- module a;
- enum Hello { kValue, kValue2, kValue3 };
- enum NativeEnum {};
- struct Structure { Hello hi; };
-
- interface Foo {
- Foo(int32 a) => (int32 b);
- Bar(int32 b, Structure? s) => (bool c);
- };
- """
- self._testThrows('b.mojom', contents,
- 'attribute Stable not allowed on module')
-
- def testWrongEnumDefault(self):
- contents = """
- module a;
- // err: default should go on EnumValue not Enum.
- [Default=kValue]
- enum Hello { kValue, kValue2, kValue3 };
- enum NativeEnum {};
- struct Structure { Hello hi; };
-
- interface Foo {
- Foo(int32 a) => (int32 b);
- Bar(int32 b, Structure? s) => (bool c);
- };
- """
- self._testThrows('b.mojom', contents,
- 'attribute Default not allowed on enum')
-
- def testWrongStructMinVersion(self):
- contents = """
- module a;
- enum Hello { kValue, kValue2, kValue3 };
- enum NativeEnum {};
- // err: struct cannot have MinVersion.
- [MinVersion=2]
- struct Structure { Hello hi; };
-
- interface Foo {
- Foo(int32 a) => (int32 b);
- Bar(int32 b, Structure? s) => (bool c);
- };
- """
- self._testThrows('b.mojom', contents,
- 'attribute MinVersion not allowed on struct')
-
- def testWrongMethodRequireContext(self):
- contents = """
- module a;
- enum Hello { kValue, kValue2, kValue3 };
- enum NativeEnum {};
- struct Structure { Hello hi; };
-
- interface Foo {
- // err: RequireContext is for interfaces.
- [RequireContext=Hello.kValue]
- Foo(int32 a) => (int32 b);
- Bar(int32 b, Structure? s) => (bool c);
- };
- """
- self._testThrows('b.mojom', contents,
- 'RequireContext not allowed on method')
-
- def testWrongMethodRequireContext(self):
- # crbug.com/1230122
- contents = """
- module a;
- interface Foo {
- // err: sync not Sync.
- [sync]
- Foo(int32 a) => (int32 b);
- };
- """
- self._testThrows('b.mojom', contents,
- 'attribute sync not allowed.*Did you mean: Sync')
-
- def testStableExtensibleEnum(self):
- # crbug.com/1193875
- contents = """
- module a;
- [Stable]
- enum Foo {
- kDefaultVal,
- kOtherVal = 2,
- };
- """
- self._testThrows('a.mojom', contents,
- 'Extensible.*?required.*?Stable.*?enum')
diff --git a/utils/ipc/mojo/public/tools/bindings/checks/mojom_definitions_check.py b/utils/ipc/mojo/public/tools/bindings/checks/mojom_definitions_check.py
deleted file mode 100644
index 702d41c3..00000000
--- a/utils/ipc/mojo/public/tools/bindings/checks/mojom_definitions_check.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2022 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Ensure no duplicate type definitions before generation."""
-
-import mojom.generate.check as check
-import mojom.generate.module as module
-
-
-class Check(check.Check):
- def __init__(self, *args, **kwargs):
- super(Check, self).__init__(*args, **kwargs)
-
- def CheckModule(self):
- kinds = dict()
- for module in self.module.imports:
- for kind in module.enums + module.structs + module.unions:
- kind_name = f'{kind.module.mojom_namespace}.{kind.mojom_name}'
- if kind_name in kinds:
- previous_module = kinds[kind_name]
- if previous_module.path != module.path:
- raise check.CheckException(
- self.module, f"multiple-definition for type {kind_name}" +
- f"(defined in both {previous_module} and {module})")
- kinds[kind_name] = kind.module
-
- for kind in self.module.enums + self.module.structs + self.module.unions:
- kind_name = f'{kind.module.mojom_namespace}.{kind.mojom_name}'
- if kind_name in kinds:
- previous_module = kinds[kind_name]
- raise check.CheckException(
- self.module, f"multiple-definition for type {kind_name}" +
- f"(previous definition in {previous_module})")
- return True
diff --git a/utils/ipc/mojo/public/tools/bindings/checks/mojom_interface_feature_check.py b/utils/ipc/mojo/public/tools/bindings/checks/mojom_interface_feature_check.py
deleted file mode 100644
index 07f51a64..00000000
--- a/utils/ipc/mojo/public/tools/bindings/checks/mojom_interface_feature_check.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright 2023 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Validate mojo runtime feature guarded interfaces are nullable."""
-
-import mojom.generate.check as check
-import mojom.generate.module as module
-
-
-class Check(check.Check):
- def __init__(self, *args, **kwargs):
- super(Check, self).__init__(*args, **kwargs)
-
- # `param` is an Interface of some sort.
- def _CheckNonNullableFeatureGuardedInterface(self, kind):
- # Only need to validate interface if it has a RuntimeFeature
- if not kind.kind.runtime_feature:
- return
- # Nullable (optional) is ok as the interface expects they might not be sent.
- if kind.is_nullable:
- return
- interface = kind.kind.mojom_name
- raise check.CheckException(
- self.module,
- f"interface {interface} has a RuntimeFeature but is not nullable")
-
- # `param` can be a lot of things so check if it is a remote/receiver.
- # Array/Map must be recursed into.
- def _CheckFieldOrParam(self, kind):
- if module.IsAnyInterfaceKind(kind):
- self._CheckNonNullableFeatureGuardedInterface(kind)
- if module.IsArrayKind(kind):
- self._CheckFieldOrParam(kind.kind)
- if module.IsMapKind(kind):
- self._CheckFieldOrParam(kind.key_kind)
- self._CheckFieldOrParam(kind.value_kind)
-
- def _CheckInterfaceFeatures(self, interface):
- for method in interface.methods:
- for param in method.parameters:
- self._CheckFieldOrParam(param.kind)
- if method.response_parameters:
- for param in method.response_parameters:
- self._CheckFieldOrParam(param.kind)
-
- def _CheckStructFeatures(self, struct):
- for field in struct.fields:
- self._CheckFieldOrParam(field.kind)
-
- def _CheckUnionFeatures(self, union):
- for field in union.fields:
- self._CheckFieldOrParam(field.kind)
-
- def CheckModule(self):
- """Validate that any runtime feature guarded interfaces that might be passed
- over mojo are nullable."""
- for interface in self.module.interfaces:
- self._CheckInterfaceFeatures(interface)
- for struct in self.module.structs:
- self._CheckStructFeatures(struct)
- for union in self.module.unions:
- self._CheckUnionFeatures(union)
diff --git a/utils/ipc/mojo/public/tools/bindings/checks/mojom_interface_feature_check_unittest.py b/utils/ipc/mojo/public/tools/bindings/checks/mojom_interface_feature_check_unittest.py
deleted file mode 100644
index e96152fd..00000000
--- a/utils/ipc/mojo/public/tools/bindings/checks/mojom_interface_feature_check_unittest.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# Copyright 2023 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-import mojom.generate.check as check
-from mojom_bindings_generator import LoadChecks, _Generate
-from mojom_parser_test_case import MojomParserTestCase
-
-
-class FakeArgs:
- """Fakes args to _Generate - intention is to do just enough to run checks"""
- def __init__(self, tester, files=None):
- """ `tester` is MojomParserTestCase for paths.
- `files` will have tester path added."""
- self.checks_string = 'features'
- self.depth = tester.GetPath('')
- self.filelist = None
- self.filename = [tester.GetPath(x) for x in files]
- self.gen_directories = tester.GetPath('gen')
- self.generators_string = ''
- self.import_directories = []
- self.output_dir = tester.GetPath('out')
- self.scrambled_message_id_salt_paths = None
- self.typemaps = []
- self.variant = 'none'
-
-
-class MojoBindingsCheckTest(MojomParserTestCase):
- def _ParseAndGenerate(self, mojoms):
- self.ParseMojoms(mojoms)
- args = FakeArgs(self, files=mojoms)
- _Generate(args, {})
-
- def assertValid(self, filename, content):
- self.WriteFile(filename, content)
- self._ParseAndGenerate([filename])
-
- def assertThrows(self, filename, content, regexp):
- mojoms = []
- self.WriteFile(filename, content)
- mojoms.append(filename)
- with self.assertRaisesRegexp(check.CheckException, regexp):
- self._ParseAndGenerate(mojoms)
-
- def testLoads(self):
- """Validate that the check is registered under the expected name."""
- check_modules = LoadChecks('features')
- self.assertTrue(check_modules['features'])
-
- def testNullableOk(self):
- self.assertValid(
- "a.mojom", """
- module a;
- // Scaffolding.
- feature kFeature {
- const string name = "Hello";
- const bool enabled_state = false;
- };
- [RuntimeFeature=kFeature]
- interface Guarded {
- };
-
- // Unguarded interfaces should be ok everywhere.
- interface NotGuarded { };
-
- // Optional (nullable) interfaces should be ok everywhere:
- struct Bar {
- pending_remote<Guarded>? remote;
- pending_receiver<Guarded>? receiver;
- };
- union Thingy {
- pending_remote<Guarded>? remote;
- pending_receiver<Guarded>? receiver;
- };
- interface Foo {
- Foo(
- pending_remote<Guarded>? remote,
- pending_receiver<Guarded>? receiver,
- pending_associated_remote<Guarded>? a_remote,
- pending_associated_receiver<Guarded>? a_receiver,
- // Unguarded interfaces do not have to be nullable.
- pending_remote<NotGuarded> remote,
- pending_receiver<NotGuarded> receiver,
- pending_associated_remote<NotGuarded> a_remote,
- pending_associated_receiver<NotGuarded> a_receiver
- ) => (
- pending_remote<Guarded>? remote,
- pending_receiver<Guarded>? receiver
- );
- Bar(array<pending_remote<Guarded>?> remote)
- => (map<string, pending_receiver<Guarded>?> a);
- };
- """)
-
- def testMethodParamsMustBeNullable(self):
- prelude = """
- module a;
- // Scaffolding.
- feature kFeature {
- const string name = "Hello";
- const bool enabled_state = false;
- };
- [RuntimeFeature=kFeature]
- interface Guarded { };
- """
- self.assertThrows(
- 'a.mojom', prelude + """
- interface Trial {
- Method(pending_remote<Guarded> a) => ();
- };
- """, 'interface Guarded has a RuntimeFeature')
- self.assertThrows(
- 'a.mojom', prelude + """
- interface Trial {
- Method(bool foo) => (pending_receiver<Guarded> a);
- };
- """, 'interface Guarded has a RuntimeFeature')
- self.assertThrows(
- 'a.mojom', prelude + """
- interface Trial {
- Method(pending_receiver<Guarded> a) => ();
- };
- """, 'interface Guarded has a RuntimeFeature')
- self.assertThrows(
- 'a.mojom', prelude + """
- interface Trial {
- Method(pending_associated_remote<Guarded> a) => ();
- };
- """, 'interface Guarded has a RuntimeFeature')
- self.assertThrows(
- 'a.mojom', prelude + """
- interface Trial {
- Method(pending_associated_receiver<Guarded> a) => ();
- };
- """, 'interface Guarded has a RuntimeFeature')
- self.assertThrows(
- 'a.mojom', prelude + """
- interface Trial {
- Method(array<pending_associated_receiver<Guarded>> a) => ();
- };
- """, 'interface Guarded has a RuntimeFeature')
- self.assertThrows(
- 'a.mojom', prelude + """
- interface Trial {
- Method(map<string, pending_associated_receiver<Guarded>> a) => ();
- };
- """, 'interface Guarded has a RuntimeFeature')
-
- def testStructUnionMembersMustBeNullable(self):
- prelude = """
- module a;
- // Scaffolding.
- feature kFeature {
- const string name = "Hello";
- const bool enabled_state = false;
- };
- [RuntimeFeature=kFeature]
- interface Guarded { };
- """
- self.assertThrows(
- 'a.mojom', prelude + """
- struct Trial {
- pending_remote<Guarded> a;
- };
- """, 'interface Guarded has a RuntimeFeature')
- self.assertThrows(
- 'a.mojom', prelude + """
- union Trial {
- pending_remote<Guarded> a;
- };
- """, 'interface Guarded has a RuntimeFeature')
diff --git a/utils/ipc/mojo/public/tools/bindings/checks/mojom_restrictions_check.py b/utils/ipc/mojo/public/tools/bindings/checks/mojom_restrictions_check.py
deleted file mode 100644
index d570e26c..00000000
--- a/utils/ipc/mojo/public/tools/bindings/checks/mojom_restrictions_check.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright 2022 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Validate RequireContext and AllowedContext annotations before generation."""
-
-import mojom.generate.check as check
-import mojom.generate.module as module
-
-
-class Check(check.Check):
- def __init__(self, *args, **kwargs):
- self.kind_to_interfaces = dict()
- super(Check, self).__init__(*args, **kwargs)
-
- def _IsPassedInterface(self, candidate):
- if isinstance(
- candidate.kind,
- (module.PendingReceiver, module.PendingRemote,
- module.PendingAssociatedReceiver, module.PendingAssociatedRemote)):
- return True
- return False
-
- def _CheckInterface(self, method, param):
- # |param| is a pending_x<Interface> so need .kind.kind to get Interface.
- interface = param.kind.kind
- if interface.require_context:
- if method.allowed_context is None:
- raise check.CheckException(
- self.module, "method `{}` has parameter `{}` which passes interface"
- " `{}` that requires an AllowedContext annotation but none exists.".
- format(
- method.mojom_name,
- param.mojom_name,
- interface.mojom_name,
- ))
- # If a string was provided, or if an enum was not imported, this will
- # be a string and we cannot validate that it is in range.
- if not isinstance(method.allowed_context, module.EnumValue):
- raise check.CheckException(
- self.module,
- "method `{}` has AllowedContext={} which is not a valid enum value."
- .format(method.mojom_name, method.allowed_context))
- # EnumValue must be from the same enum to be compared.
- if interface.require_context.enum != method.allowed_context.enum:
- raise check.CheckException(
- self.module, "method `{}` has parameter `{}` which passes interface"
- " `{}` that requires AllowedContext={} but one of kind `{}` was "
- "provided.".format(
- method.mojom_name,
- param.mojom_name,
- interface.mojom_name,
- interface.require_context.enum,
- method.allowed_context.enum,
- ))
- # RestrictContext enums have most privileged field first (lowest value).
- interface_value = interface.require_context.field.numeric_value
- method_value = method.allowed_context.field.numeric_value
- if interface_value < method_value:
- raise check.CheckException(
- self.module, "RequireContext={} > AllowedContext={} for method "
- "`{}` which passes interface `{}`.".format(
- interface.require_context.GetSpec(),
- method.allowed_context.GetSpec(), method.mojom_name,
- interface.mojom_name))
- return True
-
- def _GatherReferencedInterfaces(self, field):
- key = field.kind.spec
- # structs/unions can nest themselves so we need to bookkeep.
- if not key in self.kind_to_interfaces:
- # Might reference ourselves so have to create the list first.
- self.kind_to_interfaces[key] = set()
- for param in field.kind.fields:
- if self._IsPassedInterface(param):
- self.kind_to_interfaces[key].add(param)
- elif isinstance(param.kind, (module.Struct, module.Union)):
- for iface in self._GatherReferencedInterfaces(param):
- self.kind_to_interfaces[key].add(iface)
- return self.kind_to_interfaces[key]
-
- def _CheckParams(self, method, params):
- # Note: we have to repeat _CheckParams for each method as each might have
- # different AllowedContext= attributes. We cannot memoize this function,
- # but can do so for gathering referenced interfaces as their RequireContext
- # attributes do not change.
- for param in params:
- if self._IsPassedInterface(param):
- self._CheckInterface(method, param)
- elif isinstance(param.kind, (module.Struct, module.Union)):
- for interface in self._GatherReferencedInterfaces(param):
- self._CheckInterface(method, interface)
-
- def _CheckMethod(self, method):
- if method.parameters:
- self._CheckParams(method, method.parameters)
- if method.response_parameters:
- self._CheckParams(method, method.response_parameters)
-
- def CheckModule(self):
- for interface in self.module.interfaces:
- for method in interface.methods:
- self._CheckMethod(method)
diff --git a/utils/ipc/mojo/public/tools/bindings/checks/mojom_restrictions_checks_unittest.py b/utils/ipc/mojo/public/tools/bindings/checks/mojom_restrictions_checks_unittest.py
deleted file mode 100644
index a6cd71e2..00000000
--- a/utils/ipc/mojo/public/tools/bindings/checks/mojom_restrictions_checks_unittest.py
+++ /dev/null
@@ -1,254 +0,0 @@
-# Copyright 2022 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-import mojom.generate.check as check
-from mojom_bindings_generator import LoadChecks, _Generate
-from mojom_parser_test_case import MojomParserTestCase
-
-# Mojoms that we will use in multiple tests.
-basic_mojoms = {
- 'level.mojom':
- """
- module level;
- enum Level {
- kHighest,
- kMiddle,
- kLowest,
- };
- """,
- 'interfaces.mojom':
- """
- module interfaces;
- import "level.mojom";
- struct Foo {int32 bar;};
- [RequireContext=level.Level.kHighest]
- interface High {
- DoFoo(Foo foo);
- };
- [RequireContext=level.Level.kMiddle]
- interface Mid {
- DoFoo(Foo foo);
- };
- [RequireContext=level.Level.kLowest]
- interface Low {
- DoFoo(Foo foo);
- };
- """
-}
-
-
-class FakeArgs:
- """Fakes args to _Generate - intention is to do just enough to run checks"""
-
- def __init__(self, tester, files=None):
- """ `tester` is MojomParserTestCase for paths.
- `files` will have tester path added."""
- self.checks_string = 'restrictions'
- self.depth = tester.GetPath('')
- self.filelist = None
- self.filename = [tester.GetPath(x) for x in files]
- self.gen_directories = tester.GetPath('gen')
- self.generators_string = ''
- self.import_directories = []
- self.output_dir = tester.GetPath('out')
- self.scrambled_message_id_salt_paths = None
- self.typemaps = []
- self.variant = 'none'
-
-
-class MojoBindingsCheckTest(MojomParserTestCase):
- def _WriteBasicMojoms(self):
- for filename, contents in basic_mojoms.items():
- self.WriteFile(filename, contents)
- return list(basic_mojoms.keys())
-
- def _ParseAndGenerate(self, mojoms):
- self.ParseMojoms(mojoms)
- args = FakeArgs(self, files=mojoms)
- _Generate(args, {})
-
- def testLoads(self):
- """Validate that the check is registered under the expected name."""
- check_modules = LoadChecks('restrictions')
- self.assertTrue(check_modules['restrictions'])
-
- def testValidAnnotations(self):
- mojoms = self._WriteBasicMojoms()
-
- a = 'a.mojom'
- self.WriteFile(
- a, """
- module a;
- import "level.mojom";
- import "interfaces.mojom";
-
- interface PassesHigh {
- [AllowedContext=level.Level.kHighest]
- DoHigh(pending_receiver<interfaces.High> hi);
- };
- interface PassesMedium {
- [AllowedContext=level.Level.kMiddle]
- DoMedium(pending_receiver<interfaces.Mid> hi);
- [AllowedContext=level.Level.kMiddle]
- DoMediumRem(pending_remote<interfaces.Mid> hi);
- [AllowedContext=level.Level.kMiddle]
- DoMediumAssoc(pending_associated_receiver<interfaces.Mid> hi);
- [AllowedContext=level.Level.kMiddle]
- DoMediumAssocRem(pending_associated_remote<interfaces.Mid> hi);
- };
- interface PassesLow {
- [AllowedContext=level.Level.kLowest]
- DoLow(pending_receiver<interfaces.Low> hi);
- };
-
- struct One { pending_receiver<interfaces.High> hi; };
- struct Two { One one; };
- interface PassesNestedHigh {
- [AllowedContext=level.Level.kHighest]
- DoNestedHigh(Two two);
- };
-
- // Allowed as PassesHigh is not itself restricted.
- interface PassesPassesHigh {
- DoPass(pending_receiver<PassesHigh> hiho);
- };
- """)
- mojoms.append(a)
- self._ParseAndGenerate(mojoms)
-
- def _testThrows(self, filename, content, regexp):
- mojoms = self._WriteBasicMojoms()
- self.WriteFile(filename, content)
- mojoms.append(filename)
- with self.assertRaisesRegexp(check.CheckException, regexp):
- self._ParseAndGenerate(mojoms)
-
- def testMissingAnnotation(self):
- contents = """
- module b;
- import "level.mojom";
- import "interfaces.mojom";
-
- interface PassesHigh {
- // err: missing annotation.
- DoHigh(pending_receiver<interfaces.High> hi);
- };
- """
- self._testThrows('b.mojom', contents, 'require.*?AllowedContext')
-
- def testAllowTooLow(self):
- contents = """
- module b;
- import "level.mojom";
- import "interfaces.mojom";
-
- interface PassesHigh {
- // err: level is worse than required.
- [AllowedContext=level.Level.kMiddle]
- DoHigh(pending_receiver<interfaces.High> hi);
- };
- """
- self._testThrows('b.mojom', contents,
- 'RequireContext=.*?kHighest > AllowedContext=.*?kMiddle')
-
- def testWrongEnumInAllow(self):
- contents = """
- module b;
- import "level.mojom";
- import "interfaces.mojom";
- enum Blah {
- kZero,
- };
- interface PassesHigh {
- // err: different enums.
- [AllowedContext=Blah.kZero]
- DoHigh(pending_receiver<interfaces.High> hi);
- };
- """
- self._testThrows('b.mojom', contents, 'but one of kind')
-
- def testNotAnEnumInAllow(self):
- contents = """
- module b;
- import "level.mojom";
- import "interfaces.mojom";
- interface PassesHigh {
- // err: not an enum.
- [AllowedContext=doopdedoo.mojom.kWhatever]
- DoHigh(pending_receiver<interfaces.High> hi);
- };
- """
- self._testThrows('b.mojom', contents, 'not a valid enum value')
-
- def testMissingAllowedForNestedStructs(self):
- contents = """
- module b;
- import "level.mojom";
- import "interfaces.mojom";
- struct One { pending_receiver<interfaces.High> hi; };
- struct Two { One one; };
- interface PassesNestedHigh {
- // err: missing annotation.
- DoNestedHigh(Two two);
- };
- """
- self._testThrows('b.mojom', contents, 'require.*?AllowedContext')
-
- def testMissingAllowedForNestedUnions(self):
- contents = """
- module b;
- import "level.mojom";
- import "interfaces.mojom";
- struct One { pending_receiver<interfaces.High> hi; };
- struct Two { One one; };
- union Three {One one; Two two; };
- interface PassesNestedHigh {
- // err: missing annotation.
- DoNestedHigh(Three three);
- };
- """
- self._testThrows('b.mojom', contents, 'require.*?AllowedContext')
-
- def testMultipleInterfacesThrows(self):
- contents = """
- module b;
- import "level.mojom";
- import "interfaces.mojom";
- struct One { pending_receiver<interfaces.High> hi; };
- interface PassesMultipleInterfaces {
- [AllowedContext=level.Level.kMiddle]
- DoMultiple(
- pending_remote<interfaces.Mid> mid,
- pending_receiver<interfaces.High> hi,
- One one
- );
- };
- """
- self._testThrows('b.mojom', contents,
- 'RequireContext=.*?kHighest > AllowedContext=.*?kMiddle')
-
- def testMultipleInterfacesAllowed(self):
- """Multiple interfaces can be passed, all satisfy the level."""
- mojoms = self._WriteBasicMojoms()
-
- b = "b.mojom"
- self.WriteFile(
- b, """
- module b;
- import "level.mojom";
- import "interfaces.mojom";
- struct One { pending_receiver<interfaces.High> hi; };
- interface PassesMultipleInterfaces {
- [AllowedContext=level.Level.kHighest]
- DoMultiple(
- pending_receiver<interfaces.High> hi,
- pending_remote<interfaces.Mid> mid,
- One one
- );
- };
- """)
- mojoms.append(b)
- self._ParseAndGenerate(mojoms)
diff --git a/utils/ipc/mojo/public/tools/bindings/concatenate-files.py b/utils/ipc/mojo/public/tools/bindings/concatenate-files.py
deleted file mode 100755
index 4dd26d4a..00000000
--- a/utils/ipc/mojo/public/tools/bindings/concatenate-files.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2019 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# This utility concatenates several files into one. On Unix-like systems
-# it is equivalent to:
-# cat file1 file2 file3 ...files... > target
-#
-# The reason for writing a separate utility is that 'cat' is not available
-# on all supported build platforms, but Python is, and hence this provides
-# us with an easy and uniform way of doing this on all platforms.
-
-# for py2/py3 compatibility
-from __future__ import print_function
-
-import optparse
-import sys
-
-
-def Concatenate(filenames):
- """Concatenate files.
-
- Args:
- files: Array of file names.
- The last name is the target; all earlier ones are sources.
-
- Returns:
- True, if the operation was successful.
- """
- if len(filenames) < 2:
- print("An error occurred generating %s:\nNothing to do." % filenames[-1])
- return False
-
- try:
- with open(filenames[-1], "wb") as target:
- for filename in filenames[:-1]:
- with open(filename, "rb") as current:
- target.write(current.read())
- return True
- except IOError as e:
- print("An error occurred when writing %s:\n%s" % (filenames[-1], e))
- return False
-
-
-def main():
- parser = optparse.OptionParser()
- parser.set_usage("""Concatenate several files into one.
- Equivalent to: cat file1 ... > target.""")
- (_options, args) = parser.parse_args()
- sys.exit(0 if Concatenate(args) else 1)
-
-
-if __name__ == "__main__":
- main()
diff --git a/utils/ipc/mojo/public/tools/bindings/concatenate_and_replace_closure_exports.py b/utils/ipc/mojo/public/tools/bindings/concatenate_and_replace_closure_exports.py
deleted file mode 100755
index 7d56c9f9..00000000
--- a/utils/ipc/mojo/public/tools/bindings/concatenate_and_replace_closure_exports.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2018 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Simple utility which concatenates a set of files into a single output file
-while also stripping any goog.provide or goog.require lines. This allows us to
-provide a very primitive sort of "compilation" without any extra toolchain
-support and without having to modify otherwise compilable sources in the tree
-which use these directives.
-
-goog.provide lines are replaced with an equivalent invocation of
-mojo.internal.exportModule, which accomplishes essentially the same thing in an
-uncompiled context. A singular exception is made for the 'mojo.internal' export,
-which is instead replaced with an inlined assignment to initialize the
-namespace.
-"""
-
-from __future__ import print_function
-
-import optparse
-import re
-import sys
-
-
-_MOJO_INTERNAL_MODULE_NAME = "mojo.internal"
-_MOJO_EXPORT_MODULE_SYMBOL = "mojo.internal.exportModule"
-
-
-def FilterLine(filename, line, output):
- if line.startswith("goog.require"):
- return
-
- if line.startswith("goog.provide"):
- match = re.match(r"goog.provide\('([^']+)'\);", line)
- if not match:
- print("Invalid goog.provide line in %s:\n%s" % (filename, line))
- sys.exit(1)
-
- module_name = match.group(1)
- if module_name == _MOJO_INTERNAL_MODULE_NAME:
- output.write("self.mojo = { internal: {} };")
- else:
- output.write("%s('%s');\n" % (_MOJO_EXPORT_MODULE_SYMBOL, module_name))
- return
-
- output.write(line)
-
-def ConcatenateAndReplaceExports(filenames):
- if (len(filenames) < 2):
- print("At least two filenames (one input and the output) are required.")
- return False
-
- try:
- with open(filenames[-1], "w") as target:
- for filename in filenames[:-1]:
- with open(filename, "r") as current:
- for line in current.readlines():
- FilterLine(filename, line, target)
- return True
- except IOError as e:
- print("Error generating %s\n: %s" % (filenames[-1], e))
- return False
-
-def main():
- parser = optparse.OptionParser()
- parser.set_usage("""file1 [file2...] outfile
- Concatenate several files into one, stripping Closure provide and
- require directives along the way.""")
- (_, args) = parser.parse_args()
- sys.exit(0 if ConcatenateAndReplaceExports(args) else 1)
-
-
-if __name__ == "__main__":
- main()
diff --git a/utils/ipc/mojo/public/tools/bindings/gen_data_files_list.py b/utils/ipc/mojo/public/tools/bindings/gen_data_files_list.py
deleted file mode 100644
index c6daff03..00000000
--- a/utils/ipc/mojo/public/tools/bindings/gen_data_files_list.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2017 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Generates a list of all files in a directory.
-
-This script takes in a directory and an output file name as input.
-It then reads the directory and creates a list of all file names
-in that directory. The list is written to the output file.
-There is also an option to pass in '-p' or '--pattern'
-which will check each file name against a regular expression
-pattern that is passed in. Only files which match the regex
-will be written to the list.
-"""
-
-from __future__ import print_function
-
-import os
-import re
-import sys
-
-from optparse import OptionParser
-
-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 main():
- parser = OptionParser()
- parser.add_option('-d', '--directory', help='Read files from DIRECTORY')
- parser.add_option('-o', '--output', help='Write list to FILE')
- parser.add_option('-p',
- '--pattern',
- help='Only reads files that name matches PATTERN',
- default=".")
- (options, _) = parser.parse_args()
- pattern = re.compile(options.pattern)
- files = [f for f in os.listdir(options.directory) if pattern.match(f)]
-
- contents = '\n'.join(f for f in files) + '\n'
- WriteFile(contents, options.output)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/utils/ipc/mojo/public/tools/bindings/generate_type_mappings.py b/utils/ipc/mojo/public/tools/bindings/generate_type_mappings.py
deleted file mode 100755
index 4a53e2bf..00000000
--- a/utils/ipc/mojo/public/tools/bindings/generate_type_mappings.py
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2016 The Chromium Authors
-# 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 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'],
- 'forward_declaration': entry.get('forward_declaration', None),
- 'public_headers': config.get('traits_headers', []),
- 'traits_headers': config.get('traits_private_headers', []),
- 'copyable_pass_by_value': entry.get('copyable_pass_by_value',
- False),
- 'default_constructible': entry.get('default_constructible', True),
- '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 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, _ = parser.parse_known_args()
- typemaps = {}
- if params.cpp_config_path:
- typemaps = 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()
diff --git a/utils/ipc/mojo/public/tools/bindings/minify_with_terser.py b/utils/ipc/mojo/public/tools/bindings/minify_with_terser.py
deleted file mode 100755
index cefee7a4..00000000
--- a/utils/ipc/mojo/public/tools/bindings/minify_with_terser.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python3
-# Copyright 2023 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# This utility minifies JS files with terser.
-#
-# Instance of 'node' has no 'RunNode' member (no-member)
-# pylint: disable=no-member
-
-import argparse
-import os
-import sys
-
-_HERE_PATH = os.path.dirname(__file__)
-_SRC_PATH = os.path.normpath(os.path.join(_HERE_PATH, '..', '..', '..', '..'))
-_CWD = os.getcwd()
-sys.path.append(os.path.join(_SRC_PATH, 'third_party', 'node'))
-import node
-import node_modules
-
-
-def MinifyFile(input_file, output_file):
- node.RunNode([
- node_modules.PathToTerser(), input_file, '--mangle', '--compress',
- '--comments', 'false', '--output', output_file
- ])
-
-
-def main(argv):
- parser = argparse.ArgumentParser()
- parser.add_argument('--input', required=True)
- parser.add_argument('--output', required=True)
- args = parser.parse_args(argv)
-
- # Delete the output file if it already exists. It may be a sym link to the
- # input, because in non-optimized/pre-Terser builds the input file is copied
- # to the output location with gn copy().
- out_path = os.path.join(_CWD, args.output)
- if (os.path.exists(out_path)):
- os.remove(out_path)
-
- MinifyFile(os.path.join(_CWD, args.input), out_path)
-
-
-if __name__ == '__main__':
- main(sys.argv[1:])
diff --git a/utils/ipc/mojo/public/tools/bindings/mojom.gni b/utils/ipc/mojo/public/tools/bindings/mojom.gni
deleted file mode 100644
index 3f6e54e0..00000000
--- a/utils/ipc/mojo/public/tools/bindings/mojom.gni
+++ /dev/null
@@ -1,2118 +0,0 @@
-# Copyright 2014 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/closure_compiler/closure_args.gni")
-import("//third_party/closure_compiler/compile_js.gni")
-import("//third_party/protobuf/proto_library.gni")
-import("//ui/webui/resources/tools/generate_grd.gni")
-import("//ui/webui/webui_features.gni")
-
-import("//build/config/cast.gni")
-
-# TODO(rockot): Maybe we can factor these dependencies out of //mojo. They're
-# used to conditionally enable message ID scrambling in a way which is
-# consistent across toolchains and which is affected by branded vs non-branded
-# Chrome builds. Ideally we could create some generic knobs here that could be
-# flipped elsewhere though.
-import("//build/config/chrome_build.gni")
-import("//build/config/chromeos/ui_mode.gni")
-import("//build/config/features.gni")
-import("//build/config/nacl/config.gni")
-import("//build/toolchain/kythe.gni")
-import("//components/nacl/features.gni")
-import("//third_party/jinja2/jinja2.gni")
-import("//third_party/ply/ply.gni")
-import("//tools/ipc_fuzzer/ipc_fuzzer.gni")
-declare_args() {
- # Indicates whether typemapping should be supported in this build
- # configuration. This may be disabled when building external projects which
- # depend on //mojo but which do not need/want all of the Chromium tree
- # dependencies that come with typemapping.
- #
- # Note that (perhaps obviously) a huge amount of Chromium code will not build
- # with typemapping disabled, so it is never valid to set this to |false| in
- # any Chromium build configuration.
- enable_mojom_typemapping = true
-
- # Controls message ID scrambling behavior. If |true|, message IDs are
- # scrambled (i.e. randomized based on the contents of //chrome/VERSION) on
- # non-Chrome OS desktop platforms. Enabled on official builds by default.
- # Set to |true| to enable message ID scrambling on a specific build.
- # See also `enable_scrambled_message_ids` below for more details.
- enable_mojom_message_id_scrambling = is_official_build
-
- # Enables generating javascript fuzzing-related code and the bindings for the
- # MojoLPM fuzzer targets. Off by default.
- enable_mojom_fuzzer = false
-
- # Enables Closure compilation of generated JS lite bindings. In environments
- # where compilation is supported, any mojom target "foo" will also have a
- # corresponding "foo_js_library_for_compile" target generated.
- if (is_chromeos_ash) {
- enable_mojom_closure_compile = enable_js_type_check && optimize_webui
- }
-}
-
-# Closure libraries are needed for mojom_closure_compile, and when
-# js_type_check is enabled on Ash.
-if (is_chromeos_ash) {
- generate_mojom_closure_libraries =
- enable_mojom_closure_compile || enable_js_type_check
-} else {
- generate_mojom_closure_libraries = false
-}
-
-# NOTE: We would like to avoid scrambling message IDs where it doesn't add
-# value, so we limit the behavior to desktop builds for now. There is some
-# redundancy in the conditions here, but it is tolerated for clarity:
-# We're explicit about Mac, Windows, and Linux desktop support, but it's
-# also necessary to ensure that bindings in alternate toolchains (e.g.
-# NaCl IRT) are always consistent with the default toolchain; for that
-# reason we always enable scrambling within NaCl toolchains when possible,
-# as well as within the default toolchain when NaCl is enabled.
-#
-# Finally, because we *cannot* enable scrambling on Chrome OS (it would break
-# ARC) we have to explicitly opt out there even when NaCl is enabled (and
-# consequently also when building for NaCl toolchains.) For this reason we
-# check |target_os| explicitly, as it's consistent across all toolchains.
-#
-# TODO(crbug.com/1052397): Remove !chromeos_is_browser_only once
-# lacros-chrome switches to target_os="chromeos"
-enable_scrambled_message_ids =
- enable_mojom_message_id_scrambling &&
- (is_mac || is_win || (is_linux && !is_castos) ||
- ((enable_nacl || is_nacl) &&
- (target_os != "chromeos" && !chromeos_is_browser_only)))
-
-_mojom_tools_root = "//mojo/public/tools"
-_mojom_library_root = "$_mojom_tools_root/mojom/mojom"
-mojom_parser_script = "$_mojom_tools_root/mojom/mojom_parser.py"
-mojom_parser_sources = [
- "$_mojom_library_root/__init__.py",
- "$_mojom_library_root/error.py",
- "$_mojom_library_root/fileutil.py",
- "$_mojom_library_root/generate/__init__.py",
- "$_mojom_library_root/generate/check.py",
- "$_mojom_library_root/generate/generator.py",
- "$_mojom_library_root/generate/module.py",
- "$_mojom_library_root/generate/pack.py",
- "$_mojom_library_root/generate/template_expander.py",
- "$_mojom_library_root/generate/translate.py",
- "$_mojom_library_root/parse/__init__.py",
- "$_mojom_library_root/parse/ast.py",
- "$_mojom_library_root/parse/conditional_features.py",
- "$_mojom_library_root/parse/lexer.py",
- "$_mojom_library_root/parse/parser.py",
- "//tools/diagnosis/crbug_1001171.py",
-]
-
-mojom_generator_root = "$_mojom_tools_root/bindings"
-mojom_generator_script = "$mojom_generator_root/mojom_bindings_generator.py"
-mojom_generator_sources =
- mojom_parser_sources + [
- "$mojom_generator_root/checks/__init__.py",
- "$mojom_generator_root/checks/mojom_attributes_check.py",
- "$mojom_generator_root/checks/mojom_definitions_check.py",
- "$mojom_generator_root/checks/mojom_interface_feature_check.py",
- "$mojom_generator_root/checks/mojom_restrictions_check.py",
- "$mojom_generator_root/generators/__init__.py",
- "$mojom_generator_root/generators/cpp_util.py",
- "$mojom_generator_root/generators/mojom_cpp_generator.py",
- "$mojom_generator_root/generators/mojom_java_generator.py",
- "$mojom_generator_root/generators/mojom_js_generator.py",
- "$mojom_generator_root/generators/mojom_mojolpm_generator.py",
- "$mojom_generator_root/generators/mojom_ts_generator.py",
- "$mojom_generator_script",
- "//build/action_helpers.py",
- "//build/gn_helpers.py",
- "//build/zip_helpers.py",
- ]
-
-if (enable_scrambled_message_ids) {
- declare_args() {
- # The path to a file whose contents can be used as the basis for a message
- # ID scrambling salt.
- mojom_message_id_salt_path = "//chrome/VERSION"
- }
-
- assert(mojom_message_id_salt_path != "")
- message_scrambling_args = [
- "--scrambled_message_id_salt_path",
- rebase_path(mojom_message_id_salt_path, root_build_dir),
- ]
- message_scrambling_inputs = [ mojom_message_id_salt_path ]
-} else {
- message_scrambling_args = []
- message_scrambling_inputs = []
-}
-
-# Generates targets for building C++, JavaScript and Java bindings from mojom
-# files. The output files will go under the generated file directory tree with
-# the same path as each input file.
-#
-# Other targets should depend on one of these generated targets (where "foo"
-# is the target name):
-#
-# foo
-# C++ bindings.
-#
-# foo_blink
-# C++ bindings using Blink standard types.
-#
-# foo_java
-# Java bindings.
-#
-# foo_js
-# JavaScript bindings; used as compile-time dependency.
-#
-# foo_js_data_deps
-# JavaScript bindings; used as run-time dependency.
-#
-# Parameters:
-#
-# sources (optional if one of the deps sets listed below is present)
-# List of source .mojom files to compile.
-#
-# deps (optional)
-# Note: this can contain only other mojom targets.
-#
-# DEPRECATED: This is synonymous with public_deps because all mojom
-# dependencies must be public by design. Please use public_deps.
-#
-# public_deps (optional)
-# Note: this can contain only other mojom targets.
-#
-# parser_deps (optional)
-# List of non-mojom targets required for the mojom sources to be parsed.
-#
-# import_dirs (optional)
-# List of import directories that will get added when processing sources.
-#
-# input_root_override (optional)
-# Root path for the .mojom files used to generate the namespaces for
-# interfaces. Useful with targets outside //, e.g. in parent directories
-# above "//". The default input root is //
-# Example: Vivaldi's source root is "//vivaldi/",
-# and "//vivaldi/chromium/" is "//"
-# In such cases, not using this argument lead to the output files being
-# located in different directories than expected.
-#
-# testonly (optional)
-#
-# visibility (optional)
-#
-# visibility_blink (optional)
-# The value to use for visibility for the blink variant. If unset,
-# |visibility| is used.
-#
-# cpp_only (optional)
-# If set to true, only the C++ bindings targets will be generated.
-#
-# NOTE: If the global |enable_mojom_fuzzer| build arg is true, JS bindings
-# will still be generated even when |cpp_only| is set to |true|, unless
-# you also set |enable_fuzzing| to |false| in your mojom target.
-#
-# cpp_typemaps (optional)
-# A list of typemaps to be applied to the generated C++ bindings for this
-# mojom target. Note that this only applies to the non-Blink variant of
-# generated C++ bindings.
-#
-# Every typemap is a GN scope describing how one or more mojom types maps
-# to a non-mojom C++ type, including necessary deps and headers required
-# for the mapping to work. See the Typemaps section below.
-#
-# blink_cpp_typemaps (optional)
-# Same as above, but for the Blink variant of generated C++ bindings.
-#
-# cpp_proxy_target (optional)
-# The name of a target which all C++ dependencies will link against
-# instead of linking directly against this mojom target's generated C++
-# sources. Normally when declaring invoking the mojom("foo") target, GN
-# emits a source_set or component target named "foo" which encompasses the
-# default variant of generated C++ bindings. This changes that to instead
-# emit a group("foo") which merely forwards public_deps to the named
-# `cpp_proxy_target`. That target must in turn depend on
-# "foo_cpp_sources".
-#
-# This is useful primarily in conjunction with export_define et al to
-# embed generated C++ bindings within an existing component target.
-#
-# blink_cpp_proxy_target (optional)
-# Same concept as `cpp_proxy_target` above, but affects the generated
-# "foo_blink" Blink-variant C++ bindings.
-#
-# cpp_configs (optional)
-# A list of extra configs to apply to the default variant of generated C++
-# bindings.
-#
-# blink_cpp_configs (optional)
-# A list of extra configs to apply to the Blink variant of generated C++
-# bindings.
-#
-# mojom_source_deps (optional)
-# A list of mojoms this target depends upon. This is equivalent to
-# public_deps except that the C++ bindings depend on each of the named
-# "foo" targets' "foo_cpp_sources" rather than on foo's
-# `cpp_proxy_target`. It only makes sense to use this for dependencies
-# that set `cpp_proxy_target`, and only when the dependent mojom() would
-# otherwise have circular dependencies with that proxy target.
-#
-# mojom_blink_source_deps (optional)
-# Same as above but depends on "foo_blink_cpp_sources" and is used for
-# dependencies that specify a `blink_cpp_proxy_target`.
-#
-# generate_java (optional)
-# If set to true, Java bindings are generated for Android builds. If
-# |cpp_only| is set to true, it overrides this to prevent generation of
-# Java bindings.
-#
-# enable_js_fuzzing (optional)
-# Enables generation of javascript fuzzing sources for the target if the
-# global build arg |enable_mojom_fuzzer| is also set to |true|.
-# Defaults to |true|. If JS fuzzing generation is enabled for a target,
-# the target will always generate JS bindings even if |cpp_only| is set to
-# |true|. See note above.
-#
-# enable_mojolpm_fuzzing (optional)
-# Enables generation of fuzzing sources for the target if the global build
-# arg |enable_mojom_fuzzer| is also set to |true|. Defaults to |true|.
-#
-# support_lazy_serialization (optional)
-# If set to |true|, generated C++ bindings will effectively prefer to
-# transmit messages in an unserialized form when going between endpoints
-# in the same process. This avoids the runtime cost of serialization,
-# deserialization, and validation logic at the expensive of increased
-# code size. Defaults to |false|.
-#
-# disable_variants (optional)
-# If |true|, no variant sources will be generated for the target. Defaults
-# to |false|.
-#
-# disallow_native_types (optional)
-# If set to |true|, mojoms in this target may not apply the [Native]
-# attribute to struct or enum declarations. This avoids emitting code
-# which depends on legacy IPC serialization. Default is |false|, meaning
-# [Native] types are allowed.
-#
-# disallow_interfaces (optional)
-# If set to |true|, mojoms in this target may not define interfaces.
-# Generates bindings with a smaller set of dependencies. Defaults to
-# |false|.
-#
-# scramble_message_ids (optional)
-# If set to |true| (the default), generated mojom interfaces will use
-# scrambled ordinal identifiers in encoded messages.
-#
-# component_output_prefix (optional)
-# The prefix to use for the output_name of any component library emitted
-# for generated C++ bindings. If this is omitted, C++ bindings targets are
-# emitted as source_sets instead. Because this controls the name of the
-# output shared library binary in the root output directory, it must be
-# unique across the entire build configuration.
-#
-# This is required if |component_macro_prefix| is specified.
-#
-# component_macro_prefix (optional)
-# This specifies a macro prefix to use for component export macros and
-# should therefore be globally unique in the project. For example if this
-# is "FOO_BAR", then the generated C++ sources will be built with
-# IS_FOO_BAR_{suffix}_IMPL defined, and the generated public headers will
-# annotate public symbol definitions with
-# COMPONENT_EXPORT(FOO_BAR_{suffix}). "suffix" in this case depends on
-# which internal subtarget is generating the code (e.g. "SHARED", or a
-# variant name like "BLINK").
-#
-# enabled_features (optional)
-# Definitions in a mojom file can be guarded by an EnableIf attribute. If
-# the value specified by the attribute does not match any items in the
-# list of enabled_features, the definition will be disabled, with no code
-# emitted for it.
-#
-# generate_closure_exports (optional)
-# Generates JS lite bindings will use goog.provide and goog.require
-# annotations to export its symbols and import core Mojo bindings support
-# and other mojom dependency modules. Use this if you plan to compile your
-# bindings into a larger JS binary. Defaults to |false|, instead
-# generating JS lite bindings which assume they will be manually loaded in
-# correct dependency order. Note that this only has an effect if
-# the |enable_mojom_closure_compile| global arg is set to |true| as well.
-#
-# generate_webui_js_bindings (optional)
-# Generate WebUI bindings in JavaScript rather than TypeScript. Defaults
-# to false. ChromeOS only parameter.
-#
-# generate_legacy_js_bindings (optional)
-# Generate js_data_deps target containing legacy JavaScript bindings files
-# for Blink tests and other non-WebUI users when generating TypeScript
-# bindings for WebUI. Ignored if generate_webui_js_bindings is set to
-# true.
-#
-# js_generate_struct_deserializers (optional)
-# Generates JS deerialize methods for structs.
-#
-# extra_cpp_template_paths (optional)
-# List of extra C++ templates that are used to generate additional source
-# and/or header files. The templates should end with extension ".tmpl".
-#
-# webui_module_path (optional)
-# The path or URL at which modules generated by this target will be
-# accessible to WebUI pages. This may either be an absolute path or
-# a full URL path starting with "chrome://resources/mojo". If this path
-# is not specified, WebUI bindings will not be generated.
-#
-# If an absolute path, a WebUI page may only import these modules if
-# they are added to that page's data source (usually by adding the
-# modules to the mojo_files list for build_webui(), or by listing the
-# files as inputs to the page's ts_library() and/or generate_grd() build
-# steps.
-#
-# If this is is instead a URL string starting with
-# "chrome://resources/mojo", the resulting bindings files should
-# be added to one of the lists in ui/webui/resources/mojo/BUILD.gn,
-# at which point they will be made available to all WebUI pages at the
-# given URL.
-#
-# Note: WebUI module bindings are generated in TypeScript by default,
-# unless |generate_webui_js_bindings| is specified as true.
-#
-# The following parameters are used to support the component build. They are
-# needed so that bindings which are linked with a component can use the same
-# export settings for classes. The first three are for the chromium variant, and
-# the last three are for the blink variant. These parameters can also override
-# |component_macro_prefix| for a specific variant, allowing e.g. one variant
-# to be linked into a larger non-mojom component target, while all other
-# variants get their own unique component target.
-# export_class_attribute (optional)
-# The attribute to add to the class declaration. e.g. "CONTENT_EXPORT"
-# export_define (optional)
-# A define to be added to the source_set which is needed by the export
-# header. e.g. "CONTENT_IMPLEMENTATION=1"
-# export_header (optional)
-# A header to be added to the generated bindings to support the component
-# build. e.g. "content/common/content_export.h"
-# export_class_attribute_blink (optional)
-# export_define_blink (optional)
-# export_header_blink (optional)
-# These three parameters are the blink variants of the previous 3.
-#
-# The following parameters are used to correct component build dependencies.
-# They are needed so mojom-mojom dependencies follow the rule that dependencies
-# on a source set in another component are replaced by a dependency on the
-# containing component. The first two are for the chromium variant; the other
-# two are for the blink variant.
-# overridden_deps (optional)
-# The list of mojom deps to be overridden.
-# component_deps (optional)
-# The list of component deps to add to replace overridden_deps.
-# overridden_deps_blink (optional)
-# component_deps_blink (optional)
-# These two parameters are the blink variants of the previous two.
-#
-# check_includes_blink (optional)
-# Overrides the check_includes variable for the blink variant.
-# If check_includes_blink is not defined, the check_includes variable
-# retains its original value.
-#
-# Typemaps
-# ========
-# The cpp_typemaps and blink_cpp_typemaps each specify an optional list of
-# typemapping configurations. Each configuration is a GN scope with metadata
-# describing what and how to map.
-#
-# Typemap scope parameters:
-# types
-# A list of type specifications for this typemap. Each type specification
-# is a nested GN scope which can be expressed with the following syntax:
-#
-# {
-# mojom = "foo.mojom.Bar"
-# cpp = "::foo::LegitBar"
-# move_only = true
-# # etc...
-# }
-#
-# Each type specification supports the following values:
-#
-# mojom (required)
-# The fully qualified name of a mojom type to be mapped. This is a
-# string like "foo.mojom.Bar".
-#
-# cpp (required)
-# The fully qualified name of the C++ type to which the mojom type
-# should be mapped in generated bindings. This is a string like
-# "::base::Value" or "std::vector<::base::Value>".
-#
-# copyable_pass_by_value (optional)
-# A boolean value (default false) which effectively indicates
-# whether the C++ type is very cheap to copy. If so, generated
-# bindings will pass by value but not use std::move() at call sites.
-#
-# default_constructible (optional)
-# A boolean value (default true) which indicates whether the C++
-# type is default constructible. If a C++ type is not default
-# constructible (e.g. the implementor of the type prefers not to
-# publicly expose a default constructor that creates an object in an
-# invalid state), Mojo will instead construct C++ type with an
-# argument of the type `mojo::DefaultConstruct::Tag` (essentially a
-# passkey-like type specifically for this use case).
-#
-# force_serialize (optional)
-# A boolean value (default false) which disables lazy serialization
-# of the typemapped type if lazy serialization is enabled for the
-# mojom target applying this typemap.
-#
-# forward_declaration (optional)
-# A forward declaration of the C++ type, which bindings that don't
-# need the full type definition can use to reduce the size of
-# the generated code. This is a string like
-# "namespace base { class Value; }".
-#
-# hashable (optional)
-# A boolean value (default false) indicating whether the C++ type is
-# hashable. Set to true if true AND needed (i.e. you need to use the
-# type as the key of a mojom map).
-#
-# move_only (optional)
-# A boolean value (default false) which indicates whether the C++
-# type is move-only. If true, generated bindings will pass the type
-# by value and use std::move() at call sites.
-#
-# nullable_is_same_type (optional)
-# A boolean value (default false) which indicates that the C++ type
-# has some baked-in semantic notion of a "null" state. If true, the
-# traits for the type must define IsNull and SetToNull methods.
-#
-# When false, nullable fields are represented by wrapping the C++
-# type with absl::optional, and null values are simply
-# absl::nullopt.
-#
-# Additional typemap scope parameters:
-#
-# traits_headers (optional)
-# Headers which must be included in the generated mojom in order for
-# serialization to be possible. This generally means including at least
-# the header for the corresponding mojom traits definitions.
-#
-# traits_private_headers (optional)
-# Headers which must be included in generated C++ serialization code for
-# a mojom using the typemap. This should be used only when including a
-# header in |traits_headers| is problematic for compilation, as is
-# sometimes the case with legacy IPC message headers.
-#
-# traits_sources (optional)
-# The references to the source files (typically a single .cc and .h file)
-# defining an appropriate set of EnumTraits or StructTraits, etc for the
-# the type-mapping. Using this will cause the listed sources to be
-# integrated directly into the dependent mojom's generated type-mapping
-# targets.
-#
-# Prefer using |traits_public_deps| over inlined |traits_sources|, as this
-# will generally lead to easier build maintenance over time.
-#
-# NOTE: If a typemap is shared by Blink and non-Blink bindings, you cannot
-# use this and MUST use |traits_public_deps| to reference traits built
-# within a separate target.
-#
-# traits_deps / traits_public_deps (optional)
-# Any dependencies of sources in |traits_headers| or |traits_sources| must
-# be listed here.
-#
-template("mojom") {
- assert(
- defined(invoker.sources) || defined(invoker.deps) ||
- defined(invoker.public_deps),
- "\"sources\" or \"deps\" must be defined for the $target_name template.")
-
- if (defined(invoker.export_class_attribute) ||
- defined(invoker.export_define) || defined(invoker.export_header)) {
- assert(defined(invoker.export_class_attribute))
- assert(defined(invoker.export_define) || defined(invoker.cpp_configs))
- assert(defined(invoker.export_header))
- }
- if (defined(invoker.export_class_attribute_blink) ||
- defined(invoker.export_define_blink) ||
- defined(invoker.export_header_blink)) {
- assert(defined(invoker.export_class_attribute_blink))
- assert(defined(invoker.export_define_blink) ||
- defined(invoker.blink_cpp_configs))
- assert(defined(invoker.export_header_blink))
-
- # Not all platforms use the Blink variant, so make sure GN doesn't complain
- # about these values being inconsequential.
- not_needed(invoker,
- [
- "export_class_attribute_blink",
- "export_define_blink",
- "export_header_blink",
- ])
- }
- if (defined(invoker.overridden_deps) || defined(invoker.component_deps)) {
- assert(defined(invoker.overridden_deps))
- assert(defined(invoker.component_deps))
- }
-
- if (defined(invoker.overridden_deps_blink) ||
- defined(invoker.component_deps_blink)) {
- assert(defined(invoker.overridden_deps_blink))
- assert(defined(invoker.component_deps_blink))
- }
-
- # Type-mapping may be disabled or we may not generate C++ bindings.
- not_needed(invoker,
- [
- "cpp_typemaps",
- "blink_cpp_typemaps",
- ])
-
- require_full_cpp_deps =
- !defined(invoker.disallow_native_types) ||
- !invoker.disallow_native_types || !defined(invoker.disallow_interfaces) ||
- !invoker.disallow_interfaces
-
- all_deps = []
- mojom_cpp_deps = []
- if (defined(invoker.deps)) {
- all_deps += invoker.deps
- mojom_cpp_deps += invoker.deps
- }
- if (defined(invoker.public_deps)) {
- all_deps += invoker.public_deps
- mojom_cpp_deps += invoker.public_deps
- }
- if (defined(invoker.mojom_source_deps)) {
- all_deps += invoker.mojom_source_deps
- }
- if (defined(invoker.mojom_blink_source_deps)) {
- all_deps += invoker.mojom_blink_source_deps
- }
- not_needed([ "mojom_deps" ])
-
- if (defined(invoker.component_macro_prefix)) {
- assert(defined(invoker.component_output_prefix))
- }
-
- group("${target_name}__is_mojom") {
- }
-
- # Explicitly ensure that all dependencies (invoker.deps and
- # invoker.public_deps) are mojom targets.
- group("${target_name}__check_deps_are_all_mojom") {
- deps = []
- foreach(d, all_deps) {
- name = get_label_info(d, "label_no_toolchain")
- toolchain = get_label_info(d, "toolchain")
- deps += [ "${name}__is_mojom(${toolchain})" ]
- }
- }
-
- sources_list = []
- if (defined(invoker.sources)) {
- sources_list = invoker.sources
- }
-
- # Listed sources may be relative to the current target dir, or they may be
- # absolute paths, including paths to generated mojom files. While those are
- # fine as-is for input references, deriving output paths can be more subtle.
- #
- # Here we rewrite all source paths to be relative to the root build dir and
- # strip any root_gen_dir prefixes.
- #
- # So for a target in //foo/bar with:
- #
- # sources = [
- # "a.mojom",
- # "b/c.mojom",
- # "//baz/d.mojom",
- # "$target_gen_dir/e.mojom",
- # ]
- #
- # output_file_base_paths will be:
- #
- # [
- # "foo/bar/a.mojom",
- # "foo/bar/b/c.mojom",
- # "baz/d.mojom",
- # "foo/bar/e.mojom",
- # ]
- #
- # This result is essentially a list of base filename paths which are suitable
- # for the naming of any generated output files derived from their
- # corresponding input mojoms. These paths are always considered to be relative
- # to root_gen_dir.
- if (defined(invoker.input_root_override)) {
- source_abspaths = rebase_path(sources_list, invoker.input_root_override)
- } else {
- source_abspaths = rebase_path(sources_list, "//")
- }
- output_file_base_paths = []
- foreach(path, source_abspaths) {
- output_file_base_paths +=
- [ string_replace(path, rebase_path(root_gen_dir, "//") + "/", "") ]
- }
-
- # Sanity check that either all input files have a .mojom extension, or
- # all input files have a .test-mojom extension AND |testonly| is |true|.
- sources_list_filenames =
- process_file_template(sources_list, "{{source_file_part}}")
- sources_list_filenames_with_mojom_extension =
- process_file_template(sources_list, "{{source_name_part}}.mojom")
- if (sources_list_filenames != sources_list_filenames_with_mojom_extension) {
- sources_list_filenames_with_test_mojom_extension =
- process_file_template(sources_list, "{{source_name_part}}.test-mojom")
- if (sources_list_filenames ==
- sources_list_filenames_with_test_mojom_extension) {
- assert(
- defined(invoker.testonly) && invoker.testonly,
- "mojom targets for .test-mojom files must set |testonly| to |true|")
- } else {
- assert(
- false,
- "One or more mojom files has an invalid extension. The only " +
- "allowed extensions are .mojom and .test-mojom, and any given " +
- "mojom target must use one or the other exclusively.")
- }
- }
-
- build_metadata_filename = "$target_gen_dir/$target_name.build_metadata"
- build_metadata = {
- }
- build_metadata.sources = rebase_path(sources_list, target_gen_dir)
- build_metadata.deps = []
- foreach(dep, all_deps) {
- dep_target_gen_dir = get_label_info(dep, "target_gen_dir")
- dep_name = get_label_info(dep, "name")
- build_metadata.deps +=
- [ rebase_path("$dep_target_gen_dir/$dep_name.build_metadata",
- target_gen_dir) ]
- }
- write_file(build_metadata_filename, build_metadata, "json")
-
- generate_js_fuzzing =
- (!defined(invoker.enable_js_fuzzing) || invoker.enable_js_fuzzing) &&
- enable_mojom_fuzzer && (!defined(invoker.testonly) || !invoker.testonly)
-
- generate_mojolpm_fuzzing =
- (!defined(invoker.enable_mojolpm_fuzzing) ||
- invoker.enable_mojolpm_fuzzing) && enable_mojom_fuzzer &&
- (!defined(invoker.testonly) || !invoker.testonly)
-
- parser_target_name = "${target_name}__parser"
- parser_deps = []
- foreach(dep, all_deps) {
- _label = get_label_info(dep, "label_no_toolchain")
- parser_deps += [ "${_label}__parser" ]
- }
- if (defined(invoker.parser_deps)) {
- parser_deps += invoker.parser_deps
- }
- if (sources_list == []) {
- # Even without sources we generate a parser target to at least forward
- # other parser dependencies.
- group(parser_target_name) {
- public_deps = parser_deps
- }
- } else {
- enabled_features = []
- if (defined(invoker.enabled_features)) {
- enabled_features += invoker.enabled_features
- }
- if (is_posix) {
- enabled_features += [ "is_posix" ]
- }
- if (is_android) {
- enabled_features += [ "is_android" ]
- } else if (is_chromeos_ash) {
- enabled_features += [
- "is_chromeos",
- "is_chromeos_ash",
- ]
- } else if (is_chromeos_lacros) {
- enabled_features += [
- "is_chromeos",
- "is_chromeos_lacros",
- ]
- } else if (is_fuchsia) {
- enabled_features += [ "is_fuchsia" ]
- } else if (is_ios) {
- enabled_features += [ "is_ios" ]
- } else if (is_linux) {
- enabled_features += [ "is_linux" ]
- } else if (is_mac) {
- enabled_features += [ "is_mac" ]
- } else if (is_win) {
- enabled_features += [ "is_win" ]
- }
-
- if (is_apple) {
- enabled_features += [ "is_apple" ]
- }
-
- action(parser_target_name) {
- allow_remote = true
- custom_processor = "mojom_parser"
- script = mojom_parser_script
- inputs = mojom_parser_sources + ply_sources + [ build_metadata_filename ]
- sources = sources_list
- public_deps = parser_deps
- outputs = []
- foreach(base_path, output_file_base_paths) {
- filename = get_path_info(base_path, "file")
- dirname = get_path_info(base_path, "dir")
- outputs += [ "$root_gen_dir/$dirname/${filename}-module" ]
- }
-
- filelist = []
- foreach(source, sources_list) {
- filelist += [ rebase_path(source, root_build_dir) ]
- }
-
- # Workaround for https://github.com/ninja-build/ninja/issues/1966.
- rsp_file = "$target_gen_dir/${target_name}.rsp"
- write_file(rsp_file, filelist)
- inputs += [ rsp_file ]
-
- args = [
- # Resolve relative input mojom paths against both the root src dir and
- # the root gen dir.
- "--input-root",
- rebase_path("//.", root_build_dir),
- "--input-root",
- rebase_path(root_gen_dir, root_build_dir),
-
- "--output-root",
- rebase_path(root_gen_dir, root_build_dir),
-
- "--mojom-file-list=" + rebase_path(rsp_file, root_build_dir),
-
- "--check-imports",
- rebase_path(build_metadata_filename, root_build_dir),
- ]
-
- if (defined(invoker.input_root_override)) {
- args += [
- "--input-root",
- rebase_path(invoker.input_root_override, root_build_dir),
- ]
- }
-
- foreach(enabled_feature, enabled_features) {
- args += [
- "--enable-feature",
- enabled_feature,
- ]
- }
-
- if (defined(invoker.webui_module_path)) {
- args += [
- "--add-module-metadata",
- "webui_module_path=${invoker.webui_module_path}",
- ]
- if (defined(invoker.generate_webui_js_bindings) &&
- invoker.generate_webui_js_bindings) {
- args += [
- "--add-module-metadata",
- "generate_webui_js=True",
- ]
- }
- }
- }
- }
-
- generator_cpp_message_ids_target_name = "${target_name}__generate_message_ids"
-
- # Generate code that is shared by different variants.
- if (sources_list != []) {
- base_dir = "//"
- if (defined(invoker.input_root_override)) {
- base_dir = invoker.input_root_override
- }
-
- common_generator_args = [
- "--use_bundled_pylibs",
- "-o",
- rebase_path(root_gen_dir, root_build_dir),
- "generate",
- "-d",
- rebase_path(base_dir, root_build_dir),
- "-I",
- rebase_path("//", root_build_dir),
- "--bytecode_path",
- rebase_path("$root_gen_dir/mojo/public/tools/bindings", root_build_dir),
- ]
- if (defined(invoker.input_root_override)) {
- common_generator_args += [
- "-I",
- rebase_path(invoker.input_root_override, root_build_dir),
- ]
- }
-
- if (defined(invoker.disallow_native_types) &&
- invoker.disallow_native_types) {
- common_generator_args += [ "--disallow_native_types" ]
- }
-
- if (defined(invoker.disallow_interfaces) && invoker.disallow_interfaces) {
- common_generator_args += [ "--disallow_interfaces" ]
- }
-
- if (defined(invoker.import_dirs)) {
- foreach(import_dir, invoker.import_dirs) {
- common_generator_args += [
- "-I",
- rebase_path(import_dir, root_build_dir),
- ]
- }
- }
-
- if (defined(invoker.component_macro_prefix)) {
- shared_component_export_macro =
- "COMPONENT_EXPORT(${invoker.component_macro_prefix}_SHARED)"
- shared_component_impl_macro =
- "IS_${invoker.component_macro_prefix}_SHARED_IMPL"
- shared_component_output_name = "${invoker.component_output_prefix}_shared"
- } else if (defined(invoker.export_class_attribute_shared) ||
- defined(invoker.export_class_attribute)) {
- if (defined(invoker.export_class_attribute_shared)) {
- assert(defined(invoker.export_header_shared))
- shared_component_export_macro = invoker.export_class_attribute_shared
- shared_component_impl_macro = invoker.export_define_shared
- } else {
- assert(!defined(invoker.export_header_shared))
-
- # If no explicit shared attribute/define was provided by the invoker,
- # we derive some reasonable settings frorm the default variant.
- shared_component_export_macro = "COMPONENT_EXPORT(MOJOM_SHARED_" +
- invoker.export_class_attribute + ")"
- shared_component_impl_macro =
- "IS_MOJOM_SHARED_" + invoker.export_class_attribute + "_IMPL"
- }
-
- if (defined(invoker.component_output_prefix)) {
- shared_component_output_name =
- "${invoker.component_output_prefix}_shared"
- } else {
- shared_component_output_name = "${target_name}_shared"
- }
- }
-
- action(generator_cpp_message_ids_target_name) {
- allow_remote = true
- script = mojom_generator_script
- inputs = mojom_generator_sources + jinja2_sources
- sources = sources_list +
- [ "$root_gen_dir/mojo/public/tools/bindings/cpp_templates.zip" ]
- deps = [
- ":$parser_target_name",
- "//mojo/public/tools/bindings:precompile_templates",
- ]
- if (defined(invoker.parser_deps)) {
- deps += invoker.parser_deps
- }
- outputs = []
- args = common_generator_args
- filelist = []
- foreach(source, sources_list) {
- filelist += [ rebase_path(source, root_build_dir) ]
- }
- foreach(base_path, output_file_base_paths) {
- filename = get_path_info(base_path, "file")
- dirname = get_path_info(base_path, "dir")
- inputs += [ "$root_gen_dir/$dirname/${filename}-module" ]
- outputs += [ "$root_gen_dir/$base_path-shared-message-ids.h" ]
- }
-
- # Workaround for https://github.com/ninja-build/ninja/issues/1966.
- rsp_file = "$target_gen_dir/${target_name}.rsp"
- write_file(rsp_file, filelist)
- inputs += [ rsp_file ]
-
- args += [
- "--filelist=" + rebase_path(rsp_file, root_build_dir),
- "--generate_non_variant_code",
- "--generate_message_ids",
- "-g",
- "c++",
- ]
-
- if (!defined(invoker.scramble_message_ids) ||
- invoker.scramble_message_ids) {
- inputs += message_scrambling_inputs
- args += message_scrambling_args
- }
- }
-
- generator_shared_target_name = "${target_name}_shared__generator"
-
- action(generator_shared_target_name) {
- allow_remote = true
- visibility = [ ":*" ]
- script = mojom_generator_script
- inputs = mojom_generator_sources + jinja2_sources
- sources = sources_list +
- [ "$root_gen_dir/mojo/public/tools/bindings/cpp_templates.zip" ]
- deps = [
- ":$parser_target_name",
- "//mojo/public/tools/bindings:precompile_templates",
- ]
- if (defined(invoker.parser_deps)) {
- deps += invoker.parser_deps
- }
-
- outputs = []
- args = common_generator_args
- filelist = []
- foreach(source, sources_list) {
- filelist += [ rebase_path(source, root_build_dir) ]
- }
- foreach(base_path, output_file_base_paths) {
- # Need the mojom-module as an input to this action.
- filename = get_path_info(base_path, "file")
- dirname = get_path_info(base_path, "dir")
- inputs += [ "$root_gen_dir/$dirname/${filename}-module" ]
-
- outputs += [
- "$root_gen_dir/$base_path-features.h",
- "$root_gen_dir/$base_path-params-data.h",
- "$root_gen_dir/$base_path-shared-internal.h",
- "$root_gen_dir/$base_path-shared.cc",
- "$root_gen_dir/$base_path-shared.h",
- ]
- }
-
- # Workaround for https://github.com/ninja-build/ninja/issues/1966.
- rsp_file = "$target_gen_dir/${target_name}.rsp"
- write_file(rsp_file, filelist)
- inputs += [ rsp_file ]
-
- args += [
- "--filelist=" + rebase_path(rsp_file, root_build_dir),
- "--generate_non_variant_code",
- "-g",
- "c++",
- ]
-
- if (defined(shared_component_export_macro)) {
- args += [
- "--export_attribute",
- shared_component_export_macro,
- "--export_header",
- "base/component_export.h",
- ]
- }
-
- # Enable adding annotations to generated C++ headers that are used for
- # cross-references in CodeSearch.
- if (enable_kythe_annotations) {
- args += [ "--enable_kythe_annotations" ]
- }
- }
- } else {
- group(generator_cpp_message_ids_target_name) {
- }
- }
-
- shared_cpp_sources_target_name = "${target_name}_shared_cpp_sources"
- source_set(shared_cpp_sources_target_name) {
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- configs += [ "//build/config/compiler:wexit_time_destructors" ]
- deps = []
- public_deps = []
- if (output_file_base_paths != []) {
- sources = []
- foreach(base_path, output_file_base_paths) {
- sources += [
- "$root_gen_dir/$base_path-features.h",
- "$root_gen_dir/$base_path-params-data.h",
- "$root_gen_dir/$base_path-shared-internal.h",
- "$root_gen_dir/$base_path-shared.cc",
- "$root_gen_dir/$base_path-shared.h",
- ]
- }
- public_deps += [ ":$generator_shared_target_name" ]
- }
- if (require_full_cpp_deps) {
- public_deps += [ "//mojo/public/cpp/bindings" ]
- } else {
- public_deps += [ "//mojo/public/cpp/bindings:bindings_base" ]
- }
- foreach(d, all_deps) {
- # Resolve the name, so that a target //mojo/something becomes
- # //mojo/something:something and we can append shared_cpp_sources_suffix
- # to get the cpp dependency name.
- full_name = get_label_info("$d", "label_no_toolchain")
- public_deps += [ "${full_name}_shared" ]
- }
- if (defined(shared_component_impl_macro)) {
- defines = [ shared_component_impl_macro ]
- }
- }
-
- shared_cpp_library_target_name = "${target_name}_shared"
- if (defined(shared_component_output_name)) {
- component(shared_cpp_library_target_name) {
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- output_name = "$shared_component_output_name"
- public_deps = [ ":$shared_cpp_sources_target_name" ]
- }
- } else {
- group(shared_cpp_library_target_name) {
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- public_deps = [ ":$shared_cpp_sources_target_name" ]
- }
- }
-
- if (generate_mojolpm_fuzzing) {
- # This block generates the proto files used for the MojoLPM fuzzer,
- # and the corresponding proto targets that will be linked in the fuzzer
- # targets. These are independent of the typemappings, and can be done
- # separately here.
-
- generator_mojolpm_proto_target_name =
- "${target_name}_mojolpm_proto_generator"
-
- action(generator_mojolpm_proto_target_name) {
- allow_remote = true
- script = mojom_generator_script
- inputs = mojom_generator_sources + jinja2_sources
- sources =
- invoker.sources + [
- "$root_gen_dir/mojo/public/tools/bindings/cpp_templates.zip",
- "$root_gen_dir/mojo/public/tools/bindings/mojolpm_templates.zip",
- ]
- deps = [
- ":$parser_target_name",
- "//mojo/public/tools/bindings:precompile_templates",
- ]
-
- outputs = []
- args = common_generator_args
- filelist = []
-
- # Split the input into generated and non-generated source files. They
- # need to be processed separately.
- gen_dir_path_wildcard = get_path_info("//", "gen_dir") + "/*"
- non_gen_sources =
- filter_exclude(invoker.sources, [ gen_dir_path_wildcard ])
- gen_sources = filter_include(invoker.sources, [ gen_dir_path_wildcard ])
-
- foreach(source, non_gen_sources) {
- filelist += [ rebase_path(source, root_build_dir) ]
- inputs += [ "$target_gen_dir/$source-module" ]
- outputs += [ "$target_gen_dir/$source.mojolpm.proto" ]
- }
-
- foreach(source, gen_sources) {
- filelist += [ rebase_path(source, root_build_dir) ]
-
- # For generated files, we assume they're in the target_gen_dir or a
- # sub-folder of it. Rebase the path so we can get the relative location.
- source_file = rebase_path(source, target_gen_dir)
- inputs += [ "$target_gen_dir/$source_file-module" ]
- outputs += [ "$target_gen_dir/$source_file.mojolpm.proto" ]
- }
-
- # Workaround for https://github.com/ninja-build/ninja/issues/1966.
- rsp_file = "$target_gen_dir/${target_name}.rsp"
- write_file(rsp_file, filelist)
- inputs += [ rsp_file ]
-
- args += [
- "--filelist=" + rebase_path(rsp_file, root_build_dir),
- "--generate_non_variant_code",
- "-g",
- "mojolpm",
- ]
- }
-
- mojolpm_proto_target_name = "${target_name}_mojolpm_proto"
- if (defined(invoker.sources)) {
- proto_library(mojolpm_proto_target_name) {
- testonly = true
- generate_python = false
-
- # Split the input into generated and non-generated source files. They
- # need to be processed separately.
- gen_dir_path_wildcard = get_path_info("//", "gen_dir") + "/*"
- non_gen_sources =
- filter_exclude(invoker.sources, [ gen_dir_path_wildcard ])
- gen_sources = filter_include(invoker.sources, [ gen_dir_path_wildcard ])
- sources = process_file_template(
- non_gen_sources,
- [ "{{source_gen_dir}}/{{source_file_part}}.mojolpm.proto" ])
- sources += process_file_template(
- gen_sources,
- [ "{{source_dir}}/{{source_file_part}}.mojolpm.proto" ])
-
- import_dirs = [ "//" ]
- proto_in_dir = "${root_gen_dir}"
- proto_out_dir = "."
- proto_deps = [ ":$generator_mojolpm_proto_target_name" ]
- link_deps = [ "//mojo/public/tools/fuzzers:mojolpm_proto" ]
-
- foreach(d, all_deps) {
- # Resolve the name, so that a target //mojo/something becomes
- # //mojo/something:something and we can append mojolpm_proto_suffix
- # to get the proto dependency name.
- full_name = get_label_info("$d", "label_no_toolchain")
- proto_deps += [ "${full_name}_mojolpm_proto" ]
- link_deps += [ "${full_name}_mojolpm_proto" ]
- }
- }
- } else {
- group(mojolpm_proto_target_name) {
- testonly = true
- public_deps = [ "//mojo/public/tools/fuzzers:mojolpm_proto" ]
- if (defined(generator_shared_target_name)) {
- public_deps += [ ":$generator_shared_target_name" ]
- }
- foreach(d, all_deps) {
- # Resolve the name, so that a target //mojo/something becomes
- # //mojo/something:something and we can append #mojolpm_proto_suffix
- # to get the proto dependency name.
- full_name = get_label_info("$d", "label_no_toolchain")
- public_deps += [ "${full_name}_mojolpm_proto" ]
- }
- }
- }
- }
-
- # Generate code for variants.
- default_variant = {
- component_macro_suffix = ""
- }
- if ((!defined(invoker.disable_variants) || !invoker.disable_variants) &&
- use_blink) {
- blink_variant = {
- variant = "blink"
- component_macro_suffix = "_BLINK"
- for_blink = true
- }
- enabled_configurations = [
- default_variant,
- blink_variant,
- ]
- } else {
- enabled_configurations = [ default_variant ]
- }
- foreach(bindings_configuration, enabled_configurations) {
- cpp_only = false
- if (defined(invoker.cpp_only)) {
- cpp_only = invoker.cpp_only
- }
- variant_suffix = ""
- if (defined(bindings_configuration.variant)) {
- variant = bindings_configuration.variant
- variant_suffix = "_${variant}"
- cpp_only = true
- }
-
- cpp_typemap_configs = []
- export_defines = []
- export_defines_overridden = false
- force_source_set = false
- proxy_target = ""
- extra_configs = []
- output_visibility = []
- output_visibility = [ "*" ]
- cpp_source_deps = []
- if (defined(bindings_configuration.for_blink) &&
- bindings_configuration.for_blink) {
- if (defined(invoker.blink_cpp_typemaps)) {
- cpp_typemap_configs = invoker.blink_cpp_typemaps
- }
- if (defined(invoker.export_define_blink)) {
- export_defines_overridden = true
- export_defines = [ invoker.export_define_blink ]
- force_source_set = true
- }
- if (defined(invoker.blink_cpp_configs)) {
- extra_configs += invoker.blink_cpp_configs
- }
- if (defined(invoker.blink_cpp_proxy_target)) {
- proxy_target = invoker.blink_cpp_proxy_target
- }
- if (defined(invoker.visibility_blink)) {
- output_visibility = []
- output_visibility = invoker.visibility_blink
- }
- if (defined(invoker.mojom_blink_source_deps)) {
- cpp_source_deps = invoker.mojom_blink_source_deps
- }
- } else {
- if (defined(invoker.cpp_typemaps)) {
- cpp_typemap_configs = invoker.cpp_typemaps
- }
- if (defined(invoker.export_define)) {
- export_defines_overridden = true
- export_defines = [ invoker.export_define ]
- force_source_set = true
- }
- if (defined(invoker.cpp_configs)) {
- extra_configs += invoker.cpp_configs
- }
- if (defined(invoker.cpp_proxy_target)) {
- proxy_target = invoker.cpp_proxy_target
- }
- if (defined(invoker.visibility)) {
- output_visibility = []
- output_visibility = invoker.visibility
- }
- if (defined(invoker.mojom_source_deps)) {
- cpp_source_deps = invoker.mojom_source_deps
- }
- }
- not_needed([ "cpp_typemap_configs" ])
- if (proxy_target != "") {
- group("${target_name}${variant_suffix}__has_cpp_proxy") {
- }
- }
-
- if (!export_defines_overridden && defined(invoker.component_macro_prefix)) {
- output_name_override =
- "${invoker.component_output_prefix}${variant_suffix}"
- export_defines =
- [ "IS_${invoker.component_macro_prefix}" +
- "${bindings_configuration.component_macro_suffix}_IMPL" ]
- }
-
- generate_java = false
- if (!cpp_only && defined(invoker.generate_java)) {
- generate_java = invoker.generate_java
- }
- type_mappings_target_name = "${target_name}${variant_suffix}__type_mappings"
- type_mappings_path =
- "$target_gen_dir/${target_name}${variant_suffix}__type_mappings"
- if (sources_list != []) {
- export_args = []
- export_args_overridden = false
- if (defined(bindings_configuration.for_blink) &&
- bindings_configuration.for_blink) {
- if (defined(invoker.export_class_attribute_blink)) {
- export_args_overridden = true
- export_args += [
- "--export_attribute",
- invoker.export_class_attribute_blink,
- "--export_header",
- invoker.export_header_blink,
- ]
- }
- } else if (defined(invoker.export_class_attribute)) {
- export_args_overridden = true
- export_args += [
- "--export_attribute",
- invoker.export_class_attribute,
- "--export_header",
- invoker.export_header,
- ]
- }
- if (!export_args_overridden && defined(invoker.component_macro_prefix)) {
- export_args += [
- "--export_attribute",
- "COMPONENT_EXPORT(${invoker.component_macro_prefix}" +
- "${bindings_configuration.component_macro_suffix})",
- "--export_header",
- "base/component_export.h",
- ]
- }
-
- generator_cpp_output_suffixes = []
- variant_dash_suffix = ""
- if (defined(variant)) {
- variant_dash_suffix = "-${variant}"
- }
- generator_cpp_output_suffixes += [
- "${variant_dash_suffix}-forward.h",
- "${variant_dash_suffix}-import-headers.h",
- "${variant_dash_suffix}-test-utils.h",
- "${variant_dash_suffix}.cc",
- "${variant_dash_suffix}.h",
- ]
-
- generator_target_name = "${target_name}${variant_suffix}__generator"
-
- # TODO(crbug.com/1194274): Investigate nondeterminism in Py3 builds.
- action(generator_target_name) {
- allow_remote = true
- visibility = [ ":*" ]
- script = mojom_generator_script
- inputs = mojom_generator_sources + jinja2_sources
- sources =
- sources_list + [
- "$root_gen_dir/mojo/public/tools/bindings/cpp_templates.zip",
- type_mappings_path,
- ]
- if (generate_mojolpm_fuzzing &&
- !defined(bindings_configuration.variant)) {
- sources += [
- "$root_gen_dir/mojo/public/tools/bindings/mojolpm_templates.zip",
- ]
- }
- deps = [
- ":$parser_target_name",
- ":$type_mappings_target_name",
- "//mojo/public/tools/bindings:precompile_templates",
- ]
-
- if (defined(invoker.parser_deps)) {
- deps += invoker.parser_deps
- }
- outputs = []
- args = common_generator_args + export_args
- filelist = []
- foreach(source, sources_list) {
- filelist += [ rebase_path(source, root_build_dir) ]
- }
- foreach(base_path, output_file_base_paths) {
- filename = get_path_info(base_path, "file")
- dirname = get_path_info(base_path, "dir")
- inputs += [ "$root_gen_dir/$dirname/${filename}-module" ]
-
- outputs += [
- "$root_gen_dir/${base_path}${variant_dash_suffix}-forward.h",
- "$root_gen_dir/${base_path}${variant_dash_suffix}-import-headers.h",
- "$root_gen_dir/${base_path}${variant_dash_suffix}-test-utils.h",
- "$root_gen_dir/${base_path}${variant_dash_suffix}.cc",
- "$root_gen_dir/${base_path}${variant_dash_suffix}.h",
- ]
- if (generate_mojolpm_fuzzing &&
- !defined(bindings_configuration.variant)) {
- outputs += [
- "$root_gen_dir/${base_path}${variant_dash_suffix}-mojolpm.cc",
- "$root_gen_dir/${base_path}${variant_dash_suffix}-mojolpm.h",
- ]
- }
- }
-
- # Workaround for https://github.com/ninja-build/ninja/issues/1966.
- rsp_file = "$target_gen_dir/${target_name}.rsp"
- write_file(rsp_file, filelist)
- inputs += [ rsp_file ]
- args += [
- "--filelist=" + rebase_path("$rsp_file", root_build_dir),
- "-g",
- ]
-
- if (generate_mojolpm_fuzzing &&
- !defined(bindings_configuration.variant)) {
- args += [ "c++,mojolpm" ]
- } else {
- args += [ "c++" ]
- }
-
- if (defined(bindings_configuration.variant)) {
- args += [
- "--variant",
- bindings_configuration.variant,
- ]
- }
-
- args += [
- "--typemap",
- rebase_path(type_mappings_path, root_build_dir),
- ]
-
- if (defined(bindings_configuration.for_blink) &&
- bindings_configuration.for_blink) {
- args += [ "--for_blink" ]
- }
-
- if (defined(invoker.support_lazy_serialization) &&
- invoker.support_lazy_serialization) {
- args += [ "--support_lazy_serialization" ]
- }
-
- if (enable_kythe_annotations) {
- args += [ "--enable_kythe_annotations" ]
- }
-
- if (!defined(invoker.scramble_message_ids) ||
- invoker.scramble_message_ids) {
- inputs += message_scrambling_inputs
- args += message_scrambling_args
- }
-
- if (defined(invoker.extra_cpp_template_paths)) {
- foreach(extra_cpp_template, invoker.extra_cpp_template_paths) {
- args += [
- "--extra_cpp_template_paths",
- rebase_path(extra_cpp_template, root_build_dir),
- ]
- inputs += [ extra_cpp_template ]
-
- assert(
- get_path_info(extra_cpp_template, "extension") == "tmpl",
- "--extra_cpp_template_paths only accepts template files ending in extension .tmpl")
- foreach(base_path, output_file_base_paths) {
- template_file_name = get_path_info("$extra_cpp_template", "name")
- outputs += [ "$root_gen_dir/${base_path}${variant_dash_suffix}-${template_file_name}" ]
- }
- }
- }
- }
- }
-
- # Write the typemapping configuration for this target out to a file to be
- # validated by a Python script. This helps catch mistakes that can't
- # be caught by logic in GN.
- _typemap_config_filename =
- "$target_gen_dir/${target_name}${variant_suffix}.typemap_config"
- _typemap_stamp_filename = "${_typemap_config_filename}.validated"
- _typemap_validator_target_name = "${type_mappings_target_name}__validator"
- _rebased_typemap_configs = []
- foreach(config, cpp_typemap_configs) {
- _rebased_config = {
- }
- _rebased_config = config
- if (defined(config.traits_headers)) {
- _rebased_config.traits_headers = []
- _rebased_config.traits_headers =
- rebase_path(config.traits_headers, "//")
- }
- if (defined(config.traits_private_headers)) {
- _rebased_config.traits_private_headers = []
- _rebased_config.traits_private_headers =
- rebase_path(config.traits_private_headers, "//")
- }
- _rebased_typemap_configs += [ _rebased_config ]
- }
- write_file(_typemap_config_filename, _rebased_typemap_configs, "json")
- _mojom_target_name = target_name
-
- action(_typemap_validator_target_name) {
- allow_remote = true
- script = "$mojom_generator_root/validate_typemap_config.py"
- inputs = [ _typemap_config_filename ]
- outputs = [ _typemap_stamp_filename ]
- args = [
- get_label_info(_mojom_target_name, "label_no_toolchain"),
- rebase_path(_typemap_config_filename, root_build_dir),
- rebase_path(_typemap_stamp_filename, root_build_dir),
- ]
- }
-
- action(type_mappings_target_name) {
- allow_remote = true
- inputs =
- mojom_generator_sources + jinja2_sources + [ _typemap_stamp_filename ]
- outputs = [ type_mappings_path ]
- script = "$mojom_generator_root/generate_type_mappings.py"
- deps = [ ":$_typemap_validator_target_name" ]
- args = [
- "--output",
- rebase_path(type_mappings_path, root_build_dir),
- ]
-
- sources = []
- foreach(d, all_deps) {
- name = get_label_info(d, "label_no_toolchain")
- toolchain = get_label_info(d, "toolchain")
- dependency_output = "${name}${variant_suffix}__type_mappings"
- dependency_target = "${dependency_output}(${toolchain})"
- deps += [ dependency_target ]
- dependency_output_dir =
- get_label_info(dependency_output, "target_gen_dir")
- dependency_name = get_label_info(dependency_output, "name")
- dependency_path = "$dependency_output_dir/${dependency_name}"
- sources += [ dependency_path ]
- args += [
- "--dependency",
- rebase_path(dependency_path, root_build_dir),
- ]
- }
-
- # Newer GN-based typemaps are aggregated into a single config.
- inputs += [ _typemap_config_filename ]
- args += [
- "--cpp-typemap-config",
- rebase_path(_typemap_config_filename, root_build_dir),
- ]
- }
-
- group("${target_name}${variant_suffix}_headers") {
- public_deps = []
- if (sources_list != []) {
- public_deps += [
- ":$generator_cpp_message_ids_target_name",
- ":$generator_shared_target_name",
- ":$generator_target_name",
- ]
- }
- foreach(d, all_deps) {
- full_name = get_label_info("$d", "label_no_toolchain")
- public_deps += [ "${full_name}${variant_suffix}_headers" ]
- }
- if (defined(bindings_configuration.for_blink) &&
- bindings_configuration.for_blink) {
- public_deps += [ "//mojo/public/cpp/bindings:wtf_support" ]
- }
- }
-
- js_data_deps_target_name = target_name + "_js_data_deps"
- not_needed([ "js_data_deps_target_name" ])
-
- if (!force_source_set && defined(invoker.component_macro_prefix)) {
- sources_target_type = "component"
- } else {
- sources_target_type = "source_set"
- }
-
- output_target_name = "${target_name}${variant_suffix}"
- if (proxy_target != "") {
- group(output_target_name) {
- public_deps = [ proxy_target ]
- visibility = output_visibility
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- }
- sources_target_name = "${output_target_name}_cpp_sources"
- } else {
- sources_target_name = output_target_name
- }
-
- target(sources_target_type, sources_target_name) {
- if (defined(output_name_override)) {
- output_name = output_name_override
- }
- visibility = output_visibility + [
- ":$output_target_name",
- ":${target_name}_mojolpm",
- ]
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- defines = export_defines
- configs += [ "//build/config/compiler:wexit_time_destructors" ]
- configs += extra_configs
- if (output_file_base_paths != []) {
- sources = []
- foreach(base_path, output_file_base_paths) {
- foreach(suffix, generator_cpp_output_suffixes) {
- sources += [ "$root_gen_dir/${base_path}$suffix" ]
- }
- }
- }
- deps = [
- ":$generator_cpp_message_ids_target_name",
- "//mojo/public/cpp/bindings:struct_traits",
- "//mojo/public/interfaces/bindings:bindings_headers",
- ]
- public_deps = [
- ":$shared_cpp_library_target_name",
- "//base",
- ]
- if (require_full_cpp_deps) {
- public_deps += [ "//mojo/public/cpp/bindings" ]
- } else {
- public_deps += [ "//mojo/public/cpp/bindings:bindings_base" ]
- }
-
- if (sources_list != []) {
- public_deps += [ ":$generator_target_name" ]
- }
- foreach(d, mojom_cpp_deps) {
- # Resolve the name, so that a target //mojo/something becomes
- # //mojo/something:something and we can append variant_suffix to
- # get the cpp dependency name.
- full_name = get_label_info(d, "label_no_toolchain")
- public_deps += [ "${full_name}${variant_suffix}" ]
- }
- foreach(d, cpp_source_deps) {
- full_name = get_label_info(d, "label_no_toolchain")
- public_deps += [
- "${full_name}${variant_suffix}__has_cpp_proxy",
- "${full_name}${variant_suffix}_cpp_sources",
- ]
- }
- if (defined(bindings_configuration.for_blink) &&
- bindings_configuration.for_blink) {
- if (defined(invoker.overridden_deps_blink)) {
- foreach(d, invoker.overridden_deps_blink) {
- # Resolve the name, so that a target //mojo/something becomes
- # //mojo/something:something and we can append variant_suffix
- # to get the cpp dependency name.
- full_name = get_label_info("$d", "label_no_toolchain")
- public_deps -= [ "${full_name}${variant_suffix}" ]
- }
- public_deps += invoker.component_deps_blink
- }
- if (defined(invoker.check_includes_blink)) {
- check_includes = invoker.check_includes_blink
- }
- } else {
- if (defined(invoker.check_includes_blink)) {
- not_needed(invoker, [ "check_includes_blink" ])
- }
- if (defined(invoker.overridden_deps)) {
- foreach(d, invoker.overridden_deps) {
- # Resolve the name, so that a target //mojo/something becomes
- # //mojo/something:something and we can append variant_suffix
- # to get the cpp dependency name.
- full_name = get_label_info("$d", "label_no_toolchain")
- public_deps -= [ "${full_name}${variant_suffix}" ]
- }
- public_deps += invoker.component_deps
- }
- }
- foreach(config, cpp_typemap_configs) {
- if (defined(config.traits_sources)) {
- sources += config.traits_sources
- }
- if (defined(config.traits_deps)) {
- deps += config.traits_deps
- }
- if (defined(config.traits_public_deps)) {
- public_deps += config.traits_public_deps
- }
- }
- if (defined(bindings_configuration.for_blink) &&
- bindings_configuration.for_blink) {
- public_deps += [ "//mojo/public/cpp/bindings:wtf_support" ]
- }
- }
-
- if (generate_mojolpm_fuzzing && !defined(variant)) {
- # This block contains the C++ targets for the MojoLPM fuzzer, we need to
- # do this here so that we can use the typemap configuration for the
- # empty-variant Mojo target.
-
- mojolpm_target_name = "${target_name}_mojolpm"
- mojolpm_generator_target_name = "${target_name}__generator"
- source_set(mojolpm_target_name) {
- # There are still a few missing header dependencies between mojo targets
- # with typemaps and the dependencies of their typemap headers. It would
- # be good to enable include checking for these in the future though.
- check_includes = false
- testonly = true
- if (defined(invoker.sources)) {
- # Split the input into generated and non-generated source files. They
- # need to be processed separately.
- gen_dir_path_wildcard = get_path_info("//", "gen_dir") + "/*"
- non_gen_sources =
- filter_exclude(invoker.sources, [ gen_dir_path_wildcard ])
- gen_sources =
- filter_include(invoker.sources, [ gen_dir_path_wildcard ])
- sources = process_file_template(
- non_gen_sources,
- [
- "{{source_gen_dir}}/{{source_file_part}}-mojolpm.cc",
- "{{source_gen_dir}}/{{source_file_part}}-mojolpm.h",
- ])
- sources += process_file_template(
- gen_sources,
- [
- "{{source_dir}}/{{source_file_part}}-mojolpm.cc",
- "{{source_dir}}/{{source_file_part}}-mojolpm.h",
- ])
- deps = [ ":$output_target_name" ]
- } else {
- sources = []
- deps = []
- }
-
- public_deps = [
- ":$generator_shared_target_name",
-
- # NB: hardcoded dependency on the no-variant variant generator, since
- # mojolpm only uses the no-variant type.
- ":$mojolpm_generator_target_name",
- ":$mojolpm_proto_target_name",
- "//base",
- "//mojo/public/tools/fuzzers:mojolpm",
- ]
-
- foreach(d, all_deps) {
- # Resolve the name, so that a target //mojo/something becomes
- # //mojo/something:something and we can append variant_suffix to
- # get the cpp dependency name.
- full_name = get_label_info("$d", "label_no_toolchain")
- public_deps += [ "${full_name}_mojolpm" ]
- }
-
- foreach(config, cpp_typemap_configs) {
- if (defined(config.traits_deps)) {
- deps += config.traits_deps
- }
- if (defined(config.traits_public_deps)) {
- public_deps += config.traits_public_deps
- }
- }
- }
- }
-
- if (generate_java && is_android) {
- import("//build/config/android/rules.gni")
-
- java_generator_target_name = target_name + "_java__generator"
- if (sources_list != []) {
- action(java_generator_target_name) {
- script = mojom_generator_script
- inputs = mojom_generator_sources + jinja2_sources
- sources = sources_list
- deps = [
- ":$parser_target_name",
- ":$type_mappings_target_name",
- "//mojo/public/tools/bindings:precompile_templates",
- ]
- outputs = []
- args = common_generator_args
- filelist = []
- foreach(source, sources_list) {
- filelist += [ rebase_path(source, root_build_dir) ]
- }
- foreach(base_path, output_file_base_paths) {
- outputs += [ "$root_gen_dir/$base_path.srcjar" ]
- }
-
- response_file_contents = filelist
-
- args += [
- "--filelist={{response_file_name}}",
- "-g",
- "java",
- ]
-
- if (!defined(invoker.scramble_message_ids) ||
- invoker.scramble_message_ids) {
- inputs += message_scrambling_inputs
- args += message_scrambling_args
- }
- }
- } else {
- group(java_generator_target_name) {
- }
- }
-
- java_srcjar_target_name = target_name + "_java_sources"
-
- action(java_srcjar_target_name) {
- script = "//build/android/gyp/zip.py"
- inputs = []
- if (output_file_base_paths != []) {
- foreach(base_path, output_file_base_paths) {
- inputs += [ "$root_gen_dir/${base_path}.srcjar" ]
- }
- }
- output = "$target_gen_dir/$target_name.srcjar"
- outputs = [ output ]
- rebase_inputs = rebase_path(inputs, root_build_dir)
- rebase_output = rebase_path(output, root_build_dir)
- args = [
- "--input-zips=$rebase_inputs",
- "--output=$rebase_output",
- ]
- deps = []
- if (sources_list != []) {
- deps = [ ":$java_generator_target_name" ]
- }
- }
-
- java_target_name = target_name + "_java"
- android_library(java_target_name) {
- forward_variables_from(invoker, [ "enable_bytecode_checks" ])
- deps = [
- "//mojo/public/java:bindings_java",
- "//mojo/public/java:system_java",
- "//third_party/androidx:androidx_annotation_annotation_java",
- ]
-
- # Disable warnings/checks on these generated files.
- chromium_code = false
-
- foreach(d, all_deps) {
- # Resolve the name, so that a target //mojo/something becomes
- # //mojo/something:something and we can append "_java" to get the java
- # dependency name.
- full_name = get_label_info(d, "label_no_toolchain")
- deps += [ "${full_name}_java" ]
- }
-
- srcjar_deps = [ ":$java_srcjar_target_name" ]
- }
- }
- }
-
- if (defined(invoker.generate_webui_js_bindings)) {
- assert(is_chromeos_ash,
- "generate_webui_js_bindings can only be used on ChromeOS Ash")
- assert(invoker.generate_webui_js_bindings,
- "generate_webui_js_bindings should be set to true or removed")
- }
-
- use_typescript_for_target = defined(invoker.webui_module_path) &&
- !defined(invoker.generate_webui_js_bindings)
-
- generate_legacy_js = !use_typescript_for_target ||
- (defined(invoker.generate_legacy_js_bindings) &&
- invoker.generate_legacy_js_bindings)
-
- if (!use_typescript_for_target &&
- defined(invoker.generate_legacy_js_bindings)) {
- not_needed(invoker, [ "generate_legacy_js_bindings" ])
- }
-
- # Targets needed by both TS and JS bindings targets. These are needed
- # unconditionally for JS bindings targets, and are needed for TS bindings
- # targets when generate_legacy_js_bindings is true. This option is provided
- # since the legacy bindings are needed by Blink tests and non-Chromium users,
- # which are not expected to migrate to modules or TypeScript.
- if (generate_legacy_js && (generate_js_fuzzing ||
- !defined(invoker.cpp_only) || !invoker.cpp_only)) {
- if (sources_list != []) {
- generator_js_target_name = "${target_name}_js__generator"
-
- action(generator_js_target_name) {
- script = mojom_generator_script
- inputs = mojom_generator_sources + jinja2_sources
- sources = sources_list
- deps = [
- ":$parser_target_name",
- "//mojo/public/tools/bindings:precompile_templates",
- ]
- if (defined(invoker.parser_deps)) {
- deps += invoker.parser_deps
- }
- outputs = []
- args = common_generator_args
- filelist = []
- foreach(source, sources_list) {
- filelist += [ rebase_path(source, root_build_dir) ]
- }
- foreach(base_path, output_file_base_paths) {
- outputs += [
- "$root_gen_dir/$base_path.js",
- "$root_gen_dir/$base_path.m.js",
- "$root_gen_dir/$base_path-lite.js",
- "$root_gen_dir/$base_path-lite-for-compile.js",
- ]
-
- if (defined(invoker.webui_module_path) &&
- !use_typescript_for_target) {
- outputs += [ "$root_gen_dir/mojom-webui/$base_path-webui.js" ]
- }
- }
-
- response_file_contents = filelist
-
- args += [
- "--filelist={{response_file_name}}",
- "-g",
- "javascript",
- ]
-
- if (defined(invoker.js_generate_struct_deserializers) &&
- invoker.js_generate_struct_deserializers) {
- args += [ "--js_generate_struct_deserializers" ]
- }
-
- if (!defined(invoker.scramble_message_ids) ||
- invoker.scramble_message_ids) {
- inputs += message_scrambling_inputs
- args += message_scrambling_args
- }
-
- if (generate_js_fuzzing) {
- args += [ "--generate_fuzzing" ]
- }
- }
- }
-
- js_target_name = target_name + "_js"
- group(js_target_name) {
- public_deps = []
- if (sources_list != []) {
- public_deps += [ ":$generator_js_target_name" ]
- }
-
- foreach(d, all_deps) {
- full_name = get_label_info(d, "label_no_toolchain")
- public_deps += [ "${full_name}_js" ]
- }
- }
-
- group(js_data_deps_target_name) {
- deps = []
- if (sources_list != []) {
- data = []
- foreach(base_path, output_file_base_paths) {
- data += [
- "$root_gen_dir/${base_path}.js",
- "$root_gen_dir/${base_path}.m.js",
- "$root_gen_dir/${base_path}-lite.js",
- ]
- }
- deps += [ ":$generator_js_target_name" ]
- }
-
- if (defined(invoker.disallow_native_types) &&
- invoker.disallow_native_types) {
- data_deps = []
- } else {
- data_deps = [ "//mojo/public/js:bindings_module" ]
- }
- foreach(d, all_deps) {
- full_name = get_label_info(d, "label_no_toolchain")
- data_deps += [ "${full_name}_js_data_deps" ]
- }
- }
- }
-
- # js_library() closure compiler targets, primarily used on ChromeOS. Only
- # generate these targets if the mojom target is not C++ only and is not using
- # TypeScript.
- if (generate_mojom_closure_libraries &&
- (!defined(invoker.cpp_only) || !invoker.cpp_only) && generate_legacy_js) {
- js_library_for_compile_target_name = "${target_name}_js_library_for_compile"
- if (sources_list != []) {
- js_library(js_library_for_compile_target_name) {
- extra_public_deps = [ ":$generator_js_target_name" ]
- sources = []
- foreach(base_path, output_file_base_paths) {
- sources += [ "$root_gen_dir/${base_path}-lite-for-compile.js" ]
- }
- externs_list = [
- "${externs_path}/mojo_core.js",
- "${externs_path}/pending.js",
- ]
- deps = []
- if (!defined(invoker.disallow_native_types)) {
- deps += [ "//mojo/public/js:bindings_lite_sources" ]
- }
- foreach(d, all_deps) {
- full_name = get_label_info(d, "label_no_toolchain")
- deps += [ "${full_name}_js_library_for_compile" ]
- }
- }
- } else {
- group(js_library_for_compile_target_name) {
- }
- }
-
- # WebUI specific closure targets, not needed by targets that are generating
- # TypeScript WebUI bindings or by legacy-only targets.
- if (defined(invoker.webui_module_path) && !use_typescript_for_target) {
- webui_js_target_name = "${target_name}_webui_js"
- if (sources_list != []) {
- js_library(webui_js_target_name) {
- extra_public_deps = [ ":$generator_js_target_name" ]
- sources = []
- foreach(base_path, output_file_base_paths) {
- sources += [ "$root_gen_dir/mojom-webui/${base_path}-webui.js" ]
- }
- externs_list = [
- "${externs_path}/mojo_core.js",
- "${externs_path}/pending.js",
- ]
- if (defined(invoker.disallow_native_types) &&
- invoker.disallow_native_types) {
- deps = []
- } else {
- deps = [ "//mojo/public/js:bindings_uncompiled" ]
- }
- foreach(d, all_deps) {
- full_name = get_label_info(d, "label_no_toolchain")
- deps += [ "${full_name}_webui_js" ]
- }
- }
- } else {
- group(webui_js_target_name) {
- }
- }
-
- webui_grdp_target_name = "${target_name}_webui_grdp"
- out_grd = "$target_gen_dir/${target_name}_webui_resources.grdp"
- grd_prefix = "${target_name}_webui"
- generate_grd(webui_grdp_target_name) {
- grd_prefix = grd_prefix
- out_grd = out_grd
-
- deps = [ ":$webui_js_target_name" ]
-
- input_files = []
- foreach(base_path, output_file_base_paths) {
- input_files += [ "${base_path}-webui.js" ]
- }
-
- input_files_base_dir =
- rebase_path("$root_gen_dir/mojom-webui", "$root_build_dir")
- }
- }
- }
- if ((generate_js_fuzzing || !defined(invoker.cpp_only) ||
- !invoker.cpp_only) && use_typescript_for_target) {
- if (sources_list != []) {
- source_filelist = []
- foreach(source, sources_list) {
- source_filelist += [ rebase_path(source, root_build_dir) ]
- }
-
- # Generate Typescript bindings.
- generator_ts_target_name = "${target_name}_ts__generator"
-
- action(generator_ts_target_name) {
- script = mojom_generator_script
- inputs = mojom_generator_sources + jinja2_sources
- sources = sources_list
- deps = [
- ":$parser_target_name",
- "//mojo/public/tools/bindings:precompile_templates",
- ]
-
- outputs = []
- foreach(base_path, output_file_base_paths) {
- outputs += [ "$root_gen_dir/$base_path-webui.ts" ]
- }
- args = common_generator_args
- response_file_contents = source_filelist
-
- args += [
- "--filelist={{response_file_name}}",
- "-g",
- "typescript",
- ]
-
- if (!defined(invoker.scramble_message_ids) ||
- invoker.scramble_message_ids) {
- inputs += message_scrambling_inputs
- args += message_scrambling_args
- }
-
- if (defined(invoker.js_generate_struct_deserializers) &&
- invoker.js_generate_struct_deserializers) {
- args += [ "--js_generate_struct_deserializers" ]
- }
-
- # TODO(crbug.com/1007587): Support scramble_message_ids if above is
- # insufficient.
- # TODO(crbug.com/1007591): Support generate_fuzzing.
- }
- }
- }
-}
-
-# A helper for the mojom() template above when component libraries are desired
-# for generated C++ bindings units. Supports all the same arguments as mojom()
-# except for the optional |component_output_prefix| and |component_macro_prefix|
-# arguments. These are instead shortened to |output_prefix| and |macro_prefix|
-# and are *required*.
-template("mojom_component") {
- assert(defined(invoker.output_prefix) && defined(invoker.macro_prefix))
-
- mojom(target_name) {
- forward_variables_from(invoker,
- "*",
- [
- "output_prefix",
- "macro_prefix",
- ])
- component_output_prefix = invoker.output_prefix
- component_macro_prefix = invoker.macro_prefix
- }
-}
diff --git a/utils/ipc/mojo/public/tools/bindings/mojom_bindings_generator.py b/utils/ipc/mojo/public/tools/bindings/mojom_bindings_generator.py
deleted file mode 100755
index 8c641c2a..00000000
--- a/utils/ipc/mojo/public/tools/bindings/mojom_bindings_generator.py
+++ /dev/null
@@ -1,424 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""The frontend for the Mojo bindings system."""
-
-from __future__ import print_function
-
-import argparse
-
-import hashlib
-import importlib
-import json
-import os
-import pprint
-import re
-import struct
-import sys
-
-# Disable lint check for finding modules:
-# pylint: disable=F0401
-
-def _GetDirAbove(dirname):
- """Returns the directory "above" this file containing |dirname| (which must
- also be "above" this file)."""
- path = os.path.abspath(__file__)
- while True:
- path, tail = os.path.split(path)
- assert tail
- if tail == dirname:
- return path
-
-
-sys.path.insert(
- 0,
- os.path.join(
- os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "mojom"))
-
-from mojom.error import Error
-import mojom.fileutil as fileutil
-from mojom.generate.module import Module
-from mojom.generate import template_expander
-from mojom.generate import translate
-from mojom.generate.generator import WriteFile
-
-sys.path.append(
- os.path.join(_GetDirAbove("mojo"), "tools", "diagnosis"))
-import crbug_1001171
-
-
-_BUILTIN_GENERATORS = {
- "c++": "mojom_cpp_generator",
- "javascript": "mojom_js_generator",
- "java": "mojom_java_generator",
- "mojolpm": "mojom_mojolpm_generator",
- "typescript": "mojom_ts_generator",
-}
-
-_BUILTIN_CHECKS = {
- "attributes": "mojom_attributes_check",
- "definitions": "mojom_definitions_check",
- "features": "mojom_interface_feature_check",
- "restrictions": "mojom_restrictions_check",
-}
-
-
-def LoadGenerators(generators_string):
- if not generators_string:
- return {} # No generators.
-
- generators = {}
- for generator_name in [s.strip() for s in generators_string.split(",")]:
- language = generator_name.lower()
- if language not in _BUILTIN_GENERATORS:
- print("Unknown generator name %s" % generator_name)
- sys.exit(1)
- generator_module = importlib.import_module(
- "generators.%s" % _BUILTIN_GENERATORS[language])
- generators[language] = generator_module
- return generators
-
-
-def LoadChecks(checks_string):
- if not checks_string:
- return {} # No checks.
-
- checks = {}
- for check_name in [s.strip() for s in checks_string.split(",")]:
- check = check_name.lower()
- if check not in _BUILTIN_CHECKS:
- print("Unknown check name %s" % check_name)
- sys.exit(1)
- check_module = importlib.import_module("checks.%s" % _BUILTIN_CHECKS[check])
- checks[check] = check_module
- return checks
-
-
-def MakeImportStackMessage(imported_filename_stack):
- """Make a (human-readable) message listing a chain of imports. (Returned
- string begins with a newline (if nonempty) and does not end with one.)"""
- return ''.join(
- reversed(["\n %s was imported by %s" % (a, b) for (a, b) in \
- zip(imported_filename_stack[1:], imported_filename_stack)]))
-
-
-class RelativePath:
- """Represents a path relative to the source tree or generated output dir."""
-
- def __init__(self, path, source_root, output_dir):
- self.path = path
- if path.startswith(source_root):
- self.root = source_root
- elif path.startswith(output_dir):
- self.root = output_dir
- else:
- raise Exception("Invalid input path %s" % path)
-
- def relative_path(self):
- return os.path.relpath(
- os.path.abspath(self.path), os.path.abspath(self.root))
-
-
-def _GetModulePath(path, output_dir):
- return os.path.join(output_dir, path.relative_path() + '-module')
-
-
-def ScrambleMethodOrdinals(interfaces, salt):
- already_generated = set()
- for interface in interfaces:
- i = 0
- already_generated.clear()
- for method in interface.methods:
- if method.explicit_ordinal is not None:
- continue
- while True:
- i = i + 1
- if i == 1000000:
- raise Exception("Could not generate %d method ordinals for %s" %
- (len(interface.methods), interface.mojom_name))
- # Generate a scrambled method.ordinal value. The algorithm doesn't have
- # to be very strong, cryptographically. It just needs to be non-trivial
- # to guess the results without the secret salt, in order to make it
- # harder for a compromised process to send fake Mojo messages.
- sha256 = hashlib.sha256(salt)
- sha256.update(interface.mojom_name.encode('utf-8'))
- sha256.update(str(i).encode('utf-8'))
- # Take the first 4 bytes as a little-endian uint32.
- ordinal = struct.unpack('<L', sha256.digest()[:4])[0]
- # Trim to 31 bits, so it always fits into a Java (signed) int.
- ordinal = ordinal & 0x7fffffff
- if ordinal in already_generated:
- continue
- already_generated.add(ordinal)
- method.ordinal = ordinal
- method.ordinal_comment = (
- 'The %s value is based on sha256(salt + "%s%d").' %
- (ordinal, interface.mojom_name, i))
- break
-
-
-def ReadFileContents(filename):
- with open(filename, 'rb') as f:
- return f.read()
-
-
-class MojomProcessor:
- """Takes parsed mojom modules and generates language bindings from them.
-
- Attributes:
- _processed_files: {Dict[str, mojom.generate.module.Module]} Mapping from
- relative mojom filename paths to the module AST for that mojom file.
- """
- def __init__(self, should_generate):
- self._should_generate = should_generate
- self._processed_files = {}
- self._typemap = {}
-
- def LoadTypemaps(self, typemaps):
- # Support some very simple single-line comments in typemap JSON.
- comment_expr = r"^\s*//.*$"
- def no_comments(line):
- return not re.match(comment_expr, line)
- for filename in typemaps:
- with open(filename) as f:
- typemaps = json.loads("".join(filter(no_comments, f.readlines())))
- for language, typemap in typemaps.items():
- language_map = self._typemap.get(language, {})
- language_map.update(typemap)
- self._typemap[language] = language_map
- if 'c++' in self._typemap:
- self._typemap['mojolpm'] = self._typemap['c++']
-
- def _GenerateModule(self, args, remaining_args, check_modules,
- generator_modules, rel_filename, imported_filename_stack):
- # Return the already-generated module.
- if rel_filename.path in self._processed_files:
- return self._processed_files[rel_filename.path]
-
- if rel_filename.path in imported_filename_stack:
- print("%s: Error: Circular dependency" % rel_filename.path + \
- MakeImportStackMessage(imported_filename_stack + [rel_filename.path]))
- sys.exit(1)
-
- module_path = _GetModulePath(rel_filename, args.output_dir)
- with open(module_path, 'rb') as f:
- module = Module.Load(f)
-
- if args.scrambled_message_id_salt_paths:
- salt = b''.join(
- map(ReadFileContents, args.scrambled_message_id_salt_paths))
- ScrambleMethodOrdinals(module.interfaces, salt)
-
- if self._should_generate(rel_filename.path):
- # Run checks on module first.
- for check_module in check_modules.values():
- checker = check_module.Check(module)
- checker.CheckModule()
- # Then run generation.
- for language, generator_module in generator_modules.items():
- generator = generator_module.Generator(
- module, args.output_dir, typemap=self._typemap.get(language, {}),
- variant=args.variant, bytecode_path=args.bytecode_path,
- for_blink=args.for_blink,
- js_generate_struct_deserializers=\
- args.js_generate_struct_deserializers,
- export_attribute=args.export_attribute,
- export_header=args.export_header,
- generate_non_variant_code=args.generate_non_variant_code,
- support_lazy_serialization=args.support_lazy_serialization,
- disallow_native_types=args.disallow_native_types,
- disallow_interfaces=args.disallow_interfaces,
- generate_message_ids=args.generate_message_ids,
- generate_fuzzing=args.generate_fuzzing,
- enable_kythe_annotations=args.enable_kythe_annotations,
- extra_cpp_template_paths=args.extra_cpp_template_paths,
- generate_extra_cpp_only=args.generate_extra_cpp_only)
- filtered_args = []
- if hasattr(generator_module, 'GENERATOR_PREFIX'):
- prefix = '--' + generator_module.GENERATOR_PREFIX + '_'
- filtered_args = [arg for arg in remaining_args
- if arg.startswith(prefix)]
- generator.GenerateFiles(filtered_args)
-
- # Save result.
- self._processed_files[rel_filename.path] = module
- return module
-
-
-def _Generate(args, remaining_args):
- if args.variant == "none":
- args.variant = None
-
- for idx, import_dir in enumerate(args.import_directories):
- tokens = import_dir.split(":")
- if len(tokens) >= 2:
- args.import_directories[idx] = RelativePath(tokens[0], tokens[1],
- args.output_dir)
- else:
- args.import_directories[idx] = RelativePath(tokens[0], args.depth,
- args.output_dir)
- generator_modules = LoadGenerators(args.generators_string)
- check_modules = LoadChecks(args.checks_string)
-
- fileutil.EnsureDirectoryExists(args.output_dir)
-
- processor = MojomProcessor(lambda filename: filename in args.filename)
- processor.LoadTypemaps(set(args.typemaps))
-
- if args.filelist:
- with open(args.filelist) as f:
- args.filename.extend(f.read().split())
-
- for filename in args.filename:
- processor._GenerateModule(
- args, remaining_args, check_modules, generator_modules,
- RelativePath(filename, args.depth, args.output_dir), [])
-
- return 0
-
-
-def _Precompile(args, _):
- generator_modules = LoadGenerators(",".join(_BUILTIN_GENERATORS.keys()))
-
- template_expander.PrecompileTemplates(generator_modules, args.output_dir)
- return 0
-
-
-def main():
- parser = argparse.ArgumentParser(
- description="Generate bindings from mojom files.")
- parser.add_argument("--use_bundled_pylibs", action="store_true",
- help="use Python modules bundled in the SDK")
- parser.add_argument(
- "-o",
- "--output_dir",
- dest="output_dir",
- default=".",
- help="output directory for generated files")
-
- subparsers = parser.add_subparsers()
-
- generate_parser = subparsers.add_parser(
- "generate", description="Generate bindings from mojom files.")
- generate_parser.add_argument("filename", nargs="*",
- help="mojom input file")
- generate_parser.add_argument("--filelist", help="mojom input file list")
- generate_parser.add_argument("-d", "--depth", dest="depth", default=".",
- help="depth from source root")
- generate_parser.add_argument("-g",
- "--generators",
- dest="generators_string",
- metavar="GENERATORS",
- default="c++,javascript,java,mojolpm",
- help="comma-separated list of generators")
- generate_parser.add_argument("-c",
- "--checks",
- dest="checks_string",
- metavar="CHECKS",
- default=",".join(_BUILTIN_CHECKS.keys()),
- help="comma-separated list of checks")
- generate_parser.add_argument(
- "--gen_dir", dest="gen_directories", action="append", metavar="directory",
- default=[], help="add a directory to be searched for the syntax trees.")
- generate_parser.add_argument(
- "-I", dest="import_directories", action="append", metavar="directory",
- default=[],
- help="add a directory to be searched for import files. The depth from "
- "source root can be specified for each import by appending it after "
- "a colon")
- generate_parser.add_argument("--typemap", action="append", metavar="TYPEMAP",
- default=[], dest="typemaps",
- help="apply TYPEMAP to generated output")
- generate_parser.add_argument("--variant", dest="variant", default=None,
- help="output a named variant of the bindings")
- generate_parser.add_argument(
- "--bytecode_path", required=True, help=(
- "the path from which to load template bytecode; to generate template "
- "bytecode, run %s precompile BYTECODE_PATH" % os.path.basename(
- sys.argv[0])))
- generate_parser.add_argument("--for_blink", action="store_true",
- help="Use WTF types as generated types for mojo "
- "string/array/map.")
- generate_parser.add_argument(
- "--js_generate_struct_deserializers", action="store_true",
- help="Generate javascript deserialize methods for structs in "
- "mojom-lite.js file")
- generate_parser.add_argument(
- "--export_attribute", default="",
- help="Optional attribute to specify on class declaration to export it "
- "for the component build.")
- generate_parser.add_argument(
- "--export_header", default="",
- help="Optional header to include in the generated headers to support the "
- "component build.")
- generate_parser.add_argument(
- "--generate_non_variant_code", action="store_true",
- help="Generate code that is shared by different variants.")
- generate_parser.add_argument(
- "--scrambled_message_id_salt_path",
- dest="scrambled_message_id_salt_paths",
- help="If non-empty, the path to a file whose contents should be used as"
- "a salt for generating scrambled message IDs. If this switch is specified"
- "more than once, the contents of all salt files are concatenated to form"
- "the salt value.", default=[], action="append")
- generate_parser.add_argument(
- "--support_lazy_serialization",
- help="If set, generated bindings will serialize lazily when possible.",
- action="store_true")
- generate_parser.add_argument(
- "--extra_cpp_template_paths",
- dest="extra_cpp_template_paths",
- action="append",
- metavar="path_to_template",
- default=[],
- help="Provide a path to a new template (.tmpl) that is used to generate "
- "additional C++ source/header files ")
- generate_parser.add_argument(
- "--generate_extra_cpp_only",
- help="If set and extra_cpp_template_paths provided, will only generate"
- "extra_cpp_template related C++ bindings",
- action="store_true")
- generate_parser.add_argument(
- "--disallow_native_types",
- help="Disallows the [Native] attribute to be specified on structs or "
- "enums within the mojom file.", action="store_true")
- generate_parser.add_argument(
- "--disallow_interfaces",
- help="Disallows interface definitions within the mojom file. It is an "
- "error to specify this flag when processing a mojom file which defines "
- "any interface.", action="store_true")
- generate_parser.add_argument(
- "--generate_message_ids",
- help="Generates only the message IDs header for C++ bindings. Note that "
- "this flag only matters if --generate_non_variant_code is also "
- "specified.", action="store_true")
- generate_parser.add_argument(
- "--generate_fuzzing",
- action="store_true",
- help="Generates additional bindings for fuzzing in JS.")
- generate_parser.add_argument(
- "--enable_kythe_annotations",
- action="store_true",
- help="Adds annotations for kythe metadata generation.")
-
- generate_parser.set_defaults(func=_Generate)
-
- precompile_parser = subparsers.add_parser("precompile",
- description="Precompile templates for the mojom bindings generator.")
- precompile_parser.set_defaults(func=_Precompile)
-
- args, remaining_args = parser.parse_known_args()
- return args.func(args, remaining_args)
-
-
-if __name__ == "__main__":
- with crbug_1001171.DumpStateOnLookupError():
- ret = main()
- # Exit without running GC, which can save multiple seconds due to the large
- # number of object created. But flush is necessary as os._exit doesn't do
- # that.
- sys.stdout.flush()
- sys.stderr.flush()
- os._exit(ret)
diff --git a/utils/ipc/mojo/public/tools/bindings/mojom_bindings_generator_unittest.py b/utils/ipc/mojo/public/tools/bindings/mojom_bindings_generator_unittest.py
deleted file mode 100644
index 761922b6..00000000
--- a/utils/ipc/mojo/public/tools/bindings/mojom_bindings_generator_unittest.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright 2014 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from mojom_bindings_generator import MakeImportStackMessage
-from mojom_bindings_generator import ScrambleMethodOrdinals
-
-
-class FakeIface:
- def __init__(self):
- self.mojom_name = None
- self.methods = None
-
-
-class FakeMethod:
- def __init__(self, explicit_ordinal=None):
- self.explicit_ordinal = explicit_ordinal
- self.ordinal = explicit_ordinal
- self.ordinal_comment = None
-
-
-class MojoBindingsGeneratorTest(unittest.TestCase):
- """Tests mojo_bindings_generator."""
-
- def testMakeImportStackMessage(self):
- """Tests MakeImportStackMessage()."""
- self.assertEqual(MakeImportStackMessage(["x"]), "")
- self.assertEqual(MakeImportStackMessage(["x", "y"]),
- "\n y was imported by x")
- self.assertEqual(MakeImportStackMessage(["x", "y", "z"]),
- "\n z was imported by y\n y was imported by x")
-
- def testScrambleMethodOrdinals(self):
- """Tests ScrambleMethodOrdinals()."""
- interface = FakeIface()
- interface.mojom_name = 'RendererConfiguration'
- interface.methods = [
- FakeMethod(),
- FakeMethod(),
- FakeMethod(),
- FakeMethod(explicit_ordinal=42)
- ]
- ScrambleMethodOrdinals([interface], "foo".encode('utf-8'))
- # These next three values are hard-coded. If the generation algorithm
- # changes from being based on sha256(seed + interface.name + str(i)) then
- # these numbers will obviously need to change too.
- #
- # Note that hashlib.sha256('fooRendererConfiguration1').digest()[:4] is
- # '\xa5\xbc\xf9\xca' and that hex(1257880741) = '0x4af9bca5'. The
- # difference in 0x4a vs 0xca is because we only take 31 bits.
- self.assertEqual(interface.methods[0].ordinal, 1257880741)
- self.assertEqual(interface.methods[1].ordinal, 631133653)
- self.assertEqual(interface.methods[2].ordinal, 549336076)
-
- # Explicit method ordinals should not be scrambled.
- self.assertEqual(interface.methods[3].ordinal, 42)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/utils/ipc/mojo/public/tools/bindings/validate_typemap_config.py b/utils/ipc/mojo/public/tools/bindings/validate_typemap_config.py
deleted file mode 100755
index 6bb7a209..00000000
--- a/utils/ipc/mojo/public/tools/bindings/validate_typemap_config.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2020 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import json
-import os
-import re
-import sys
-
-
-def CheckCppTypemapConfigs(target_name, config_filename, out_filename):
- _SUPPORTED_CONFIG_KEYS = set([
- 'types', 'traits_headers', 'traits_private_headers', 'traits_sources',
- 'traits_deps', 'traits_public_deps'
- ])
- _SUPPORTED_TYPE_KEYS = set([
- 'mojom', 'cpp', 'copyable_pass_by_value', 'force_serialize', 'hashable',
- 'move_only', 'nullable_is_same_type', 'forward_declaration',
- 'default_constructible'
- ])
- with open(config_filename, 'r') as f:
- for config in json.load(f):
- for key in config.keys():
- if key not in _SUPPORTED_CONFIG_KEYS:
- raise ValueError('Invalid typemap property "%s" when processing %s' %
- (key, target_name))
-
- types = config.get('types')
- if not types:
- raise ValueError('Typemap for %s must specify at least one type to map'
- % target_name)
-
- for entry in types:
- for key in entry.keys():
- if key not in _SUPPORTED_TYPE_KEYS:
- raise IOError(
- 'Invalid type property "%s" in typemap for "%s" on target %s' %
- (key, entry.get('mojom', '(unknown)'), target_name))
-
- with open(out_filename, 'w') as f:
- f.truncate(0)
-
-
-def main():
- parser = argparse.ArgumentParser()
- _, args = parser.parse_known_args()
- if len(args) != 3:
- print('Usage: validate_typemap_config.py target_name config_filename '
- 'stamp_filename')
- sys.exit(1)
-
- CheckCppTypemapConfigs(args[0], args[1], args[2])
-
-
-if __name__ == '__main__':
- main()