| Index: mojo/public/tools/bindings/README.md
|
| diff --git a/mojo/public/tools/bindings/README.md b/mojo/public/tools/bindings/README.md
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..737c7e61df96ae8f618f4ce6e4d27bcb8970e140
|
| --- /dev/null
|
| +++ b/mojo/public/tools/bindings/README.md
|
| @@ -0,0 +1,749 @@
|
| +#  Mojom IDL and Bindings Generator
|
| +This document is a subset of the [Mojo documentation](/mojo).
|
| +
|
| +[TOC]
|
| +
|
| +## Overview
|
| +
|
| +Mojom is the IDL for Mojo bindings interfaces. Given a `.mojom` file, the
|
| +[bindings generator](https://cs.chromium.org/chromium/src/mojo/public/tools/bindings)
|
| +outputs bindings for all supported languages: **C++**, **JavaScript**, and
|
| +**Java**.
|
| +
|
| +For a trivial example consider the following hypothetical Mojom file we write to
|
| +`//services/widget/public/interfaces/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 may be included in a single Mojom file.
|
| +
|
| +If we add a corresponding GN target to
|
| +`//services/widget/public/interfaces/BUILD.gn`:
|
| +
|
| +```
|
| +import("mojo/public/tools/bindings/mojom.gni")
|
| +
|
| +mojom("interfaces") {
|
| + sources = [
|
| + "frobinator.mojom",
|
| + ]
|
| +}
|
| +```
|
| +
|
| +and then build this target:
|
| +
|
| +```
|
| +ninja -C out/r services/widget/public/interfaces
|
| +```
|
| +
|
| +we'll find several generated sources in our output directory:
|
| +
|
| +```
|
| +out/r/gen/services/widget/public/interfaces/frobinator.mojom.cc
|
| +out/r/gen/services/widget/public/interfaces/frobinator.mojom.h
|
| +out/r/gen/services/widget/public/interfaces/frobinator.mojom.js
|
| +out/r/gen/services/widget/public/interfaces/frobinator.mojom.srcjar
|
| +...
|
| +```
|
| +
|
| +Each of these generated source modules includes a set of definitions
|
| +representing the Mojom contents within the target language. 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 maping 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.
|
| +| *`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.
|
| +| *`InterfaceType&`* | An interface request 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.
|
| +| *`associated InterfaceType`* | An associated interface handle. See [Associated Interfaces](#Associated-Interfaces)
|
| +| *`associated InterfaceType&`* | An associated interface request. 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 aggregaging all defined symbols therein within a
|
| +common Mojom namespace. The specific impact this has on generated binidngs 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 preferrably 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/interfaces/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 {
|
| + YES,
|
| + NO
|
| +};
|
| +
|
| +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.YES;
|
| +
|
| + // 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;
|
| + SampleInterface? maybe_a_sample_interface_client_pipe;
|
| + SampleInterface& non_nullable_sample_interface_request;
|
| + SampleInterface&? nullable_sample_interface_request;
|
| + associated SampleInterface associated_interface_client;
|
| + associated SampleInterface& associated_interface_request;
|
| + assocaited SampleInterface&? maybe_another_associated_request;
|
| +};
|
| +```
|
| +
|
| +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).
|
| +
|
| +### Enumeration Types
|
| +
|
| +Enumeration types may be defined using the **enum** keyword either directly
|
| +within a module or within the namespace of some struct or interface:
|
| +
|
| +```
|
| +module business.mojom;
|
| +
|
| +enum Department {
|
| + SALES = 0,
|
| + DEV,
|
| +};
|
| +
|
| +struct Employee {
|
| + enum Type {
|
| + FULL_TIME,
|
| + PART_TIME,
|
| + };
|
| +
|
| + Type type;
|
| + // ...
|
| +};
|
| +```
|
| +
|
| +That that similar to C-style enums, individual values may be explicitly assigned
|
| +within an enum definition. By default values are based at zero and incremenet 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 within the namespace of some struct or interface:
|
| +
|
| +```
|
| +module business.mojom;
|
| +
|
| +const string kServiceName = "business";
|
| +
|
| +struct Employee {
|
| + const uint64 kInvalidId = 0;
|
| +
|
| + enum Type {
|
| + FULL_TIME,
|
| + PART_TIME,
|
| + };
|
| +
|
| + 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)
|
| +
|
| +### Interfaces
|
| +
|
| +An **interface** is a logical bundle of parameterized request messages. Each
|
| +request message may optionally define a parameterized response message. Here's
|
| +syntax 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#Synchronous-Calls) in the C++
|
| + bindings documentation. Note that sync calls are not currently supported in
|
| + other target languages.
|
| +
|
| +**`[Extensible]`**
|
| +: The `Extensible` attribute may be specified for any enum definition. 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.
|
| +
|
| +**`[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 [Using Legacy IPC Traits](/ipc#Using-Legacy-IPC-Traits) 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.
|
| +
|
| +## 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 langauge, please refer to the
|
| +bindings API documentation for that language:
|
| +
|
| +* [C++ Bindings](/mojo/public/cpp/bindings)
|
| +* [JavaScript Bindings](/mojo/public/js)
|
| +* [Java Bindings](/mojo/public/java/bindings)
|
| +
|
| +## 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 consitent 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#Connection-Errors),
|
| +[Java Connection Errors](/mojo/public/java/bindings#Connection-Errors), or
|
| +[JavaScript Connection Errors](/mojo/public/js#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 {
|
| + TRUE = 0,
|
| + FALSE = 1,
|
| + FILE_NOT_FOUND = 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#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, interface
|
| +and interface request 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.
|
| +
|
| +Currenly associated interfaces are only supported in generated C++ bindings.
|
| +See the documentation for
|
| +[C++ Associated Interfaces](/mojo/public/cpp/bindings#Associated-Interfaces).
|
| +
|
| +## Versioning
|
| +
|
| +### Overview
|
| +
|
| +*** note
|
| +**NOTE:** You don't need to worry about versioning if you don't care about
|
| +backwards compatibility. Specifically, all parts of Chrome are updated
|
| +atomically today and there is not yet any possibility of any two Chrome
|
| +processes communicating with two different versions of any given Mojom
|
| +interface.
|
| +***
|
| +
|
| +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 a birthday field. You can do:
|
| +
|
| +``` cpp
|
| +struct Employee {
|
| + uint64 employee_id;
|
| + string name;
|
| + [MinVersion=1] Date? birthday;
|
| +};
|
| +```
|
| +
|
| +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.
|
| +
|
| +**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 or *N*-method interface, the set of explicitly
|
| + assigned ordinal values must be limited to the range *[0, N-1]*.
|
| +
|
| +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;
|
| +};
|
| +```
|
| +
|
| +*** note
|
| +**NOTE:** Newly added fields of Mojo object or handle types MUST be nullable.
|
| +See [Primitive Types](#Primitive-Types).
|
| +***
|
| +
|
| +### 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.
|
| +
|
| + 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 {
|
| + AddEmployee(Employee employee) => (bool success);
|
| + QueryEmployee(uint64 id) => (Employee? employee);
|
| +};
|
| +
|
| +// New version:
|
| +interface HumanResourceDatabase {
|
| + AddEmployee(Employee employee) => (bool success);
|
| +
|
| + QueryEmployee(uint64 id, [MinVersion=1] bool retrieve_finger_print)
|
| + => (Employee? employee,
|
| + [MinVersion=1] array<uint8>? finger_print);
|
| +
|
| + [MinVersion=1]
|
| + AttachFingerPrint(uint64 id, array<uint8> finger_print)
|
| + => (bool success);
|
| +};
|
| +```
|
| +
|
| +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. However, if the method
|
| +call itself 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
|
| +`InterfacePtr<T>` in C++ bindings.)
|
| +
|
| +See
|
| +[C++ Versioning Considerations](/mojo/public/cpp/bindings#Versioning-Considerations)
|
| +and [Java Versioning Considerations](/mojo/public/java/bindings#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 {
|
| + SALES,
|
| + DEV,
|
| +};
|
| +```
|
| +
|
| +And later you can extend this enum without breaking backwards compatibility:
|
| +
|
| +``` cpp
|
| +[Extensible]
|
| +enum Department {
|
| + SALES,
|
| + DEV,
|
| + [MinVersion=1] RESEARCH,
|
| +};
|
| +```
|
| +
|
| +*** 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#Versioning-Considerations)
|
| +for details.
|
| +
|
| +## 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 Const
|
| +
|
| +AttributeSection = "[" 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 Orginal 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 "(" ParamterList ")" 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"
|
| +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
|
| +
|
| +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.
|
|
|