1# Mojo C++ Bindings API
2This document is a subset of the [Mojo documentation](/mojo/README.md).
3
4[TOC]
5
6## Overview
7The Mojo C++ Bindings API leverages the
8[C++ System API](/mojo/public/cpp/system/README.md) to provide a more natural
9set of primitives for communicating over Mojo message pipes. Combined with
10generated code from the
11[Mojom IDL and bindings generator](/mojo/public/tools/bindings/README.md), users
12can easily connect interface clients and implementations across arbitrary intra-
13and inter-process boundaries.
14
15This document provides a detailed guide to bindings API usage with example code
16snippets. For a detailed API references please consult the headers in
17[//mojo/public/cpp/bindings](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/README.md).
18
19For a simplified guide targeted at Chromium developers, see [this
20link](/docs/mojo_and_services.md).
21
22## Getting Started
23
24When a Mojom IDL file is processed by the bindings generator, C++ code is
25emitted in a series of `.h` and `.cc` files with names based on the input
26`.mojom` file. Suppose we create the following Mojom file at
27`//services/db/public/mojom/db.mojom`:
28
29```
30module db.mojom;
31
32interface Table {
33  AddRow(int32 key, string data);
34};
35
36interface Database {
37  CreateTable(Table& table);
38};
39```
40
41And a GN target to generate the bindings in
42`//services/db/public/mojom/BUILD.gn`:
43
44```
45import("//mojo/public/tools/bindings/mojom.gni")
46
47mojom("mojom") {
48  sources = [
49    "db.mojom",
50  ]
51}
52```
53
54Ensure that any target that needs this interface depends on it, e.g. with a line like:
55
56```
57   deps += [ '//services/db/public/mojom' ]
58```
59
60If we then build this target:
61
62```
63ninja -C out/r services/db/public/mojom
64```
65
66This will produce several generated source files, some of which are relevant to
67C++ bindings. Two of these files are:
68
69```
70out/gen/services/db/public/mojom/db.mojom.cc
71out/gen/services/db/public/mojom/db.mojom.h
72```
73
74You can include the above generated header in your sources in order to use the
75definitions therein:
76
77``` cpp
78#include "services/business/public/mojom/factory.mojom.h"
79
80class TableImpl : public db::mojom::Table {
81  // ...
82};
83```
84
85This document covers the different kinds of definitions generated by Mojom IDL
86for C++ consumers and how they can effectively be used to communicate across
87message pipes.
88
89*** note
90**NOTE:** Using C++ bindings from within Blink code is typically subject to
91special constraints which require the use of a different generated header.
92For details, see [Blink Type Mapping](#Blink-Type-Mapping).
93***
94
95## Interfaces
96
97Mojom IDL interfaces are translated to corresponding C++ (pure virtual) class
98interface definitions in the generated header, consisting of a single generated
99method signature for each request message on the interface. Internally there is
100also generated code for serialization and deserialization of messages, but this
101detail is hidden from bindings consumers.
102
103### Basic Usage
104
105Let's consider a new `//sample/logger.mojom` to define a simple logging
106interface which clients can use to log simple string messages:
107
108``` cpp
109module sample.mojom;
110
111interface Logger {
112  Log(string message);
113};
114```
115
116Running this through the bindings generator will produce a `logger.mojom.h`
117with the following definitions (modulo unimportant details):
118
119``` cpp
120namespace sample {
121namespace mojom {
122
123class Logger {
124  virtual ~Logger() {}
125
126  virtual void Log(const std::string& message) = 0;
127};
128
129}  // namespace mojom
130}  // namespace sample
131```
132
133### Remote and PendingReceiver
134
135In the world of Mojo bindings libraries these are effectively strongly-typed
136message pipe endpoints. If a `Remote<T>` is bound to a message pipe
137endpoint, it can be dereferenced to make calls on an opaque `T` interface. These
138calls immediately serialize their arguments (using generated code) and write a
139corresponding message to the pipe.
140
141A `PendingReceiver<T>` is essentially just a typed container to hold the other
142end of a `Remote<T>`'s pipe -- the receiving end -- until it can be
143routed to some implementation which will **bind** it. The `PendingReceiver<T>`
144doesn't actually *do* anything other than hold onto a pipe endpoint and carry
145useful compile-time type information.
146
147![Diagram illustrating Remote and PendingReceiver on either end of a message pipe](/docs/images/mojo_pipe.png)
148
149So how do we create a strongly-typed message pipe?
150
151### Creating Interface Pipes
152
153One way to do this is by manually creating a pipe and wrapping each end with a
154strongly-typed object:
155
156``` cpp
157#include "sample/logger.mojom.h"
158
159mojo::MessagePipe pipe;
160mojo::Remote<sample::mojom::Logger> logger(
161    mojo::PendingRemote<sample::mojom::Logger>(std::move(pipe.handle0), 0));
162mojo::PendingReceiver<sample::mojom::Logger> receiver(std::move(pipe.handle1));
163```
164
165That's pretty verbose, but the C++ Bindings library provides a more convenient
166way to accomplish the same thing. [remote.h](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/remote.h)
167defines a `BindNewPipeAndPassReceiver` method:
168
169``` cpp
170mojo::Remote<sample::mojom::Logger> logger;
171auto receiver = logger.BindNewPipeAndPassReceiver());
172```
173
174This second snippet is equivalent to the first one.
175
176*** note
177**NOTE:** In the first example above you may notice usage of the
178`mojo::PendingRemote<Logger>`. This is similar to a `PendingReceiver<T>`
179in that it merely holds onto a pipe handle and cannot actually read or
180write messages on the pipe. Both this type and `PendingReceiver<T>` are safe
181to move freely from sequence to sequence, whereas a bound `Remote<T>` is bound
182to a single sequence.
183
184A `Remote<T>` may be unbound by calling its `Unbind()` method,
185which returns a new `PendingRemote<T>`. Conversely, an `Remote<T>` may
186bind (and thus take ownership of) an `PendingRemote<T>` so that interface
187calls can be made on the pipe.
188
189The sequence-bound nature of `Remote<T>` is necessary to support safe
190dispatch of its [message responses](#Receiving-Responses) and
191[connection error notifications](#Connection-Errors).
192***
193
194Once the `PendingRemote<Logger>` is bound we can immediately begin calling `Logger`
195interface methods on it, which will immediately write messages into the pipe.
196These messages will stay queued on the receiving end of the pipe until someone
197binds to it and starts reading them.
198
199``` cpp
200logger->Log("Hello!");
201```
202
203This actually writes a `Log` message to the pipe.
204
205![Diagram illustrating a message traveling on a pipe from Remote<Logger> to PendingReceiver<Logger>](/docs/images/mojo_message.png)
206
207But as mentioned above, `PendingReceiver` *doesn't actually do anything*, so
208that message will just sit on the pipe forever. We need a way to read messages
209off the other end of the pipe and dispatch them. We have to
210**bind the pending receiver**.
211
212### Binding a Pending Receiver
213
214There are many different helper classes in the bindings library for binding the
215receiving end of a message pipe. The most primitive among them is `mojo::Receiver<T>`.
216A `mojo::Receiver<T>` bridges an implementation of `T`
217with a single bound message pipe endpoint (via a `mojo::PendingReceiver<T>`),
218which it continuously watches for readability.
219
220Any time the bound pipe becomes readable, the `Receiver` will schedule a task to
221read, deserialize (using generated code), and dispatch all available messages to
222the bound `T` implementation. Below is a sample implementation of the `Logger`
223interface. Notice that the implementation itself owns a `mojo::Receiver`. This is
224a common pattern, since a bound implementation must outlive any `mojo::Receiver`
225which binds it.
226
227``` cpp
228#include "base/logging.h"
229#include "base/macros.h"
230#include "sample/logger.mojom.h"
231
232class LoggerImpl : public sample::mojom::Logger {
233 public:
234  // NOTE: A common pattern for interface implementations which have one
235  // instance per client is to take a PendingReceiver in the constructor.
236
237  explicit LoggerImpl(mojo::PendingReceiver<sample::mojom::Logger> receiver)
238      : receiver_(this, std::move(receiver)) {}
239  ~Logger() override {}
240
241  // sample::mojom::Logger:
242  void Log(const std::string& message) override {
243    LOG(ERROR) << "[Logger] " << message;
244  }
245
246 private:
247  mojo::Receiver<sample::mojom::Logger> receiver_;
248
249  DISALLOW_COPY_AND_ASSIGN(LoggerImpl);
250};
251```
252
253Now we can construct a `LoggerImpl` over our `PendingReceiver<Logger>`, and the
254previously queued `Log` message will be dispatched ASAP on the `LoggerImpl`'s
255sequence:
256
257``` cpp
258LoggerImpl impl(std::move(receiver));
259```
260
261The diagram below illustrates the following sequence of events, all set in
262motion by the above line of code:
263
2641. The `LoggerImpl` constructor is called, passing the `PendingReceiver<Logger>` along
265   to the `Receiver`.
2662. The `Receiver` takes ownership of the `PendingReceiver<Logger>`'s pipe endpoint and
267   begins watching it for readability. The pipe is readable immediately, so a
268   task is scheduled to read the pending `Log` message from the pipe ASAP.
2693. The `Log` message is read and deserialized, causing the `Receiver` to invoke
270   the `Logger::Log` implementation on its bound `LoggerImpl`.
271
272![Diagram illustrating the progression of binding a pending receiver, reading a pending message, and dispatching it](/docs/images/mojo_receiver_and_dispatch.png)
273
274As a result, our implementation will eventually log the client's `"Hello!"`
275message via `LOG(ERROR)`.
276
277*** note
278**NOTE:** Messages will only be read and dispatched from a pipe as long as the
279object which binds it (*i.e.* the `mojo::Receiver` in the above example) remains
280alive.
281***
282
283### Receiving Responses
284
285Some Mojom interface methods expect a response. Suppose we modify our `Logger`
286interface so that the last logged line can be queried like so:
287
288``` cpp
289module sample.mojom;
290
291interface Logger {
292  Log(string message);
293  GetTail() => (string message);
294};
295```
296
297The generated C++ interface will now look like:
298
299``` cpp
300namespace sample {
301namespace mojom {
302
303class Logger {
304 public:
305  virtual ~Logger() {}
306
307  virtual void Log(const std::string& message) = 0;
308
309  using GetTailCallback = base::OnceCallback<void(const std::string& message)>;
310
311  virtual void GetTail(GetTailCallback callback) = 0;
312}
313
314}  // namespace mojom
315}  // namespace sample
316```
317
318As before, both clients and implementations of this interface use the same
319signature for the `GetTail` method: implementations use the `callback` argument
320to *respond* to the request, while clients pass a `callback` argument to
321asynchronously `receive` the response. A client's `callback` runs on the same
322sequence on which they invoked `GetTail` (the sequence to which their `logger`
323is bound). Here's an updated implementation:
324
325```cpp
326class LoggerImpl : public sample::mojom::Logger {
327 public:
328  // NOTE: A common pattern for interface implementations which have one
329  // instance per client is to take a PendingReceiver in the constructor.
330
331  explicit LoggerImpl(mojo::PendingReceiver<sample::mojom::Logger> receiver)
332      : receiver_(this, std::move(receiver)) {}
333  ~Logger() override {}
334
335  // sample::mojom::Logger:
336  void Log(const std::string& message) override {
337    LOG(ERROR) << "[Logger] " << message;
338    lines_.push_back(message);
339  }
340
341  void GetTail(GetTailCallback callback) override {
342    std::move(callback).Run(lines_.back());
343  }
344
345 private:
346  mojo::Receiver<sample::mojom::Logger> receiver_;
347  std::vector<std::string> lines_;
348
349  DISALLOW_COPY_AND_ASSIGN(LoggerImpl);
350};
351```
352
353And an updated client call:
354
355``` cpp
356void OnGetTail(const std::string& message) {
357  LOG(ERROR) << "Tail was: " << message;
358}
359
360logger->GetTail(base::BindOnce(&OnGetTail));
361```
362
363Behind the scenes, the implementation-side callback is actually serializing the
364response arguments and writing them onto the pipe for delivery back to the
365client. Meanwhile the client-side callback is invoked by some internal logic
366which watches the pipe for an incoming response message, reads and deserializes
367it once it arrives, and then invokes the callback with the deserialized
368parameters.
369
370### Connection Errors
371
372If a pipe is disconnected, both endpoints will be able to observe the connection
373error (unless the disconnection is caused by closing/destroying an endpoint, in
374which case that endpoint won't get such a notification). If there are remaining
375incoming messages for an endpoint on disconnection, the connection error won't
376be triggered until the messages are drained.
377
378Pipe disconnection may be caused by:
379* Mojo system-level causes: process terminated, resource exhausted, etc.
380* The bindings close the pipe due to a validation error when processing a
381  received message.
382* The peer endpoint is closed. For example, the remote side is a bound
383  `mojo::Remote<T>` and it is destroyed.
384
385Regardless of the underlying cause, when a connection error is encountered on
386a receiver endpoint, that endpoint's **disconnect handler** (if set) is
387invoked. This handler is a simple `base::OnceClosure` and may only be invoked
388*once* as long as the endpoint is bound to the same pipe. Typically clients and
389implementations use this handler to do some kind of cleanup or -- particuarly if
390the error was unexpected -- create a new pipe and attempt to establish a new
391connection with it.
392
393All message pipe-binding C++ objects (*e.g.*, `mojo::Receiver<T>`,
394`mojo::Remote<T>`, *etc.*) support setting their disconnect handler
395via a `set_disconnect_handler` method.
396
397We can set up another end-to-end `Logger` example to demonstrate disconnect handler
398invocation. Suppose that `LoggerImpl` had set up the following disconnect
399handler within its constructor:
400
401``` cpp
402LoggerImpl::LoggerImpl(mojo::PendingReceiver<sample::mojom::Logger> receiver)
403    : receiver_(this, std::move(receiver)) {
404  receiver_.set_disconnect_handler(
405      base::BindOnce(&LoggerImpl::OnError, base::Unretained(this)));
406}
407
408void LoggerImpl::OnError() {
409  LOG(ERROR) << "Client disconnected! Purging log lines.";
410  lines_.clear();
411}
412
413mojo::Remote<sample::mojom::Logger> logger;
414LoggerImpl impl(logger.BindNewPipeAndPassReceiver());
415logger->Log("OK cool");
416logger.reset();  // Closes the client end.
417
418```
419
420As long as `impl` stays alive here, it will eventually receive the `Log` message
421followed immediately by an invocation of the bound callback which outputs
422`"Client disconnected! Purging log lines."`. Like all other receiver callbacks, a disconnect handler will
423**never** be invoked once its corresponding receiver object has been destroyed.
424
425The use of `base::Unretained` is *safe* because the error handler will never be
426invoked beyond the lifetime of `receiver_`, and `this` owns `receiver_`.
427
428### A Note About Endpoint Lifetime and Callbacks
429Once a `mojo::Remote<T>` is destroyed, it is guaranteed that pending
430callbacks as well as the connection error handler (if registered) won't be
431called.
432
433Once a `mojo::Receiver<T>` is destroyed, it is guaranteed that no more method
434calls are dispatched to the implementation and the connection error handler (if
435registered) won't be called.
436
437### Best practices for dealing with process crashes and callbacks
438A common situation when calling mojo interface methods that take a callback is
439that the caller wants to know if the other endpoint is torn down (e.g. because
440of a crash). In that case, the consumer usually wants to know if the response
441callback won't be run. There are different solutions for this problem, depending
442on how the `Remote<T>` is held:
4431. The consumer owns the `Remote<T>`: `set_disconnect_handler`
444   should be used.
4452. The consumer doesn't own the `Remote<T>`: there are two helpers
446   depending on the behavior that the caller wants. If the caller wants to
447   ensure that an error handler is run, then
448   [**`mojo::WrapCallbackWithDropHandler`**](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/callback_helpers.h?l=46)
449   should be used. If the caller wants the callback to always be run, then
450   [**`mojo::WrapCallbackWithDefaultInvokeIfNotRun`**](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/callback_helpers.h?l=40)
451   helper should be used. With both of these helpers, usual callback care should
452   be followed to ensure that the callbacks don't run after the consumer is
453   destructed (e.g. because the owner of the `Remote<T>` outlives the
454   consumer). This includes using
455   [**`base::WeakPtr`**](https://cs.chromium.org/chromium/src/base/memory/weak_ptr.h?l=5)
456   or
457   [**`base::RefCounted`**](https://cs.chromium.org/chromium/src/base/memory/ref_counted.h?l=246).
458   It should also be noted that with these helpers, the callbacks could be run
459   synchronously while the Remote<T> is reset or destroyed.
460
461### A Note About Ordering
462
463As mentioned in the previous section, closing one end of a pipe will eventually
464trigger a connection error on the other end. However it's important to note that
465this event is itself ordered with respect to any other event (*e.g.* writing a
466message) on the pipe.
467
468This means that it's safe to write something contrived like:
469
470``` cpp
471LoggerImpl::LoggerImpl(mojo::PendingReceiver<sample::mojom::Logger> receiver,
472      base::OnceClosure disconnect_handler)
473    : receiver_(this, std::move(receiver)) {
474  receiver_.set_disconnect_handler(std::move(disconnect_handler));
475}
476
477void GoBindALogger(mojo::PendingReceiver<sample::mojom::Logger> receiver) {
478  base::RunLoop loop;
479  LoggerImpl impl(std::move(receiver), loop.QuitClosure());
480  loop.Run();
481}
482
483void LogSomething() {
484  mojo::Remote<sample::mojom::Logger> logger;
485  bg_thread->task_runner()->PostTask(
486      FROM_HERE, base::BindOnce(&GoBindALogger, logger.BindNewPipeAndPassReceiver()));
487  logger->Log("OK Computer");
488}
489```
490
491When `logger` goes out of scope it immediately closes its end of the message
492pipe, but the impl-side won't notice this until it receives the sent `Log`
493message. Thus the `impl` above will first log our message and *then* see a
494connection error and break out of the run loop.
495
496## Types
497
498### Enums
499
500[Mojom enums](/mojo/public/tools/bindings/README.md#Enumeration-Types) translate
501directly to equivalent strongly-typed C++11 enum classes with `int32_t` as the
502underlying type. The typename and value names are identical between Mojom and
503C++. Mojo also always defines a special enumerator `kMaxValue` that shares the
504value of the highest enumerator: this makes it easy to record Mojo enums in
505histograms and interoperate with legacy IPC.
506
507For example, consider the following Mojom definition:
508
509```cpp
510module business.mojom;
511
512enum Department {
513  kEngineering,
514  kMarketing,
515  kSales,
516};
517```
518
519This translates to the following C++ definition:
520
521```cpp
522namespace business {
523namespace mojom {
524
525enum class Department : int32_t {
526  kEngineering,
527  kMarketing,
528  kSales,
529  kMaxValue = kSales,
530};
531
532}  // namespace mojom
533}  // namespace business
534```
535
536### Structs
537
538[Mojom structs](mojo/public/tools/bindings/README.md#Structs) can be used to
539define logical groupings of fields into a new composite type. Every Mojom struct
540elicits the generation of an identically named, representative C++ class, with
541identically named public fields of corresponding C++ types, and several helpful
542public methods.
543
544For example, consider the following Mojom struct:
545
546```cpp
547module business.mojom;
548
549struct Employee {
550  int64 id;
551  string username;
552  Department department;
553};
554```
555
556This would generate a C++ class like so:
557
558```cpp
559namespace business {
560namespace mojom {
561
562class Employee;
563
564using EmployeePtr = mojo::StructPtr<Employee>;
565
566class Employee {
567 public:
568  // Default constructor - applies default values, potentially ones specified
569  // explicitly within the Mojom.
570  Employee();
571
572  // Value constructor - an explicit argument for every field in the struct, in
573  // lexical Mojom definition order.
574  Employee(int64_t id, const std::string& username, Department department);
575
576  // Creates a new copy of this struct value
577  EmployeePtr Clone();
578
579  // Tests for equality with another struct value of the same type.
580  bool Equals(const Employee& other);
581
582  // Equivalent public fields with names identical to the Mojom.
583  int64_t id;
584  std::string username;
585  Department department;
586};
587
588}  // namespace mojom
589}  // namespace business
590```
591
592Note when used as a message parameter or as a field within another Mojom struct,
593a `struct` type is wrapped by the move-only `mojo::StructPtr` helper, which is
594roughly equivalent to a `std::unique_ptr` with some additional utility methods.
595This allows struct values to be nullable and struct types to be potentially
596self-referential.
597
598Every generated struct class has a static `New()` method which returns a new
599`mojo::StructPtr<T>` wrapping a new instance of the class constructed by
600forwarding the arguments from `New`. For example:
601
602```cpp
603mojom::EmployeePtr e1 = mojom::Employee::New();
604e1->id = 42;
605e1->username = "mojo";
606e1->department = mojom::Department::kEngineering;
607```
608
609is equivalent to
610
611```cpp
612auto e1 = mojom::Employee::New(42, "mojo", mojom::Department::kEngineering);
613```
614
615Now if we define an interface like:
616
617```cpp
618interface EmployeeManager {
619  AddEmployee(Employee e);
620};
621```
622
623We'll get this C++ interface to implement:
624
625```cpp
626class EmployeeManager {
627 public:
628  virtual ~EmployeManager() {}
629
630  virtual void AddEmployee(EmployeePtr e) = 0;
631};
632```
633
634And we can send this message from C++ code as follows:
635
636```cpp
637mojom::EmployeManagerPtr manager = ...;
638manager->AddEmployee(
639    Employee::New(42, "mojo", mojom::Department::kEngineering));
640
641// or
642auto e = Employee::New(42, "mojo", mojom::Department::kEngineering);
643manager->AddEmployee(std::move(e));
644```
645
646### Unions
647
648Similarly to [structs](#Structs), tagged unions generate an identically named,
649representative C++ class which is typically wrapped in a `mojo::StructPtr<T>`.
650
651Unlike structs, all generated union fields are private and must be retrieved and
652manipulated using accessors. A field `foo` is accessible by `get_foo()` and
653settable by `set_foo()`. There is also a boolean `is_foo()` for each field which
654indicates whether the union is currently taking on the value of field `foo` in
655exclusion to all other union fields.
656
657Finally, every generated union class also has a nested `Tag` enum class which
658enumerates all of the named union fields. A Mojom union value's current type can
659be determined by calling the `which()` method which returns a `Tag`.
660
661For example, consider the following Mojom definitions:
662
663```cpp
664union Value {
665  int64 int_value;
666  float float_value;
667  string string_value;
668};
669
670interface Dictionary {
671  AddValue(string key, Value value);
672};
673```
674
675This generates the following C++ interface:
676
677```cpp
678class Value {
679 public:
680  ~Value() {}
681};
682
683class Dictionary {
684 public:
685  virtual ~Dictionary() {}
686
687  virtual void AddValue(const std::string& key, ValuePtr value) = 0;
688};
689```
690
691And we can use it like so:
692
693```cpp
694ValuePtr value = Value::New();
695value->set_int_value(42);
696CHECK(value->is_int_value());
697CHECK_EQ(value->which(), Value::Tag::INT_VALUE);
698
699value->set_float_value(42);
700CHECK(value->is_float_value());
701CHECK_EQ(value->which(), Value::Tag::FLOAT_VALUE);
702
703value->set_string_value("bananas");
704CHECK(value->is_string_value());
705CHECK_EQ(value->which(), Value::Tag::STRING_VALUE);
706```
707
708Finally, note that if a union value is not currently occupied by a given field,
709attempts to access that field will DCHECK:
710
711```cpp
712ValuePtr value = Value::New();
713value->set_int_value(42);
714LOG(INFO) << "Value is " << value->string_value();  // DCHECK!
715```
716
717### Sending Interfaces Over Interfaces
718
719We know how to create interface pipes and use their Remote and PendingReceiver endpoints
720in some interesting ways. This still doesn't add up to interesting IPC! The
721bread and butter of Mojo IPC is the ability to transfer interface endpoints
722across other interfaces, so let's take a look at how to accomplish that.
723
724#### Sending Pending Receivers
725
726Consider a new example Mojom in `//sample/db.mojom`:
727
728``` cpp
729module db.mojom;
730
731interface Table {
732  void AddRow(int32 key, string data);
733};
734
735interface Database {
736  AddTable(pending_receiver<Table> table);
737};
738```
739
740As noted in the
741[Mojom IDL documentation](/mojo/public/tools/bindings/README.md#Primitive-Types), // need to update this page too!
742the `pending_receiver<Table>` syntax corresponds
743precisely to the `PendingReceiver<T>` type discussed in the sections above, and
744in fact the generated code for these interfaces is approximately:
745
746``` cpp
747namespace db {
748namespace mojom {
749
750class Table {
751 public:
752  virtual ~Table() {}
753
754  virtual void AddRow(int32_t key, const std::string& data) = 0;
755}
756
757class Database {
758 public:
759  virtual ~Database() {}
760
761  virtual void AddTable(mojo::PendingReceiver<Table> table);
762};
763
764}  // namespace mojom
765}  // namespace db
766```
767
768We can put this all together now with an implementation of `Table` and
769`Database`:
770
771``` cpp
772#include "sample/db.mojom.h"
773
774class TableImpl : public db::mojom:Table {
775 public:
776  explicit TableImpl(mojo::PendingReceiver<db::mojom::Table> receiver)
777      : receiver_(this, std::move(receiver)) {}
778  ~TableImpl() override {}
779
780  // db::mojom::Table:
781  void AddRow(int32_t key, const std::string& data) override {
782    rows_.insert({key, data});
783  }
784
785 private:
786  mojo::Receiver<db::mojom::Table> receiver_;
787  std::map<int32_t, std::string> rows_;
788};
789
790class DatabaseImpl : public db::mojom::Database {
791 public:
792  explicit DatabaseImpl(mojo::PendingReceiver<db::mojom::Database> receiver)
793      : receiver_(this, std::move(receiver)) {}
794  ~DatabaseImpl() override {}
795
796  // db::mojom::Database:
797  void AddTable(mojo::PendingReceiver<db::mojom::Table> table) {
798    tables_.emplace_back(std::make_unique<TableImpl>(std::move(table)));
799  }
800
801 private:
802  mojo::Receiver<db::mojom::Database> receiver_;
803  std::vector<std::unique_ptr<TableImpl>> tables_;
804};
805```
806
807Pretty straightforward. The `pending_receiver<Table>` Mojom parameter to `AddTable` translates to
808a C++ `mojo::PendingReceiver<db::mojom::Table>`, which we know is just a
809strongly-typed message pipe handle. When `DatabaseImpl` gets an `AddTable` call,
810it constructs a new `TableImpl` and binds it to the received `mojo::PendingReceiver<db::mojom::Table>`.
811
812Let's see how this can be used.
813
814``` cpp
815mojo::Remote<db::mojom::Database> database;
816DatabaseImpl db_impl(database.BindNewPipeAndPassReceiver());
817
818mojo::Remote<db::mojom::Table> table1, table2;
819database->AddTable(table1.BindNewPipeAndPassReceiver());
820database->AddTable(table2.BindNewPipeAndPassReceiver());
821
822table1->AddRow(1, "hiiiiiiii");
823table2->AddRow(2, "heyyyyyy");
824```
825
826Notice that we can again start using the new `Table` pipes immediately, even
827while their `mojo::PendingReceiver<db::mojom::Table>` endpoints are still in transit.
828
829#### Sending Remotes
830
831Of course we can also send `Remote`s:
832
833``` cpp
834interface TableListener {
835  OnRowAdded(int32 key, string data);
836};
837
838interface Table {
839  AddRow(int32 key, string data);
840
841  AddListener(pending_remote<TableListener> listener);
842};
843```
844
845This would generate a `Table::AddListener` signature like so:
846
847``` cpp
848  virtual void AddListener(mojo::PendingRemote<TableListener> listener) = 0;
849```
850
851and this could be used like so:
852
853``` cpp
854mojo::PendingRemote<db::mojom::TableListener> listener;
855TableListenerImpl impl(listener.InitWithNewPipeAndPassReceiver());
856table->AddListener(std::move(listener));
857```
858
859## Other Interface Binding Types
860
861The [Interfaces](#Interfaces) section above covers basic usage of the most
862common bindings object types: `Remote`, `PendingReceiver`, and `Receiver`.
863While these types are probably the most commonly used in practice, there are
864several other ways of binding both client- and implementation-side interface
865pipes.
866
867### Self-owned Receivers
868
869A **self-owned receiver** exists as a standalone object which owns its interface
870implementation and automatically cleans itself up when its bound interface
871endpoint detects an error. The
872[**`MakeSelfOwnedReceiver`**](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/self_owned_receiver.h)
873function is used to create such a receiver.
874.
875
876``` cpp
877class LoggerImpl : public sample::mojom::Logger {
878 public:
879  LoggerImpl() {}
880  ~LoggerImpl() override {}
881
882  // sample::mojom::Logger:
883  void Log(const std::string& message) override {
884    LOG(ERROR) << "[Logger] " << message;
885  }
886
887 private:
888  // NOTE: This doesn't own any Receiver object!
889};
890
891mojo::Remote<db::mojom::Logger> logger;
892mojo::MakeSelfOwnedReceiver(std::make_unique<LoggerImpl>(),
893                        logger.BindNewPipeAndPassReceiver());
894
895logger->Log("NOM NOM NOM MESSAGES");
896```
897
898Now as long as `logger` remains open somewhere in the system, the bound
899`LoggerImpl` on the other end will remain alive.
900
901### Receiver Sets
902
903Sometimes it's useful to share a single implementation instance with multiple
904clients. [**`ReceiverSet`**](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/receiver_set.h)
905makes this easy. Consider the Mojom:
906
907``` cpp
908module system.mojom;
909
910interface Logger {
911  Log(string message);
912};
913
914interface LoggerProvider {
915  GetLogger(Logger& logger);
916};
917```
918
919We can use `ReceiverSet` to bind multiple `Logger` pending receivers to a single
920implementation instance:
921
922``` cpp
923class LogManager : public system::mojom::LoggerProvider,
924                   public system::mojom::Logger {
925 public:
926  explicit LogManager(mojo::PendingReceiver<system::mojom::LoggerProvider> receiver)
927      : provider_receiver_(this, std::move(receiver)) {}
928  ~LogManager() {}
929
930  // system::mojom::LoggerProvider:
931  void GetLogger(mojo::PendingReceiver<Logger> receiver) override {
932    logger_receivers_.Add(this, std::move(receiver));
933  }
934
935  // system::mojom::Logger:
936  void Log(const std::string& message) override {
937    LOG(ERROR) << "[Logger] " << message;
938  }
939
940 private:
941  mojo::Receiver<system::mojom::LoggerProvider> provider_receiver_;
942  mojo::ReceiverSet<system::mojom::Logger> logger_receivers_;
943};
944
945```
946
947
948### Remote Sets
949
950Similar to the `ReceiverSet` above, sometimes it's useful to maintain a set of
951`Remote`s for *e.g.* a set of clients observing some event.
952[**`RemoteSet`**](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/remote_set.h)
953is here to help. Take the Mojom:
954
955``` cpp
956module db.mojom;
957
958interface TableListener {
959  OnRowAdded(int32 key, string data);
960};
961
962interface Table {
963  AddRow(int32 key, string data);
964  AddListener(pending_remote<TableListener> listener);
965};
966```
967
968An implementation of `Table` might look something like like this:
969
970``` cpp
971class TableImpl : public db::mojom::Table {
972 public:
973  TableImpl() {}
974  ~TableImpl() override {}
975
976  // db::mojom::Table:
977  void AddRow(int32_t key, const std::string& data) override {
978    rows_.insert({key, data});
979    listeners_.ForEach([key, &data](db::mojom::TableListener* listener) {
980      listener->OnRowAdded(key, data);
981    });
982  }
983
984  void AddListener(mojo::PendingRemote<db::mojom::TableListener> listener) {
985    listeners_.Add(std::move(listener));
986  }
987
988 private:
989  mojo::RemoteSet<db::mojom::Table> listeners_;
990  std::map<int32_t, std::string> rows_;
991};
992```
993
994## Associated Interfaces
995
996Associated interfaces are interfaces which:
997
998* enable running multiple interfaces over a single message pipe while
999  preserving message ordering.
1000* make it possible for the receiver to access a single message pipe from
1001  multiple sequences.
1002
1003### Mojom
1004
1005A new keyword `associated` is introduced for remote/receiver
1006fields. For example:
1007
1008``` cpp
1009interface Bar {};
1010
1011struct Qux {
1012  pending_associated_remote<Bar> bar3;
1013};
1014
1015interface Foo {
1016  // Uses associated remote.
1017  SetBar(pending_associated_remote<Bar> bar1);
1018  // Uses associated receiver.
1019  GetBar(pending_associated_receiver<Bar> bar2);
1020  // Passes a struct with associated interface pointer.
1021  PassQux(Qux qux);
1022  // Uses associated interface pointer in callback.
1023  AsyncGetBar() => (pending_associated_remote<Bar> bar4);
1024};
1025```
1026
1027It means the interface impl/client will communicate using the same
1028message pipe over which the associated remote/receiver is
1029passed.
1030
1031### Using associated interfaces in C++
1032
1033When generating C++ bindings, the pending_associated_remote of `Bar` is
1034mapped to `mojo::PendingAssociatedRemote<Bar>`; pending_associated_receiver to
1035`mojo::PendingAssociatedReceiver<Bar>`.
1036
1037``` cpp
1038// In mojom:
1039interface Foo {
1040  ...
1041  SetBar(pending_associated_remote<Bar> bar1);
1042  GetBar(pending_associated_receiver<Bar> bar2);
1043  ...
1044};
1045
1046// In C++:
1047class Foo {
1048  ...
1049  virtual void SetBar(mojo::PendingAssociatedRemote<Bar> bar1) = 0;
1050  virtual void GetBar(mojo::PendingAssociatedReceiver<Bar> bar2) = 0;
1051  ...
1052};
1053```
1054
1055#### Passing pending associated receivers
1056
1057Assume you have already got an `Remote<Foo> foo`, and you would like
1058to call `GetBar()` on it. You can do:
1059
1060``` cpp
1061mojo::PendingAssociatedRemote<Bar> pending_bar;
1062mojo::PendingAssociatedReceiver<Bar> bar_receiver = pending_bar.InitWithNewEndpointAndPassReceiver();
1063foo->GetBar(std::move(bar_receiver));
1064
1065mojo::AssociatedRemote<Bar> bar;
1066bar.Bind(std::move(pending_bar));
1067bar->DoSomething();
1068```
1069
1070First, the code creates an associated interface of type `Bar`. It looks very
1071similar to what you would do to setup a non-associated interface. An
1072important difference is that one of the two associated endpoints (either
1073`bar_receiver` or `pending_bar`) must be sent over another interface. That is
1074how the interface is associated with an existing message pipe.
1075
1076It should be noted that you cannot call `bar->DoSomething()` before passing
1077`bar_receiver`. This is required by the FIFO-ness guarantee: at the receiver
1078side, when the message of `DoSomething` call arrives, we want to dispatch it to
1079the corresponding `AssociatedReceiver<Bar>` before processing any subsequent
1080messages. If `bar_receiver` is in a subsequent message, message dispatching gets
1081into a deadlock. On the other hand, as soon as `bar_receiver` is sent, `bar`
1082is usable. There is no need to wait until `bar_receiver` is bound to an
1083implementation at the remote side.
1084
1085`AssociatedRemote` provides a `BindNewEndpointAndPassReceiver` method
1086to make the code a little shorter. The following code achieves the same purpose:
1087
1088``` cpp
1089mojo::AssociatedRemote<Bar> bar;
1090foo->GetBar(bar.BindNewEndpointAndPassReceiver());
1091bar->DoSomething();
1092```
1093
1094The implementation of `Foo` looks like this:
1095
1096``` cpp
1097class FooImpl : public Foo {
1098  ...
1099  void GetBar(mojo::AssociatedReceiver<Bar> bar2) override {
1100    bar_receiver_.Bind(std::move(bar2));
1101    ...
1102  }
1103  ...
1104
1105  Receiver<Foo> foo_receiver_;
1106  AssociatedReceiver<Bar> bar_receiver_;
1107};
1108```
1109
1110In this example, `bar_receiver_`'s lifespan is tied to that of `FooImpl`. But you
1111don't have to do that. You can, for example, pass `bar2` to another sequence to
1112bind to an `AssociatedReceiver<Bar>` there.
1113
1114When the underlying message pipe is disconnected (e.g., `foo` or
1115`foo_receiver_` is destroyed), all associated interface endpoints (e.g.,
1116`bar` and `bar_receiver_`) will receive a disconnect error.
1117
1118#### Passing associated remotes
1119
1120Similarly, assume you have already got an `Remote<Foo> foo`, and you
1121would like to call `SetBar()` on it. You can do:
1122
1123``` cpp
1124mojo::AssociatedReceiver<Bar> bar_receiver(some_bar_impl);
1125mojo::PendingAssociatedRemote<Bar> bar;
1126mojo::PendingAssociatedReceiver<Bar> bar_pending_receiver = bar.InitWithNewEndpointAndPassReceiver();
1127foo->SetBar(std::move(bar));
1128bar_receiver.Bind(std::move(bar_pending_receiver));
1129```
1130
1131The following code achieves the same purpose:
1132
1133``` cpp
1134mojo::AssociatedReceiver<Bar> bar_receiver(some_bar_impl);
1135mojo::PendingAssociatedRemote<Bar> bar;
1136bar_receiver.Bind(bar.InitWithNewPipeAndPassReceiver());
1137foo->SetBar(std::move(bar));
1138```
1139
1140### Performance considerations
1141
1142When using associated interfaces on different sequences than the master sequence
1143(where the master interface lives):
1144
1145* Sending messages: send happens directly on the calling sequence. So there
1146  isn't sequence hopping.
1147* Receiving messages: associated interfaces bound on a different sequence from
1148  the master interface incur an extra sequence hop during dispatch.
1149
1150Therefore, performance-wise associated interfaces are better suited for
1151scenarios where message receiving happens on the master sequence.
1152
1153### Testing
1154
1155Associated interfaces need to be associated with a master interface before
1156they can be used. This means one end of the associated interface must be sent
1157over one end of the master interface, or over one end of another associated
1158interface which itself already has a master interface.
1159
1160If you want to test an associated interface endpoint without first
1161associating it, you can use `AssociatedRemote::BindNewEndpointAndPassDedicatedReceiverForTesting`.
1162This will create working associated interface endpoints which are not actually
1163associated with anything else.
1164
1165### Read more
1166
1167* [Design: Mojo Associated Interfaces](https://docs.google.com/document/d/1nq3J_HbS-gvVfIoEhcVyxm1uY-9G_7lhD-4Kyxb1WIY/edit)
1168
1169## Synchronous Calls
1170
1171### Think carefully before you decide to use sync calls
1172
1173Although sync calls are convenient, you should avoid them whenever they
1174are not absolutely necessary:
1175
1176* Sync calls hurt parallelism and therefore hurt performance.
1177* Re-entrancy changes message order and produces call stacks that you
1178probably never think about while you are coding. It has always been a
1179huge pain.
1180* Sync calls may lead to deadlocks.
1181
1182### Mojom changes
1183
1184A new attribute `[Sync]` (or `[Sync=true]`) is introduced for methods.
1185For example:
1186
1187``` cpp
1188interface Foo {
1189  [Sync]
1190  SomeSyncCall() => (Bar result);
1191};
1192```
1193
1194It indicates that when `SomeSyncCall()` is called, the control flow of
1195the calling thread is blocked until the response is received.
1196
1197It is not allowed to use this attribute with functions that don’t have
1198responses. If you just need to wait until the service side finishes
1199processing the call, you can use an empty response parameter list:
1200
1201``` cpp
1202[Sync]
1203SomeSyncCallWithNoResult() => ();
1204```
1205
1206### Generated bindings (C++)
1207
1208The generated C++ interface of the Foo interface above is:
1209
1210``` cpp
1211class Foo {
1212 public:
1213  // The service side implements this signature. The client side can
1214  // also use this signature if it wants to call the method asynchronously.
1215  virtual void SomeSyncCall(SomeSyncCallCallback callback) = 0;
1216
1217  // The client side uses this signature to call the method synchronously.
1218  virtual bool SomeSyncCall(BarPtr* result);
1219};
1220```
1221
1222As you can see, the client side and the service side use different
1223signatures. At the client side, response is mapped to output parameters
1224and the boolean return value indicates whether the operation is
1225successful. (Returning false usually means a connection error has
1226occurred.)
1227
1228At the service side, a signature with callback is used. The reason is
1229that in some cases the implementation may need to do some asynchronous
1230work which the sync method’s result depends on.
1231
1232*** note
1233**NOTE:** you can also use the signature with callback at the client side to
1234call the method asynchronously.
1235***
1236
1237### Re-entrancy
1238
1239What happens on the calling thread while waiting for the response of a
1240sync method call? It continues to process incoming sync request messages
1241(i.e., sync method calls); block other messages, including async
1242messages and sync response messages that don’t match the ongoing sync
1243call.
1244
1245![Diagram illustrating sync call flow](/docs/images/mojo_sync_call_flow.png)
1246
1247Please note that sync response messages that don’t match the ongoing
1248sync call cannot re-enter. That is because they correspond to sync calls
1249down in the call stack. Therefore, they need to be queued and processed
1250while the stack unwinds.
1251
1252### Avoid deadlocks
1253
1254Please note that the re-entrancy behavior doesn’t prevent deadlocks
1255involving async calls. You need to avoid call sequences such as:
1256
1257![Diagram illustrating a sync call deadlock](/docs/images/mojo_sync_call_deadlock.png)
1258
1259### Read more
1260
1261* [Design Proposal: Mojo Sync Methods](
1262https://docs.google.com/document/d/1dixzFzZQW8e3ldjdM8Adbo8klXDDE4pVekwo5aLgUsE)
1263
1264## Type Mapping
1265
1266In many instances you might prefer that your generated C++ bindings use a more
1267natural type to represent certain Mojom types in your interface methods. For one
1268example consider a Mojom struct such as the `Rect` below:
1269
1270``` cpp
1271module gfx.mojom;
1272
1273struct Rect {
1274  int32 x;
1275  int32 y;
1276  int32 width;
1277  int32 height;
1278};
1279
1280interface Canvas {
1281  void FillRect(Rect rect);
1282};
1283```
1284
1285The `Canvas` Mojom interface would normally generate a C++ interface like:
1286
1287``` cpp
1288class Canvas {
1289 public:
1290  virtual void FillRect(RectPtr rect) = 0;
1291};
1292```
1293
1294However, the Chromium tree already defines a native
1295[`gfx::Rect`](https://cs.chromium.org/chromium/src/ui/gfx/geometry/rect.h) which
1296is equivalent in meaning but which also has useful helper methods. Instead of
1297manually converting between a `gfx::Rect` and the Mojom-generated `RectPtr` at
1298every message boundary, wouldn't it be nice if the Mojom bindings generator
1299could instead generate:
1300
1301``` cpp
1302class Canvas {
1303 public:
1304  virtual void FillRect(const gfx::Rect& rect) = 0;
1305}
1306```
1307
1308The correct answer is, "Yes! That would be nice!" And fortunately, it can!
1309
1310### Defining `StructTraits`
1311
1312In order to teach generated bindings code how to serialize an arbitrary native
1313type `T` as an arbitrary Mojom type `mojom::U`, we need to define an appropriate
1314specialization of the
1315[`mojo::StructTraits`](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/struct_traits.h)
1316template.
1317
1318A valid specialization of `StructTraits` MUST define the following static
1319methods:
1320
1321* A single static accessor for every field of the Mojom struct, with the exact
1322  same name as the struct field. These accessors must all take a (preferably
1323  const) ref to an object of the native type, and must return a value compatible
1324  with the Mojom struct field's type. This is used to safely and consistently
1325  extract data from the native type during message serialization without
1326  incurring extra copying costs.
1327
1328* A single static `Read` method which initializes an instance of the the native
1329  type given a serialized representation of the Mojom struct. The `Read` method
1330  must return a `bool` to indicate whether the incoming data is accepted
1331  (`true`) or rejected (`false`).
1332
1333There are other methods a `StructTraits` specialization may define to satisfy
1334some less common requirements. See
1335[Advanced StructTraits Usage](#Advanced-StructTraits-Usage) for details.
1336
1337In order to define the mapping for `gfx::Rect`, we want the following
1338`StructTraits` specialization, which we'll define in
1339`//ui/gfx/geometry/mojo/geometry_mojom_traits.h`:
1340
1341``` cpp
1342#include "mojo/public/cpp/bindings/mojom_traits.h"
1343#include "ui/gfx/geometry/rect.h"
1344#include "ui/gfx/geometry/mojo/geometry.mojom.h"
1345
1346namespace mojo {
1347
1348template <>
1349class StructTraits<gfx::mojom::RectDataView, gfx::Rect> {
1350 public:
1351  static int32_t x(const gfx::Rect& r) { return r.x(); }
1352  static int32_t y(const gfx::Rect& r) { return r.y(); }
1353  static int32_t width(const gfx::Rect& r) { return r.width(); }
1354  static int32_t height(const gfx::Rect& r) { return r.height(); }
1355
1356  static bool Read(gfx::mojom::RectDataView data, gfx::Rect* out_rect);
1357};
1358
1359}  // namespace mojo
1360```
1361
1362And in `//ui/gfx/geometry/mojo/geometry_mojom_traits.cc`:
1363
1364``` cpp
1365#include "ui/gfx/geometry/mojo/geometry_mojom_traits.h"
1366
1367namespace mojo {
1368
1369// static
1370bool StructTraits<gfx::mojom::RectDataView, gfx::Rect>::Read(
1371    gfx::mojom::RectDataView data,
1372  gfx::Rect* out_rect) {
1373  if (data.width() < 0 || data.height() < 0)
1374    return false;
1375
1376  out_rect->SetRect(data.x(), data.y(), data.width(), data.height());
1377  return true;
1378};
1379
1380}  // namespace mojo
1381```
1382
1383Note that the `Read()` method returns `false` if either the incoming `width` or
1384`height` fields are negative. This acts as a validation step during
1385deserialization: if a client sends a `gfx::Rect` with a negative width or
1386height, its message will be rejected and the pipe will be closed. In this way,
1387type mapping can serve to enable custom validation logic in addition to making
1388callsites and interface implemention more convenient.
1389
1390When the struct fields have non-primitive types, e.g. string or array,
1391returning a read-only view of the data in the accessor is recommended to
1392avoid copying. It is safe because the input object is guaranteed to
1393outlive the usage of the result returned by the accessor method.
1394
1395The following example uses `StringPiece` to return a view of the GURL's
1396data (`//url/mojom/url_gurl_mojom_traits.h`):
1397
1398``` cpp
1399#include "base/strings/string_piece.h"
1400#include "url/gurl.h"
1401#include "url/mojom/url.mojom.h"
1402#include "url/url_constants.h"
1403
1404namespace mojo {
1405
1406template <>
1407struct StructTraits<url::mojom::UrlDataView, GURL> {
1408  static base::StringPiece url(const GURL& r) {
1409    if (r.possibly_invalid_spec().length() > url::kMaxURLChars ||
1410        !r.is_valid()) {
1411      return base::StringPiece();
1412    }
1413    return base::StringPiece(r.possibly_invalid_spec().c_str(),
1414                             r.possibly_invalid_spec().length());
1415  }
1416}  // namespace mojo
1417```
1418
1419### Enabling a New Type Mapping
1420
1421We've defined the `StructTraits` necessary, but we still need to teach the
1422bindings generator (and hence the build system) about the mapping. To do this we
1423must add some more information to our `mojom` target in GN:
1424
1425```
1426# Without a typemap
1427mojom("mojom") {
1428  sources = [
1429    "rect.mojom",
1430  ]
1431}
1432
1433# With a typemap.
1434mojom("mojom") {
1435  sources = [
1436    "rect.mojom",
1437  ]
1438
1439  cpp_typemaps = [
1440    {
1441      # NOTE: A single typemap entry can list multiple individual type mappings.
1442      # Each mapping assumes the same values for |traits_headers| etc below.
1443      #
1444      # To typemap a type with separate |traits_headers| etc, add a separate
1445      # entry to |cpp_typemaps|.
1446      types = [
1447        {
1448          mojom = "gfx.mojom.Rect"
1449          cpp = "::gfx::Rect"
1450        },
1451      ]
1452      traits_headers = [ "//ui/gfx/geometry/mojo/geometry_mojom_traits.h" ]
1453      traits_sources = [ "//ui/gfx/geometry/mojo/geometry_mojom_traits.cc" ]
1454      traits_public_deps = [ "//ui/gfx/geometry" ]
1455    },
1456  ]
1457}
1458```
1459
1460See typemap documentation in
1461[mojom.gni](https://cs.chromium.org/chromium/src/mojo/public/tools/bindings/mojom.gni)
1462for details on the above definition and other supported parameters.
1463
1464With this extra configuration present, any mojom references to `gfx.mojom.Rect`
1465(e.g. for method parameters or struct fields) will be `gfx::Rect` references in
1466generated C++ code.
1467```
1468
1469For the Blink variant of bindings, add to the `blink_cpp_typemaps` list instead.
1470
1471### Type Mapping Without `traits_sources`
1472
1473Using `traits_sources` in a typemap configuration means that the listed sources
1474will be baked directly into the corresponding `mojom` target's own sources. This
1475can be problematic if you want to use the same typemap for both Blink and
1476non-Blink bindings.
1477
1478For such cases, it is recommended that you define a separate `component` target
1479for your typemap traits, and reference this in the `traits_public_deps` of the
1480typemap:
1481
1482```
1483mojom("mojom") {
1484  sources = [
1485    "rect.mojom",
1486  ]
1487
1488  cpp_typemaps = [
1489    {
1490      types = [
1491        {
1492          mojom = "gfx.mojom.Rect"
1493          cpp = "::gfx::Rect"
1494        },
1495      ]
1496      traits_headers = [ "//ui/gfx/geometry/mojo/geometry_mojom_traits.h" ]
1497      traits_public_deps = [ ":geometry_mojom_traits" ]
1498    },
1499  ]
1500}
1501
1502component("geometry_mojom_traits") {
1503  sources = [
1504    "//ui/gfx/geometry/mojo/geometry_mojom_traits.cc",
1505    "//ui/gfx/geometry/mojo/geometry_mojom_traits.h",
1506  ]
1507
1508  # The header of course needs corresponding COMPONENT_EXPORT() tags.
1509  defines = [ "IS_GEOMETRY_MOJOM_TRAITS_IMPL" ]
1510}
1511```
1512
1513### StructTraits Reference
1514
1515Each of a `StructTraits` specialization's static getter methods -- one per
1516struct field -- must return a type which can be used as a data source for the
1517field during serialization. This is a quick reference mapping Mojom field type
1518to valid getter return types:
1519
1520| Mojom Field Type             | C++ Getter Return Type |
1521|------------------------------|------------------------|
1522| `bool`                       | `bool`
1523| `int8`                       | `int8_t`
1524| `uint8`                      | `uint8_t`
1525| `int16`                      | `int16_t`
1526| `uint16`                     | `uint16_t`
1527| `int32`                      | `int32_t`
1528| `uint32`                     | `uint32_t`
1529| `int64`                      | `int64_t`
1530| `uint64`                     | `uint64_t`
1531| `float`                      | `float`
1532| `double`                     | `double`
1533| `handle`                     | `mojo::ScopedHandle`
1534| `handle<message_pipe>`       | `mojo::ScopedMessagePipeHandle`
1535| `handle<data_pipe_consumer>` | `mojo::ScopedDataPipeConsumerHandle`
1536| `handle<data_pipe_producer>` | `mojo::ScopedDataPipeProducerHandle`
1537| `handle<shared_buffer>`      | `mojo::ScopedSharedBufferHandle`
1538| `pending_remote<Foo>`        | `mojo::PendingRemote<Foo>`
1539| `pending_receiver<Foo>`      | `mojo::PendingReceiver<Foo>`
1540| `pending_associated_remote<Foo>`    | `mojo::PendingAssociatedRemote<Foo>`
1541| `pending_associated_receiver<Foo>`    | `mojo::PendingAssociatedReceiver<Foo>`
1542| `string`                     | Value or reference to any type `T` that has a `mojo::StringTraits` specialization defined. By default this includes `std::string`, `base::StringPiece`, and `WTF::String` (Blink).
1543| `array<T>`                   | Value or reference to any type `T` that has a `mojo::ArrayTraits` specialization defined. By default this includes `std::vector<T>`, `mojo::CArray<T>`, and `WTF::Vector<T>` (Blink).
1544| `map<K, V>`                  | Value or reference to any type `T` that has a `mojo::MapTraits` specialization defined. By default this includes `std::map<T>`, `mojo::unordered_map<T>`, and `WTF::HashMap<T>` (Blink).
1545| `FooEnum`                    | Value of any type that has an appropriate `EnumTraits` specialization defined. By default this inlcudes only the generated `FooEnum` type.
1546| `FooStruct`                  | Value or reference to any type that has an appropriate `StructTraits` specialization defined. By default this includes only the generated `FooStructPtr` type.
1547| `FooUnion`                   | Value of reference to any type that has an appropriate `UnionTraits` specialization defined. By default this includes only the generated `FooUnionPtr` type.
1548| `Foo?`                       | `base::Optional<CppType>`, where `CppType` is the value type defined by the appropriate traits class specialization (e.g. `StructTraits`, `mojo::MapTraits`, etc.). This may be customized by the [typemapping](#Enabling-a-New-Type-Mapping).
1549
1550### Using Generated DataView Types
1551
1552Static `Read` methods on `StructTraits` specializations get a generated
1553`FooDataView` argument (such as the `RectDataView` in the example above) which
1554exposes a direct view of the serialized Mojom structure within an incoming
1555message's contents. In order to make this as easy to work with as possible, the
1556generated `FooDataView` types have a generated method corresponding to every
1557struct field:
1558
1559* For POD field types (*e.g.* bools, floats, integers) these are simple accessor
1560  methods with names identical to the field name. Hence in the `Rect` example we
1561  can access things like `data.x()` and `data.width()`. The return types
1562  correspond exactly to the mappings listed in the table above, under
1563  [StructTraits Reference](#StructTraits-Reference).
1564
1565* For handle and interface types (*e.g* `handle` or `pending_remote<Foo>`) these
1566  are named `TakeFieldName` (for a field named `field_name`) and they return an
1567  appropriate move-only handle type by value. The return types correspond
1568  exactly to the mappings listed in the table above, under
1569  [StructTraits Reference](#StructTraits-Reference).
1570
1571* For all other field types (*e.g.*, enums, strings, arrays, maps, structs)
1572  these are named `ReadFieldName` (for a field named `field_name`) and they
1573  return a `bool` (to indicate success or failure in reading). On success they
1574  fill their output argument with the deserialized field value. The output
1575  argument may be a pointer to any type with an appropriate `StructTraits`
1576  specialization defined, as mentioned in the table above, under
1577  [StructTraits Reference](#StructTraits-Reference).
1578
1579An example would be useful here. Suppose we introduced a new Mojom struct:
1580
1581``` cpp
1582struct RectPair {
1583  Rect left;
1584  Rect right;
1585};
1586```
1587
1588and a corresponding C++ type:
1589
1590``` cpp
1591class RectPair {
1592 public:
1593  RectPair() {}
1594
1595  const gfx::Rect& left() const { return left_; }
1596  const gfx::Rect& right() const { return right_; }
1597
1598  void Set(const gfx::Rect& left, const gfx::Rect& right) {
1599    left_ = left;
1600    right_ = right;
1601  }
1602
1603  // ... some other stuff
1604
1605 private:
1606  gfx::Rect left_;
1607  gfx::Rect right_;
1608};
1609```
1610
1611Our traits to map `gfx::mojom::RectPair` to `gfx::RectPair` might look like
1612this:
1613
1614``` cpp
1615namespace mojo {
1616
1617template <>
1618class StructTraits
1619 public:
1620  static const gfx::Rect& left(const gfx::RectPair& pair) {
1621    return pair.left();
1622  }
1623
1624  static const gfx::Rect& right(const gfx::RectPair& pair) {
1625    return pair.right();
1626  }
1627
1628  static bool Read(gfx::mojom::RectPairDataView data, gfx::RectPair* out_pair) {
1629    gfx::Rect left, right;
1630    if (!data.ReadLeft(&left) || !data.ReadRight(&right))
1631      return false;
1632    out_pair->Set(left, right);
1633    return true;
1634  }
1635}  // namespace mojo
1636```
1637
1638Generated `ReadFoo` methods always convert `multi_word_field_name` fields to
1639`ReadMultiWordFieldName` methods.
1640
1641<a name="Blink-Type-Mapping"></a>
1642### Variants
1643
1644By now you may have noticed that additional C++ sources are generated when a
1645Mojom is processed. These exist due to type mapping, and the source files we
1646refer to throughout this docuemnt (namely `foo.mojom.cc` and `foo.mojom.h`) are
1647really only one **variant** (the *default* or *chromium* variant) of the C++
1648bindings for a given Mojom file.
1649
1650The only other variant currently defined in the tree is the *blink* variant,
1651which produces a few additional files:
1652
1653```
1654out/gen/sample/db.mojom-blink.cc
1655out/gen/sample/db.mojom-blink.h
1656```
1657
1658These files mirror the definitions in the default variant but with different
1659C++ types in place of certain builtin field and parameter types. For example,
1660Mojom strings are represented by `WTF::String` instead of `std::string`. To
1661avoid symbol collisions, the variant's symbols are nested in an extra inner
1662namespace, so Blink consumer of the interface might write something like:
1663
1664```
1665#include "sample/db.mojom-blink.h"
1666
1667class TableImpl : public db::mojom::blink::Table {
1668 public:
1669  void AddRow(int32_t key, const WTF::String& data) override {
1670    // ...
1671  }
1672};
1673```
1674
1675In addition to using different C++ types for builtin strings, arrays, and maps,
1676the custom typemaps applied to Blink bindings are managed separately from
1677regular bindings.
1678
1679`mojom` targets support a `blink_cpp_typemaps` parameter in addition to the
1680regular `cpp_typemaps`. This lists the typemaps to apply to Blink bindings.
1681
1682To depend specifically on generated Blink bindings, reference
1683`${target_name}_blink`. So for example, with the definition:
1684
1685```
1686# In //foo/mojom
1687mojom("mojom") {
1688  sources = [
1689    "db.mojom",
1690  ]
1691}
1692```
1693
1694C++ sources can depend on the Blink bindings by depending on
1695`"//foo/mojom:mojom_blink"`.
1696
1697Finally note that both bindings variants share some common definitions which are
1698unaffected by differences in the type-mapping configuration (like enums, and
1699structures describing serialized object formats). These definitions are
1700generated in *shared* sources:
1701
1702```
1703out/gen/sample/db.mojom-shared.cc
1704out/gen/sample/db.mojom-shared.h
1705out/gen/sample/db.mojom-shared-internal.h
1706```
1707
1708Including either variant's header (`db.mojom.h` or `db.mojom-blink.h`)
1709implicitly includes the shared header, but may wish to include *only* the shared
1710header in some instances.
1711
1712C++ sources can depend on shared sources only, by referencing the
1713`"${target_name}_shared"` target, e.g. `"//foo/mojom:mojom_shared"` in the
1714example above.
1715
1716## Versioning Considerations
1717
1718For general documentation of versioning in the Mojom IDL see
1719[Versioning](/mojo/public/tools/bindings/README.md#Versioning).
1720
1721This section briefly discusses some C++-specific considerations relevant to
1722versioned Mojom types.
1723
1724### Querying Interface Versions
1725
1726`Remote` defines the following methods to query or assert remote interface
1727version:
1728
1729```cpp
1730void QueryVersion(base::OnceCallback<void(uint32_t)> callback);
1731```
1732
1733This queries the remote endpoint for the version number of its binding. When a
1734response is received `callback` is invoked with the remote version number. Note
1735that this value is cached by the `Remote` instance to avoid redundant
1736queries.
1737
1738```cpp
1739void RequireVersion(uint32_t version);
1740```
1741
1742Informs the remote endpoint that a minimum version of `version` is required by
1743the client. If the remote endpoint cannot support that version, it will close
1744its end of the pipe immediately, preventing any other requests from being
1745received.
1746
1747### Versioned Enums
1748
1749For convenience, every extensible enum has a generated helper function to
1750determine whether a received enum value is known by the implementation's current
1751version of the enum definition. For example:
1752
1753```cpp
1754[Extensible]
1755enum Department {
1756  SALES,
1757  DEV,
1758  RESEARCH,
1759};
1760```
1761
1762generates the function in the same namespace as the generated C++ enum type:
1763
1764```cpp
1765inline bool IsKnownEnumValue(Department value);
1766```
1767
1768### Using Mojo Bindings in Chrome
1769
1770See [Converting Legacy Chrome IPC To Mojo](/docs/mojo_ipc_conversion.md).
1771
1772### Additional Documentation
1773
1774[Calling Mojo From Blink](/docs/mojo_ipc_conversion.md#Blink_Specific-Advice):
1775A brief overview of what it looks like to use Mojom C++ bindings from
1776within Blink code.
1777