OLD | NEW |
(Empty) | |
| 1 # ![Mojo Graphic](https://goo.gl/6CdlbH) Mojom IDL and Bindings Generator |
| 2 This document is a subset of the [Mojo documentation](/mojo). |
| 3 |
| 4 [TOC] |
| 5 |
| 6 ## Overview |
| 7 |
| 8 Mojom is the IDL for Mojo bindings interfaces. Given a `.mojom` file, the |
| 9 [bindings generator](https://cs.chromium.org/chromium/src/mojo/public/tools/bind
ings) |
| 10 outputs bindings for all supported languages: **C++**, **JavaScript**, and |
| 11 **Java**. |
| 12 |
| 13 For a trivial example consider the following hypothetical Mojom file we write to |
| 14 `//services/widget/public/interfaces/frobinator.mojom`: |
| 15 |
| 16 ``` |
| 17 module widget.mojom; |
| 18 |
| 19 interface Frobinator { |
| 20 Frobinate(); |
| 21 }; |
| 22 ``` |
| 23 |
| 24 This defines a single [interface](#Interfaces) named `Frobinator` in a |
| 25 [module](#Modules) named `widget.mojom` (and thus fully qualified in Mojom as |
| 26 `widget.mojom.Frobinator`.) Note that many interfaces and/or other types of |
| 27 definitions may be included in a single Mojom file. |
| 28 |
| 29 If we add a corresponding GN target to |
| 30 `//services/widget/public/interfaces/BUILD.gn`: |
| 31 |
| 32 ``` |
| 33 import("mojo/public/tools/bindings/mojom.gni") |
| 34 |
| 35 mojom("interfaces") { |
| 36 sources = [ |
| 37 "frobinator.mojom", |
| 38 ] |
| 39 } |
| 40 ``` |
| 41 |
| 42 and then build this target: |
| 43 |
| 44 ``` |
| 45 ninja -C out/r services/widget/public/interfaces |
| 46 ``` |
| 47 |
| 48 we'll find several generated sources in our output directory: |
| 49 |
| 50 ``` |
| 51 out/r/gen/services/widget/public/interfaces/frobinator.mojom.cc |
| 52 out/r/gen/services/widget/public/interfaces/frobinator.mojom.h |
| 53 out/r/gen/services/widget/public/interfaces/frobinator.mojom.js |
| 54 out/r/gen/services/widget/public/interfaces/frobinator.mojom.srcjar |
| 55 ... |
| 56 ``` |
| 57 |
| 58 Each of these generated source modules includes a set of definitions |
| 59 representing the Mojom contents within the target language. For more details |
| 60 regarding the generated outputs please see |
| 61 [documentation for individual target languages](#Generated-Code-For-Target-Langu
ages). |
| 62 |
| 63 ## Mojom Syntax |
| 64 |
| 65 Mojom IDL allows developers to define **structs**, **unions**, **interfaces**, |
| 66 **constants**, and **enums**, all within the context of a **module**. These |
| 67 definitions are used to generate code in the supported target languages at build |
| 68 time. |
| 69 |
| 70 Mojom files may **import** other Mojom files in order to reference their |
| 71 definitions. |
| 72 |
| 73 ### Primitive Types |
| 74 Mojom supports a few basic data types which may be composed into structs or used |
| 75 for message parameters. |
| 76 |
| 77 | Type | Description |
| 78 |-------------------------------|-----------------------------------------------
--------| |
| 79 | `bool` | Boolean type (`true` or `false`.) |
| 80 | `int8`, `uint8` | Signed or unsigned 8-bit integer. |
| 81 | `int16`, `uint16` | Signed or unsigned 16-bit integer. |
| 82 | `int32`, `uint32` | Signed or unsigned 32-bit integer. |
| 83 | `int64`, `uint64` | Signed or unsigned 64-bit integer. |
| 84 | `float`, `double` | 32- or 64-bit floating point number. |
| 85 | `string` | UTF-8 encoded string. |
| 86 | `array<T>` | Array of any Mojom type *T*; for example, `arr
ay<uint8>` or `array<array<string>>`. |
| 87 | `array<T, N>` | Fixed-length array of any Mojom type *T*. The
parameter *N* must be an integral constant. |
| 88 | `map<S, T>` | Associated array maping values of type *S* to
values of type *T*. *S* may be a `string`, `enum`, or numeric type. |
| 89 | `handle` | Generic Mojo handle. May be any type of handle
, including a wrapped native platform handle. |
| 90 | `handle<message_pipe>` | Generic message pipe handle. |
| 91 | `handle<shared_buffer>` | Shared buffer handle. |
| 92 | `handle<data_pipe_producer>` | Data pipe producer handle. |
| 93 | `handle<data_pipe_consumer>` | Data pipe consumer handle. |
| 94 | *`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. |
| 95 | *`InterfaceType&`* | An interface request for any user-defined Mojo
m interface type. This is sugar for a more strongly-typed message pipe handle wh
ich is expected to receive request messages and should therefore eventually be b
ound to an implementation of the interface. |
| 96 | *`associated InterfaceType`* | An associated interface handle. See [Associate
d Interfaces](#Associated-Interfaces) |
| 97 | *`associated InterfaceType&`* | An associated interface request. See [Associat
ed Interfaces](#Associated-Interfaces) |
| 98 | *T*? | An optional (nullable) value. Primitive numeri
c types (integers, floats, booleans, and enums) are not nullable. All other type
s are nullable. |
| 99 |
| 100 ### Modules |
| 101 |
| 102 Every Mojom file may optionally specify a single **module** to which it belongs. |
| 103 |
| 104 This is used strictly for aggregaging all defined symbols therein within a |
| 105 common Mojom namespace. The specific impact this has on generated binidngs code |
| 106 varies for each target language. For example, if the following Mojom is used to |
| 107 generate bindings: |
| 108 |
| 109 ``` |
| 110 module business.stuff; |
| 111 |
| 112 interface MoneyGenerator { |
| 113 GenerateMoney(); |
| 114 }; |
| 115 ``` |
| 116 |
| 117 Generated C++ bindings will define a class interface `MoneyGenerator` in the |
| 118 `business::stuff` namespace, while Java bindings will define an interface |
| 119 `MoneyGenerator` in the `org.chromium.business.stuff` package. JavaScript |
| 120 bindings at this time are unaffected by module declarations. |
| 121 |
| 122 **NOTE:** By convention in the Chromium codebase, **all** Mojom files should |
| 123 declare a module name with at least (and preferrably exactly) one top-level name |
| 124 as well as an inner `mojom` module suffix. *e.g.*, `chrome.mojom`, |
| 125 `business.mojom`, *etc.* |
| 126 |
| 127 This convention makes it easy to tell which symbols are generated by Mojom when |
| 128 reading non-Mojom code, and it also avoids namespace collisions in the fairly |
| 129 common scenario where you have a real C++ or Java `Foo` along with a |
| 130 corresponding Mojom `Foo` for its serialized representation. |
| 131 |
| 132 ### Imports |
| 133 |
| 134 If your Mojom references definitions from other Mojom files, you must **import** |
| 135 those files. Import syntax is as follows: |
| 136 |
| 137 ``` |
| 138 import "services/widget/public/interfaces/frobinator.mojom"; |
| 139 ``` |
| 140 |
| 141 Import paths are always relative to the top-level directory. |
| 142 |
| 143 Note that circular imports are **not** supported. |
| 144 |
| 145 ### Structs |
| 146 |
| 147 Structs are defined using the **struct** keyword, and they provide a way to |
| 148 group related fields together: |
| 149 |
| 150 ``` cpp |
| 151 struct StringPair { |
| 152 string first; |
| 153 string second; |
| 154 }; |
| 155 ``` |
| 156 |
| 157 Struct fields may be comprised of any of the types listed above in the |
| 158 [Primitive Types](#Primitive-Types) section. |
| 159 |
| 160 Default values may be specified as long as they are constant: |
| 161 |
| 162 ``` cpp |
| 163 struct Request { |
| 164 int32 id = -1; |
| 165 string details; |
| 166 }; |
| 167 ``` |
| 168 |
| 169 What follows is a fairly |
| 170 comprehensive example using the supported field types: |
| 171 |
| 172 ``` cpp |
| 173 struct StringPair { |
| 174 string first; |
| 175 string second; |
| 176 }; |
| 177 |
| 178 enum AnEnum { |
| 179 YES, |
| 180 NO |
| 181 }; |
| 182 |
| 183 interface SampleInterface { |
| 184 DoStuff(); |
| 185 }; |
| 186 |
| 187 struct AllTheThings { |
| 188 // Note that these types can never be marked nullable! |
| 189 bool boolean_value; |
| 190 int8 signed_8bit_value = 42; |
| 191 uint8 unsigned_8bit_value; |
| 192 int16 signed_16bit_value; |
| 193 uint16 unsigned_16bit_value; |
| 194 int32 signed_32bit_value; |
| 195 uint32 unsigned_32bit_value; |
| 196 int64 signed_64bit_value; |
| 197 uint64 unsigned_64bit_value; |
| 198 float float_value_32bit; |
| 199 double float_value_64bit; |
| 200 AnEnum enum_value = AnEnum.YES; |
| 201 |
| 202 // Strings may be nullable. |
| 203 string? maybe_a_string_maybe_not; |
| 204 |
| 205 // Structs may contain other structs. These may also be nullable. |
| 206 StringPair some_strings; |
| 207 StringPair? maybe_some_more_strings; |
| 208 |
| 209 // In fact structs can also be nested, though in practice you must always make |
| 210 // such fields nullable -- otherwise messages would need to be infinitely long |
| 211 // in order to pass validation! |
| 212 AllTheThings? more_things; |
| 213 |
| 214 // Arrays may be templated over any Mojom type, and are always nullable: |
| 215 array<int32> numbers; |
| 216 array<int32>? maybe_more_numbers; |
| 217 |
| 218 // Arrays of arrays of arrays... are fine. |
| 219 array<array<array<AnEnum>>> this_works_but_really_plz_stop; |
| 220 |
| 221 // The element type may be nullable if it's a type which is allowed to be |
| 222 // nullable. |
| 223 array<AllTheThings?> more_maybe_things; |
| 224 |
| 225 // Fixed-size arrays get some extra validation on the receiving end to ensure |
| 226 // that the correct number of elements is always received. |
| 227 array<uint64, 2> uuid; |
| 228 |
| 229 // Maps follow many of the same rules as arrays. Key types may be any |
| 230 // non-handle, non-collection type, and value types may be any supported |
| 231 // struct field type. Maps may also be nullable. |
| 232 map<string, int32> one_map; |
| 233 map<AnEnum, string>? maybe_another_map; |
| 234 map<StringPair, AllTheThings?>? maybe_a_pretty_weird_but_valid_map; |
| 235 map<StringPair, map<int32, array<map<string, string>?>?>?> ridiculous; |
| 236 |
| 237 // And finally, all handle types are valid as struct fields and may be |
| 238 // nullable. Note that interfaces and interface requests (the "Foo" and |
| 239 // "Foo&" type syntax respectively) are just strongly-typed message pipe |
| 240 // handles. |
| 241 handle generic_handle; |
| 242 handle<data_pipe_consumer> reader; |
| 243 handle<data_pipe_producer>? maybe_writer; |
| 244 handle<shared_buffer> dumping_ground; |
| 245 handle<message_pipe> raw_message_pipe; |
| 246 SampleInterface? maybe_a_sample_interface_client_pipe; |
| 247 SampleInterface& non_nullable_sample_interface_request; |
| 248 SampleInterface&? nullable_sample_interface_request; |
| 249 associated SampleInterface associated_interface_client; |
| 250 associated SampleInterface& associated_interface_request; |
| 251 assocaited SampleInterface&? maybe_another_associated_request; |
| 252 }; |
| 253 ``` |
| 254 |
| 255 For details on how all of these different types translate to usable generated |
| 256 code, see |
| 257 [documentation for individual target languages](#Generated-Code-For-Target-Langu
ages). |
| 258 |
| 259 ### Enumeration Types |
| 260 |
| 261 Enumeration types may be defined using the **enum** keyword either directly |
| 262 within a module or within the namespace of some struct or interface: |
| 263 |
| 264 ``` |
| 265 module business.mojom; |
| 266 |
| 267 enum Department { |
| 268 SALES = 0, |
| 269 DEV, |
| 270 }; |
| 271 |
| 272 struct Employee { |
| 273 enum Type { |
| 274 FULL_TIME, |
| 275 PART_TIME, |
| 276 }; |
| 277 |
| 278 Type type; |
| 279 // ... |
| 280 }; |
| 281 ``` |
| 282 |
| 283 That that similar to C-style enums, individual values may be explicitly assigned |
| 284 within an enum definition. By default values are based at zero and incremenet by |
| 285 1 sequentially. |
| 286 |
| 287 The effect of nested definitions on generated bindings varies depending on the |
| 288 target language. See [documentation for individual target languages](#Generated-
Code-For-Target-Languages) |
| 289 |
| 290 ### Constants |
| 291 |
| 292 Constants may be defined using the **const** keyword either directly within a |
| 293 module or within the namespace of some struct or interface: |
| 294 |
| 295 ``` |
| 296 module business.mojom; |
| 297 |
| 298 const string kServiceName = "business"; |
| 299 |
| 300 struct Employee { |
| 301 const uint64 kInvalidId = 0; |
| 302 |
| 303 enum Type { |
| 304 FULL_TIME, |
| 305 PART_TIME, |
| 306 }; |
| 307 |
| 308 uint64 id = kInvalidId; |
| 309 Type type; |
| 310 }; |
| 311 ``` |
| 312 |
| 313 The effect of nested definitions on generated bindings varies depending on the |
| 314 target language. See [documentation for individual target languages](#Generated-
Code-For-Target-Languages) |
| 315 |
| 316 ### Interfaces |
| 317 |
| 318 An **interface** is a logical bundle of parameterized request messages. Each |
| 319 request message may optionally define a parameterized response message. Here's |
| 320 syntax to define an interface `Foo` with various kinds of requests: |
| 321 |
| 322 ``` |
| 323 interface Foo { |
| 324 // A request which takes no arguments and expects no response. |
| 325 MyMessage(); |
| 326 |
| 327 // A request which has some arguments and expects no response. |
| 328 MyOtherMessage(string name, array<uint8> bytes); |
| 329 |
| 330 // A request which expects a single-argument response. |
| 331 MyMessageWithResponse(string command) => (bool success); |
| 332 |
| 333 // A request which expects a response with multiple arguments. |
| 334 MyMessageWithMoarResponse(string a, string b) => (int8 c, int8 d); |
| 335 }; |
| 336 ``` |
| 337 |
| 338 Anything which is a valid struct field type (see [Structs](#Structs)) is also a |
| 339 valid request or response argument type. The type notation is the same for both. |
| 340 |
| 341 ### Attributes |
| 342 |
| 343 Mojom definitions may have their meaning altered by **attributes**, specified |
| 344 with a syntax similar to Java or C# attributes. There are a handle of |
| 345 interesting attributes supported today. |
| 346 |
| 347 **`[Sync]`** |
| 348 : The `Sync` attribute may be specified for any interface method which expects |
| 349 a response. This makes it so that callers of the method can wait |
| 350 synchronously for a response. See |
| 351 [Synchronous Calls](/mojo/public/cpp/bindings#Synchronous-Calls) in the C++ |
| 352 bindings documentation. Note that sync calls are not currently supported in |
| 353 other target languages. |
| 354 |
| 355 **`[Extensible]`** |
| 356 : The `Extensible` attribute may be specified for any enum definition. This |
| 357 essentially disables builtin range validation when receiving values of the |
| 358 enum type in a message, allowing older bindings to tolerate unrecognized |
| 359 values from newer versions of the enum. |
| 360 |
| 361 **`[Native]`** |
| 362 : The `Native` attribute may be specified for an empty struct declaration to |
| 363 provide a nominal bridge between Mojo IPC and legacy `IPC::ParamTraits` or |
| 364 `IPC_STRUCT_TRAITS*` macros. |
| 365 See [Using Legacy IPC Traits](/ipc#Using-Legacy-IPC-Traits) for more |
| 366 details. Note support for this attribute is strictly limited to C++ bindings |
| 367 generation. |
| 368 |
| 369 **`[MinVersion=N]`** |
| 370 : The `MinVersion` attribute is used to specify the version at which a given |
| 371 field, enum value, interface method, or method parameter was introduced. |
| 372 See [Versioning](#Versioning) for more details. |
| 373 |
| 374 ## Generated Code For Target Languages |
| 375 |
| 376 When the bindings generator successfully processes an input Mojom file, it emits |
| 377 corresponding code for each supported target language. For more details on how |
| 378 Mojom concepts translate to a given target langauge, please refer to the |
| 379 bindings API documentation for that language: |
| 380 |
| 381 * [C++ Bindings](/mojo/public/cpp/bindings) |
| 382 * [JavaScript Bindings](/mojo/public/js) |
| 383 * [Java Bindings](/mojo/public/java/bindings) |
| 384 |
| 385 ## Message Validation |
| 386 |
| 387 Regardless of target language, all interface messages are validated during |
| 388 deserialization before they are dispatched to a receiving implementation of the |
| 389 interface. This helps to ensure consitent validation across interfaces without |
| 390 leaving the burden to developers and security reviewers every time a new message |
| 391 is added. |
| 392 |
| 393 If a message fails validation, it is never dispatched. Instead a **connection |
| 394 error** is raised on the binding object (see |
| 395 [C++ Connection Errors](/mojo/public/cpp/bindings#Connection-Errors), |
| 396 [Java Connection Errors](/mojo/public/java/bindings#Connection-Errors), or |
| 397 [JavaScript Connection Errors](/mojo/public/js#Connection-Errors) for details.) |
| 398 |
| 399 Some baseline level of validation is done automatically for primitive Mojom |
| 400 types. |
| 401 |
| 402 ### Non-Nullable Objects |
| 403 |
| 404 Mojom fields or parameter values (*e.g.*, structs, interfaces, arrays, *etc.*) |
| 405 may be marked nullable in Mojom definitions (see |
| 406 [Primitive Types](#Primitive-Types).) If a field or parameter is **not** marked |
| 407 nullable but a message is received with a null value in its place, that message |
| 408 will fail validation. |
| 409 |
| 410 ### Enums |
| 411 |
| 412 Enums declared in Mojom are automatically validated against the range of legal |
| 413 values. For example if a Mojom declares the enum: |
| 414 |
| 415 ``` cpp |
| 416 enum AdvancedBoolean { |
| 417 TRUE = 0, |
| 418 FALSE = 1, |
| 419 FILE_NOT_FOUND = 2, |
| 420 }; |
| 421 ``` |
| 422 |
| 423 and a message is received with the integral value 3 (or anything other than 0, |
| 424 1, or 2) in place of some `AdvancedBoolean` field or parameter, the message will |
| 425 fail validation. |
| 426 |
| 427 *** note |
| 428 NOTE: It's possible to avoid this type of validation error by explicitly marking |
| 429 an enum as [Extensible](#Attributes) if you anticipate your enum being exchanged |
| 430 between two different versions of the binding interface. See |
| 431 [Versioning](#Versioning). |
| 432 *** |
| 433 |
| 434 ### Other failures |
| 435 |
| 436 There are a host of internal validation errors that may occur when a malformed |
| 437 message is received, but developers should not be concerned with these |
| 438 specifically; in general they can only result from internal bindings bugs, |
| 439 compromised processes, or some remote endpoint making a dubious effort to |
| 440 manually encode their own bindings messages. |
| 441 |
| 442 ### Custom Validation |
| 443 |
| 444 It's also possible for developers to define custom validation logic for specific |
| 445 Mojom struct types by exploiting the |
| 446 [type mapping](/mojo/public/cpp/bindings#Type-Mapping) system for C++ bindings. |
| 447 Messages rejected by custom validation logic trigger the same validation failure |
| 448 behavior as the built-in type validation routines. |
| 449 |
| 450 ## Associated Interfaces |
| 451 |
| 452 As mentioned in the [Primitive Types](#Primitive-Types) section above, interface |
| 453 and interface request fields and parameters may be marked as `associated`. This |
| 454 essentially means that they are piggy-backed on some other interface's message |
| 455 pipe. |
| 456 |
| 457 Because individual interface message pipes operate independently there can be no |
| 458 relative ordering guarantees among them. Associated interfaces are useful when |
| 459 one interface needs to guarantee strict FIFO ordering with respect to one or |
| 460 more other interfaces, as they allow interfaces to share a single pipe. |
| 461 |
| 462 Currenly associated interfaces are only supported in generated C++ bindings. |
| 463 See the documentation for |
| 464 [C++ Associated Interfaces](/mojo/public/cpp/bindings#Associated-Interfaces). |
| 465 |
| 466 ## Versioning |
| 467 |
| 468 ### Overview |
| 469 |
| 470 *** note |
| 471 **NOTE:** You don't need to worry about versioning if you don't care about |
| 472 backwards compatibility. Specifically, all parts of Chrome are updated |
| 473 atomically today and there is not yet any possibility of any two Chrome |
| 474 processes communicating with two different versions of any given Mojom |
| 475 interface. |
| 476 *** |
| 477 |
| 478 Services extend their interfaces to support new features over time, and clients |
| 479 want to use those new features when they are available. If services and clients |
| 480 are not updated at the same time, it's important for them to be able to |
| 481 communicate with each other using different snapshots (versions) of their |
| 482 interfaces. |
| 483 |
| 484 This document shows how to extend Mojom interfaces in a backwards-compatible |
| 485 way. Changing interfaces in a non-backwards-compatible way is not discussed, |
| 486 because in that case communication between different interface versions is |
| 487 impossible anyway. |
| 488 |
| 489 ### Versioned Structs |
| 490 |
| 491 You can use the `MinVersion` [attribute](#Attributes) to indicate from which |
| 492 version a struct field is introduced. Assume you have the following struct: |
| 493 |
| 494 ``` cpp |
| 495 struct Employee { |
| 496 uint64 employee_id; |
| 497 string name; |
| 498 }; |
| 499 ``` |
| 500 |
| 501 and you would like to add a birthday field. You can do: |
| 502 |
| 503 ``` cpp |
| 504 struct Employee { |
| 505 uint64 employee_id; |
| 506 string name; |
| 507 [MinVersion=1] Date? birthday; |
| 508 }; |
| 509 ``` |
| 510 |
| 511 By default, fields belong to version 0. New fields must be appended to the |
| 512 struct definition (*i.e*., existing fields must not change **ordinal value**) |
| 513 with the `MinVersion` attribute set to a number greater than any previous |
| 514 existing versions. |
| 515 |
| 516 **Ordinal value** refers to the relative positional layout of a struct's fields |
| 517 (and an interface's methods) when encoded in a message. Implicitly, ordinal |
| 518 numbers are assigned to fields according to lexical position. In the example |
| 519 above, `employee_id` has an ordinal value of 0 and `name` has an ordinal value |
| 520 of 1. |
| 521 |
| 522 Ordinal values can be specified explicitly using `**@**` notation, subject to |
| 523 the following hard constraints: |
| 524 |
| 525 * For any given struct or interface, if any field or method explicitly specifies |
| 526 an ordinal value, all fields or methods must explicitly specify an ordinal |
| 527 value. |
| 528 * For an *N*-field struct or *N*-method interface, the set of explicitly |
| 529 assigned ordinal values must be limited to the range *[0, N-1]*. |
| 530 |
| 531 You may reorder fields, but you must ensure that the ordinal values of existing |
| 532 fields remain unchanged. For example, the following struct remains |
| 533 backwards-compatible: |
| 534 |
| 535 ``` cpp |
| 536 struct Employee { |
| 537 uint64 employee_id@0; |
| 538 [MinVersion=1] Date? birthday@2; |
| 539 string name@1; |
| 540 }; |
| 541 ``` |
| 542 |
| 543 *** note |
| 544 **NOTE:** Newly added fields of Mojo object or handle types MUST be nullable. |
| 545 See [Primitive Types](#Primitive-Types). |
| 546 *** |
| 547 |
| 548 ### Versioned Interfaces |
| 549 |
| 550 There are two dimensions on which an interface can be extended |
| 551 |
| 552 **Appending New Parameters To Existing Methods** |
| 553 : Parameter lists are treated as structs internally, so all the rules of |
| 554 versioned structs apply to method parameter lists. The only difference is |
| 555 that the version number is scoped to the whole interface rather than to any |
| 556 individual parameter list. |
| 557 |
| 558 Please note that adding a response to a message which did not previously |
| 559 expect a response is a not a backwards-compatible change. |
| 560 |
| 561 **Appending New Methods** |
| 562 : Similarly, you can reorder methods with explicit ordinal values as long as |
| 563 the ordinal values of existing methods are unchanged. |
| 564 |
| 565 For example: |
| 566 |
| 567 ``` cpp |
| 568 // Old version: |
| 569 interface HumanResourceDatabase { |
| 570 AddEmployee(Employee employee) => (bool success); |
| 571 QueryEmployee(uint64 id) => (Employee? employee); |
| 572 }; |
| 573 |
| 574 // New version: |
| 575 interface HumanResourceDatabase { |
| 576 AddEmployee(Employee employee) => (bool success); |
| 577 |
| 578 QueryEmployee(uint64 id, [MinVersion=1] bool retrieve_finger_print) |
| 579 => (Employee? employee, |
| 580 [MinVersion=1] array<uint8>? finger_print); |
| 581 |
| 582 [MinVersion=1] |
| 583 AttachFingerPrint(uint64 id, array<uint8> finger_print) |
| 584 => (bool success); |
| 585 }; |
| 586 ``` |
| 587 |
| 588 Similar to [versioned structs](#Versioned-Structs), when you pass the parameter |
| 589 list of a request or response method to a destination using an older version of |
| 590 an interface, unrecognized fields are silently discarded. However, if the method |
| 591 call itself is not recognized, it is considered a validation error and the |
| 592 receiver will close its end of the interface pipe. For example, if a client on |
| 593 version 1 of the above interface sends an `AttachFingerPrint` request to an |
| 594 implementation of version 0, the client will be disconnected. |
| 595 |
| 596 Bindings target languages that support versioning expose means to query or |
| 597 assert the remote version from a client handle (*e.g.*, an |
| 598 `InterfacePtr<T>` in C++ bindings.) |
| 599 |
| 600 See |
| 601 [C++ Versioning Considerations](/mojo/public/cpp/bindings#Versioning-Considerati
ons) |
| 602 and [Java Versioning Considerations](/mojo/public/java/bindings#Versioning-Consi
derations) |
| 603 |
| 604 ### Versioned Enums |
| 605 |
| 606 **By default, enums are non-extensible**, which means that generated message |
| 607 validation code does not expect to see new values in the future. When an unknown |
| 608 value is seen for a non-extensible enum field or parameter, a validation error |
| 609 is raised. |
| 610 |
| 611 If you want an enum to be extensible in the future, you can apply the |
| 612 `[Extensible]` [attribute](#Attributes): |
| 613 |
| 614 ``` cpp |
| 615 [Extensible] |
| 616 enum Department { |
| 617 SALES, |
| 618 DEV, |
| 619 }; |
| 620 ``` |
| 621 |
| 622 And later you can extend this enum without breaking backwards compatibility: |
| 623 |
| 624 ``` cpp |
| 625 [Extensible] |
| 626 enum Department { |
| 627 SALES, |
| 628 DEV, |
| 629 [MinVersion=1] RESEARCH, |
| 630 }; |
| 631 ``` |
| 632 |
| 633 *** note |
| 634 **NOTE:** For versioned enum definitions, the use of a `[MinVersion]` attribute |
| 635 is strictly for documentation purposes. It has no impact on the generated code. |
| 636 *** |
| 637 |
| 638 With extensible enums, bound interface implementations may receive unknown enum |
| 639 values and will need to deal with them gracefully. See |
| 640 [C++ Versioning Considerations](/mojo/public/cpp/bindings#Versioning-Considerati
ons) |
| 641 for details. |
| 642 |
| 643 ## Grammar Reference |
| 644 |
| 645 Below is the (BNF-ish) context-free grammar of the Mojom language: |
| 646 |
| 647 ``` |
| 648 MojomFile = StatementList |
| 649 StatementList = Statement StatementList | Statement |
| 650 Statement = ModuleStatement | ImportStatement | Definition |
| 651 |
| 652 ModuleStatement = AttributeSection "module" Identifier ";" |
| 653 ImportStatement = "import" StringLiteral ";" |
| 654 Definition = Struct Union Interface Enum Const |
| 655 |
| 656 AttributeSection = "[" AttributeList "]" |
| 657 AttributeList = <empty> | NonEmptyAttributeList |
| 658 NonEmptyAttributeList = Attribute |
| 659 | Attribute "," NonEmptyAttributeList |
| 660 Attribute = Name |
| 661 | Name "=" Name |
| 662 | Name "=" Literal |
| 663 |
| 664 Struct = AttributeSection "struct" Name "{" StructBody "}" ";" |
| 665 | AttributeSection "struct" Name ";" |
| 666 StructBody = <empty> |
| 667 | StructBody Const |
| 668 | StructBody Enum |
| 669 | StructBody StructField |
| 670 StructField = AttributeSection TypeSpec Name Orginal Default ";" |
| 671 |
| 672 Union = AttributeSection "union" Name "{" UnionBody "}" ";" |
| 673 UnionBody = <empty> | UnionBody UnionField |
| 674 UnionField = AttributeSection TypeSpec Name Ordinal ";" |
| 675 |
| 676 Interface = AttributeSection "interface" Name "{" InterfaceBody "}" ";" |
| 677 InterfaceBody = <empty> |
| 678 | InterfaceBody Const |
| 679 | InterfaceBody Enum |
| 680 | InterfaceBody Method |
| 681 Method = AttributeSection Name Ordinal "(" ParamterList ")" Response ";" |
| 682 ParameterList = <empty> | NonEmptyParameterList |
| 683 NonEmptyParameterList = Parameter |
| 684 | Parameter "," NonEmptyParameterList |
| 685 Parameter = AttributeSection TypeSpec Name Ordinal |
| 686 Response = <empty> | "=>" "(" ParameterList ")" |
| 687 |
| 688 TypeSpec = TypeName "?" | TypeName |
| 689 TypeName = BasicTypeName |
| 690 | Array |
| 691 | FixedArray |
| 692 | Map |
| 693 | InterfaceRequest |
| 694 BasicTypeName = Identifier | "associated" Identifier | HandleType | NumericType |
| 695 NumericType = "bool" | "int8" | "uint8" | "int16" | "uint16" | "int32" |
| 696 | "uint32" | "int64" | "uint64" | "float" | "double" |
| 697 HandleType = "handle" | "handle" "<" SpecificHandleType ">" |
| 698 SpecificHandleType = "message_pipe" |
| 699 | "shared_buffer" |
| 700 | "data_pipe_consumer" |
| 701 | "data_pipe_producer" |
| 702 Array = "array" "<" TypeSpec ">" |
| 703 FixedArray = "array" "<" TypeSpec "," IntConstDec ">" |
| 704 Map = "map" "<" Identifier "," TypeSpec ">" |
| 705 InterfaceRequest = Identifier "&" | "associated" Identifier "&" |
| 706 |
| 707 Ordinal = <empty> | OrdinalValue |
| 708 |
| 709 Default = <empty> | "=" Constant |
| 710 |
| 711 Enum = AttributeSection "enum" Name "{" NonEmptyEnumValueList "}" ";" |
| 712 | AttributeSection "enum" Name "{" NonEmptyEnumValueList "," "}" ";" |
| 713 NonEmptyEnumValueList = EnumValue | NonEmptyEnumValueList "," EnumValue |
| 714 EnumValue = AttributeSection Name |
| 715 | AttributeSection Name "=" Integer |
| 716 | AttributeSection Name "=" Identifier |
| 717 |
| 718 Const = "const" TypeSpec Name "=" Constant ";" |
| 719 |
| 720 Constant = Literal | Identifier ";" |
| 721 |
| 722 Identifier = Name | Name "." Identifier |
| 723 |
| 724 Literal = Integer | Float | "true" | "false" | "default" | StringLiteral |
| 725 |
| 726 Integer = IntConst | "+" IntConst | "-" IntConst |
| 727 IntConst = IntConstDec | IntConstHex |
| 728 |
| 729 Float = FloatConst | "+" FloatConst | "-" FloatConst |
| 730 |
| 731 ; The rules below are for tokens matched strictly according to the given regexes |
| 732 |
| 733 Identifier = /[a-zA-Z_][0-9a-zA-Z_]*/ |
| 734 IntConstDec = /0|(1-9[0-9]*)/ |
| 735 IntConstHex = /0[xX][0-9a-fA-F]+/ |
| 736 OrdinalValue = /@(0|(1-9[0-9]*))/ |
| 737 FloatConst = ... # Imagine it's close enough to C-style float syntax. |
| 738 StringLiteral = ... # Imagine it's close enough to C-style string literals, incl
uding escapes. |
| 739 ``` |
| 740 |
| 741 ## Additional Documentation |
| 742 |
| 743 [Mojom Message Format](https://docs.google.com/document/d/13pv9cFh5YKuBggDBQ1-AL
8VReF-IYpFOFpRfvWFrwio/edit) |
| 744 : Describes the wire format used by Mojo bindings interfaces over message |
| 745 pipes. |
| 746 |
| 747 [Input Format of Mojom Message Validation Tests](https://docs.google.com/documen
t/d/1-y-2IYctyX2NPaLxJjpJfzVNWCC2SR2MJAD9MpIytHQ/edit) |
| 748 : Describes a text format used to facilitate bindings message validation |
| 749 tests. |
OLD | NEW |