G# Low-level C++ language FIDL tutorial

[TOC]

## About this tutorial

This tutorial describes how to make client calls and write servers in C++
using the Low-Level C++ Bindings (LLCPP).

[Getting Started](#getting-started) has a walk-through of using the bindings
with an example FIDL library. The [reference](#reference) section documents
the detailed bindings interface and design.

See [Comparing C, Low-Level C++, and High-Level C++ Language
Bindings][c-family-comparison] for a comparative analysis of the goals and
use cases for all the C-family language bindings.

Note: LLCPP is in currently in beta. The bindings are designed to exploit the
compatibility between FIDL wire-format and C++ memory layouts, and offer
precise control over allocation. As such, viewers are encouraged to
familiarize themselves with the [C Language Bindings](tutorial-c.md#reference)
and the [FIDL wire-format][wire-format]. Parts of this
tutorial assume knowledge of these related concepts.

# Getting started

Two build setups exist in the source tree: the Zircon build and the Fuchsia
build. The LLCPP code generator is not supported by the Zircon build. Therefore,
the steps to use the bindings depend on where the consumer code is located:

*   **Code is outside `zircon/`:**
    Add `//[library path]:[library name]_llcpp` to the GN dependencies e.g.
    `"//sdk/fidl/fuchsia.math:fuchsia.math_llcpp"`, and the bindings code
    will be automatically generated as part of the build.
*   **Code is inside `zircon/`:**
    Add a GN dependency of the form: `"$zx/system/fidl/[library-name]:llcpp"`,
    e.g. `"$zx/system/fidl/fuchsia-mem:llcpp"`, and the bindings code will be
    automatically generated as part of the build.

## Preliminary concepts

*   **Decoded message:**
    A FIDL message in [decoded form][wire-format-decoded]
    is a contiguous buffer that is directly accessible by reinterpreting the
    memory as the corresponding LLCPP FIDL type. That is, all pointers point
    within the same buffer, and the pointed objects are in a specific order
    defined by the FIDL wire-format. When making a call, a response buffer is
    used to decode the response message.

*   **Encoded message:**
    A FIDL message in [encoded form][wire-format-encoded]
    is an opaque contiguous buffer plus an array of handles. The buffer is
    of the same length as the decoded counterpart, but pointers are replaced
    with placeholders, and handles are moved to the accompanying array.
    When making a call, a request buffer is used to encode the request message.

*   **Message linearization:**
    FIDL messages have to be in a contiguous buffer packed according to the
    wire-format. When making a call however, the arguments to the bindings code
    and out-of-line objects are usually scattered in memory, unless careful
    attention is spent to follow the wire-format order. The process of walking
    down the tree of objects and packing them is termed *linearization*, and
    usually involves `O(message size)` copying.

*   **Message layout:**
    The in-memory layout of LLCPP structures is the same as the layout of the
    wire format. The LLCPP objects can be thought of as a view over the
    encoded message..

*   **Message ownership:**
    LLCPP objects use [`tracking_ptr`](#Pointers-and-memory-ownership) smart
    pointers to manage ownership and track whether an object is heap allocated
    and owned or user-managed and unowned.

## Generated API overview

Low-Level C++ bindings are full featured, and support control over allocation as
well as zero-copy encoding/decoding. (Note that contrary to the C bindings they
are meant to replace, the LLCPP bindings cover non-simple messages.)

Let's use this FIDL protocol as a motivating example:

```fidl
// fleet.fidl
library fuchsia.fleet;

struct Planet {
    string name;
    float64 mass;
    handle<channel> radio;
};
```

The following code is generated (simplified for readability):

```cpp
// fleet.h
struct Planet {
  fidl::StringView name;
  double mass;
  zx::channel radio;
};
```

Note that `string` maps to `fidl::StringView`, hence the `Planet` struct
will not own the memory associated with the `name` string. Rather, all strings
point within some buffer space that is managed by the bindings library, or that
the caller could customize. The same goes for the `fidl::VectorView<Planet>`
in the code below.

Continuing with the FIDL protocol:

```fidl
// fleet.fidl continued...
protocol SpaceShip {
    SetHeading(int16 heading);
    ScanForPlanets() -> (vector<Planet> planets);
    DirectedScan(int16 heading) -> (vector<Planet> planets);
    -> OnBeacon(int16 heading);
};
```

The following code is generated (simplified for readability):

```cpp
// fleet.h continued...
class SpaceShip final {
 public:
  struct SetHeadingRequest final {
    fidl_message_header_t _hdr;
    int16_t heading;
  };

  struct ScanForPlanetsResponse final {
    fidl_message_header_t _hdr;
    fidl::VectorView<Planet> planets;
  };
  using ScanForPlanetsRequest = fidl::AnyZeroArgMessage;

  struct DirectedScanRequest final {
    fidl_message_header_t _hdr;
    int16_t heading;
  };
  struct DirectedScanResponse final {
    fidl_message_header_t _hdr;
    fidl::VectorView<Planet> planets;
  };

  class SyncClient final { /* ... */ };
  class Call final { /* ... */ };
  class Interface { /* ... */ };

  static bool TryDispatch(Interface* impl, fidl_msg_t* msg, fidl::Transaction* txn);
  static bool Dispatch(Interface* impl, fidl_msg_t* msg, fidl::Transaction* txn);

  class ResultOf final { /* ... */ };
  class UnownedResultOf final { /* ... */ };
  class InPlace final { /* ... */ };

  // Generated classes for thread-safe async-capable client.
  struct AsyncEventHandlers {
    std::variant<fit::callback<void(int16_t)>,
                 fit::callback<void(fidl::DecodedMessage<OnBeaconResponse>)>>
        on_beacon;
  };
  class ScanForPlanetsResponseContext { /* ... */ };
  class DirectedScanResponseContext { /* ... */ };
  class ClientImpl { /* ... */ };
};
```

Notice that every request and response is modelled as a `struct`:
`SetHeadingRequest`, `ScanForPlanetsResponse`, etc.
In particular, `ScanForPlanets()` has a request that contains no arguments, and
we provide a special type for that, `fidl::AnyZeroArgMessage`.

Following those, there are three related concepts in the generated code:

+ [`SyncClient`](#sync-client): A class that owns a Zircon channel, providing
  methods to make requests to the FIDL server.
+ [`Call`](#static-functions): A class that contains static functions to make
  sync FIDL calls directly on an unowned channel, avoiding setting up a
  `SyncClient`. This is similar to the simple client wrappers from the C
  bindings, which take a `zx_handle_t`.
+ `Interface` and `[Try]Dispatch`: A server should implement the `Interface`
  pure virtual class, which allows `Dispatch` to call one of the defined
  handlers with a received FIDL message.

[`[Unowned]ResultOf`](#resultof-and-unownedresultof) are "scoping" classes
containing return type definitions of FIDL calls inside `SyncClient` and `Call`.
This allows one to conveniently write `ResultOf::SetHeading` to denote the
result of calling `SetHeading`.

[`InPlace`](#in_place-calls) is another "scoping" class that houses functions
to make a FIDL call with encoding and decoding performed in-place directly on
the user buffer. It is more efficient than those `SyncClient` or `Call`, but
comes with caveats. We will dive into these separately.

## Client API

### Sync client `(Protocol::SyncClient)`

The following code is generated for `SpaceShip::SyncClient`. Each FIDL method
always correspond to two overloads which differ in memory management strategies,
termed *flavors* in LLCPP: *managed flavor* and *caller-allocating flavor*.

```cpp
class SyncClient final {
 public:
  SyncClient(zx::channel channel);

  // FIDL: SetHeading(int16 heading);
  ResultOf::SetHeading SetHeading(int16_t heading);
  UnownedResultOf::SetHeading SetHeading(fidl::BytePart request_buffer, int16_t heading);

  // FIDL: ScanForPlanets() -> (vector<Planet> planets);
  ResultOf::ScanForPlanets ScanForPlanets();
  UnownedResultOf::ScanForPlanets ScanForPlanets(fidl::BytePart response_buffer);

  // FIDL: DirectedScan(int16 heading) -> (vector<Planet> planets);
  ResultOf::DirectedScan DirectedScan(int16_t heading);
  UnownedResultOf::DirectedScan DirectedScan(fidl::BytePart request_buffer, int16_t heading,
                                             fidl::BytePart response_buffer);
};
```

The one-way FIDL method `SetHeading(int16 heading)` maps to:

+ `ResultOf::SetHeading SetHeading(int16_t heading)`:
This is the *managed flavor*.
Buffer allocation for requests and responses are entirely handled within this
function, as is the case in simple C bindings. The bindings calculate a safe
buffer size specific to this call at compile time based on FIDL wire-format and
maximum length constraints. The buffers are allocated on the stack if they fit
under 512 bytes, or else on the heap. Here is an example of using it:

```cpp
// Create a client from a Zircon channel.
SpaceShip::SyncClient client(zx::channel(client_end));

// Calling |SetHeading| with heading = 42.
SpaceShip::ResultOf::SetHeading result = client.SetHeading(42);

// Check the transport status (encoding error, channel writing error, etc.)
if (result.status() != ZX_OK) {
  // Handle error...
}
```

In general, the managed flavor is easier to use, but may result in extra
allocation. See [ResultOf](#resultof-and-unownedresultof) for details on buffer
management.

+ `UnownedResultOf::SetHeading SetHeading(fidl::BytePart request_buffer, int16_t heading)`:
This is the *caller-allocating flavor*, which defers all memory allocation
responsibilities to the caller.
Here we see an additional parameter `request_buffer` which is always the first
argument in this flavor. The type `fidl::BytePart` references a buffer address
and size. It will be used by the bindings library to construct the FIDL request,
hence it must be sufficiently large.
The method parameters (e.g. `heading`) are *linearized* to appropriate locations
within the buffer. If `SetHeading` had a return value, this flavor would ask for
a `response_buffer` too, as the last argument. Here is an example of using it:

```cpp
// Call SetHeading with an explicit buffer, there are multiple ways...

// 1. On the stack
fidl::Buffer<SetHeadingRequest> request_buffer;
auto result = client.SetHeading(request_buffer.view(), 42);

// 2. On the heap
auto request_buffer = std::make_unique<fidl::Buffer<SetHeadingRequest>>();
auto result = client.SetHeading(request_buffer->view(), 42);

// 3. Some other means, e.g. thread-local storage
constexpr uint32_t request_size = fidl::MaxSizeInChannel<SetHeadingRequest>();
uint8_t* buffer = allocate_buffer_of_size(request_size);
fidl::BytePart request_buffer(/* data = */buffer, /* capacity = */request_size);
auto result = client.SetHeading(std::move(request_buffer), 42);

// Check the transport status (encoding error, channel writing error, etc.)
if (result.status() != ZX_OK) {
  // Handle error...
}

// Don't forget to free the buffer at the end if approach #3 was used...
```

> When the caller-allocating flavor is used, the `result` object borrows the
> request and response buffers (hence its type is under `UnownedResultOf`).
> Make sure the buffers outlive the `result` object.
> See [UnownedResultOf](#resultof-and-unownedresultof).

Caution: Buffers passed to the bindings must be aligned to 8 bytes. The
`fidl::Buffer` helper class does this automatically. Failure to align would
result in a run-time error.

* * * *

The two-way FIDL method
`ScanForPlanets() -> (vector<Planet> planets)` maps to:

+ `ResultOf::ScanForPlanets ScanForPlanets()`:
This is the *managed flavor*. Different from the C bindings, response arguments
are not returned via out-parameters. Instead, they are accessed through the
return value. Here is an example to illustrate:

```cpp
// It is cleaner to omit the |UnownedResultOf::ScanForPlanets| result type.
auto result = client.ScanForPlanets();

// Check the transport status (encoding error, channel writing error, etc.)
if (result.status() != ZX_OK) {
  // handle error & early exit...
}

// Obtains a pointer to the response struct inside |result|.
// This requires that the transport status is |ZX_OK|.
SpaceShip::ScanForPlanetsResponse* response = result.Unwrap();

// Access the |planets| response vector in the FIDL call.
for (const auto& planet : response->planets) {
  // Do something with |planet|...
}
```

> When the managed flavor is used, the returned object (`result` in this
> example) manages ownership of all buffer and handles, while `result.Unwrap()`
> returns a view over it. Therefore, the `result` object must outlive any
> references to the response.

+ `UnownedResultOf::ScanForPlanets ScanForPlanets(fidl::BytePart response_buffer)`:
The *caller-allocating flavor* receives the message into `response_buffer`.
Here is an example using it:

```cpp
fidl::Buffer<ScanForPlanetsResponse> response_buffer;
auto result = client.ScanForPlanets(response_buffer.view());
if (result.status() != ZX_OK) { /* ... */ }
auto response = result.Unwrap();
// |response->planets| points to a location within |response_buffer|.
```

> The buffers passed to caller-allocating flavor do not have to be initialized.
> A buffer may be re-used multiple times, as long as it is large enough for
> the calls involved.

Note: Since each `Planet` has a handle `zx::channel radio`, and the
`fidl::VectorView<Planet>` type does not own the individual `Planet` objects,
there needs to be a reliable way to capture the lifetime of those handles.
Here the return value `result` owns them, and takes care of closing them when
it goes out of scope.
If any handle is `std::move`ed away, `result` would not accidentally close it.

### Async-capable Client (`fidl::Client<Protocol>`)

This client is thread-safe and supports both synchronous and asynchronous calls
as well as asynchronous event handling. It also supports use with a
multi-threaded dispatcher.

#### Creation

A client is created with a client-end `zx::channel`, an `async_dispatcher_t*`,
an optional hook (`OnClientUnboundFn`) to be invoked when the channel is
unbound, and an optional `AsyncEventHandlers` containing hooks to
be invoked on FIDL events.

```cpp
Client<SpaceShip> client;
zx_status_t status = client.Bind(
    std::move(client_end), dispatcher,
    // OnClientUnboundFn
    [&](fidl::UnboundReason, zx_status_t, zx::channel) { /* ... */ },
    // AsyncEventHandlers
    { .on_beacon = [&](int16_t) { /* ... */ } });
```

#### Unbinding

The channel may be unbound automatically in case of the server-end being closed
or due to an invalid message being received from the server. You may also
actively unbind the channel through `client.Unbind()`.

Unbinding is thread-safe. In any of these cases, ongoing and future operations
will not cause a fatal failure, only returning `ZX_ERR_CANCELED` where
appropriate.

If you provided an unbound hook, it is executed as task on the dispatcher,
providing a reason and error status for the unbinding. You may also recover
ownership of the client end of the channel through the hook. The unbound hook is
guaranteed to be run.

#### Interaction with dispatcher

All asynchronous responses, event handling, and error handling are done through
the `async_dispatcher_t*` provided on creation of a client. With the exception
of the dispatcher being shutdown, you can expect that all hooks provided to the
client APIs will be executed on a dispatcher thread (and not nested within other
user code).

NOTE: If you shutdown the dispatcher while there are any active bindings, the
unbound hook MAY be executed on the thread executing shutdown. As such, you MUST
not take any locks which could be taken by hooks provided to `fidl::Client` APIs
while executing `async::Loop::Shutdown()/async_loop_shutdown()`. (You should
probably ensure that no locks are held around shutdown anyway since it joins all
dispatcher threads, which may take locks in user code).

#### Outgoing FIDL methods

You can invoke outgoing FIDL APIs through the `fidl::Client<SpaceShip>`
instance, e.g. `client->SetHeading(0)`. The full generated API is given below:

```cpp
class ClientImpl final {
 public:
  fidl::StatusAndError SetHeading(int16_t heading);
  fidl::StatusAndError SetHeading(fidl::BytePart _request_buffer,
                                  int16_t heading);

  fidl::StatusAndError ScanForPlanets(
      fit::callback<void(fidl::VectorView<Planet> planets)> _cb);
  fidl::StatusAndError ScanForPlanets(ScanForPlanetsResponseContext* _context);
  ResultOf::ScanForPlanets ScanForPlanets_Sync(int16_t heading);
  UnownedResultOf::ScanForPlanets ScanForPlanets_Sync(
      fidl::BytePart _response_buffer, int16_t heading);

  fidl::StatusAndError DirectedScan(fit::callback<void(fidl::VectorView<Planet> planets)> _cb);
  fidl::StatusAndError DirectedScan(DirectedScanResponseContext* _context);
  ResultOf::DirectedScan DirectedScan_Sync(int16_t heading);
  UnownedResultOf::DirectedScan DirectedScan_Sync(
      fidl::BytePart _request_buffer, int16_t heading,
      fidl::BytePart _response_buffer);
};
```

Note that the one-way and synchronous two-way FIDL methods have a similar API to
the `SyncClient` versions. Aside from one-way methods directly returning
`fidl::StatusAndError` and the added `_Sync` on the synchronous methods, the
behavior is identical.

##### Asynchronous APIs

The *managed* flavor of the asynchronous two-way APIs simply takes a
`fit::callback` hook which is executed on response in a dispatcher thread. The
returned `fidl::StatusAndError` refers just to the status of the outgoing call.

```cpp
auto status = client->DirectedScan(0, [&]{ /* ... */ });
```

The *caller-allocated* flavor enables you to provide the storage for the
callback as well as any associated state. This is done through the generated
virtual `ResponseContext` classes:

```cpp
class DirectedScanResponseContext : public fidl::internal::ResponseContext {
 public:
  virtual void OnReply(fidl::DecodedMessage<DirectedScanResponse> msg) = 0;
};
```

You can derive from this class, implementing `OnReply()` and `OnError()`
(inherited from `fidl::internal::ResponseContext`). You can then allocate an
object of this type as required, passing a pointer to it to the API. The object
must stay alive until either `OnReply()` or `OnError()` is invoked by the
`Client`.

NOTE: If the `Client` is destroyed with outstanding asynchronous transactions,
`OnError()` will be invoked for all of the associated `ResponseContext`s.

### Static functions `(Protocol::Call)`

The following code is generated for `SpaceShip::Call`:

```cpp
class Call final {
 public:
  static ResultOf::SetHeading
  SetHeading(zx::unowned_channel client_end, int16_t heading);
  static UnownedResultOf::SetHeading
  SetHeading(zx::unowned_channel client_end, fidl::BytePart request_buffer, int16_t heading);

  static ResultOf::ScanForPlanets
  ScanForPlanets(zx::unowned_channel client_end);
  static UnownedResultOf::ScanForPlanets
  ScanForPlanets(zx::unowned_channel client_end, fidl::BytePart response_buffer);

  static ResultOf::DirectedScan
  DirectedScan(zx::unowned_channel client_end, int16_t heading);
  static UnownedResultOf::DirectedScan
  DirectedScan(zx::unowned_channel client_end, fidl::BytePart request_buffer, int16_t heading,
               fidl::BytePart response_buffer);
};
```

These methods are similar to those found in `SyncClient`. However, they do not
own the channel. This is useful if one is migrating existing code from the
C bindings to low-level C++. Another use case is when implementing C APIs
which take a raw `zx_handle_t`. For example:

```cpp
// C interface which does not own the channel.
zx_status_t spaceship_set_heading(zx_handle_t spaceship, int16_t heading) {
  auto result = fuchsia::fleet::SpaceShip::Call::SetHeading(
      zx::unowned_channel(spaceship), heading);
  return result.status();
}
```

### ResultOf and UnownedResultOf

For a method named `Foo`, `ResultOf::Foo` is the return type of the *managed
flavor*. `UnownedResultOf::Foo` is the return type of the *caller-allocating
flavor*. Both types define the same set of methods:

*   `zx_status status() const` returns the transport status. it returns the
    first error encountered during (if applicable) linearizing, encoding, making
    a call on the underlying channel, and decoding the result.
    If the status is `ZX_OK`, the call has succeeded, and vice versa.
*   `const char* error() const` contains a brief error message when status is
    not `ZX_OK`. Otherwise, returns `nullptr`.
*   **(only for two-way calls)** `FooResponse* Unwrap()` returns a pointer
    to the FIDL response message. For `ResultOf::Foo`, the pointer points to
    memory owned by the result object. For `UnownedResultOf::Foo`, the pointer
    points to a caller-provided buffer. `Unwrap()` should only be called when
    the status is `ZX_OK`.

#### Allocation strategy And move semantics

`ResultOf::Foo` stores the response buffer inline if the message is guaranteed
to fit under 512 bytes. Since the result object is usually instantiated on the
caller's stack, this effectively means the response is stack-allocated when it
is reasonably small. If the maximal response size exceeds 512 bytes,
`ResultOf::Foo` instead contains a `std::unique_ptr` to a heap-allocated buffer.

Therefore, a `std::move()` on `ResultOf::Foo` may be costly if the response
buffer is inline: the content has to be copied, and pointers to out-of-line
objects have to be updated to locations within the destination object.
Consider the following snippet:

```cpp
int CountPlanets(ResultOf::ScanForPlanets result) { /* ... */ }

auto result = client.ScanForPlanets();
SpaceShip::ScanForPlanetsResponse* response = result.Unwrap();
Planet* planet = &response->planets[0];
int count = CountPlanets(std::move(result));    // Costly
// In addition, |response| and |planet| are invalidated due to the move
```

It may be written more efficiently as:

```cpp
int CountPlanets(fidl::VectorView<SpaceShip::Planet> planets) { /* ... */ }

auto result = client.ScanForPlanets();
int count = CountPlanets(result.Unwrap()->planets);
```

> If the result object need to be passed around multiple function calls,
> consider pre-allocating a buffer in the outer-most function and use the
> caller-allocating flavor.

### In-place calls {#inplace}

Both the *managed flavor* and the *caller-allocating flavor* will copy the
arguments into the request buffer. When there is out-of-line data involved,
*message linearization* is additionally required to collate them as per the
wire-format. When the request is large, these copying overhead can add up.
LLCPP supports making a call directly on a caller-provided buffer containing
a request message in decoded form, without any parameter copying. The request
is encoded in-place, hence the name of the scoping class `InPlace`.

```cpp
class InPlace final {
 public:
  static ::fidl::internal::StatusAndError
  SetHeading(zx::unowned_channel client_end,
             fidl::DecodedMessage<SetHeadingRequest> params);

  static ::fidl::DecodeResult<ScanForPlanets>
  ScanForPlanets(zx::unowned_channel client_end,
                 fidl::DecodedMessage<ScanForPlanetsRequest> params,
                 fidl::BytePart response_buffer);

  static ::fidl::DecodeResult<DirectedScan>
  DirectedScan(zx::unowned_channel client_end,
               fidl::DecodedMessage<DirectedScanRequest> params,
               fidl::BytePart response_buffer);
};
```

These functions always take a
[`fidl::DecodedMessage<FooRequest>`](#fidl_decodedmessage_t) which wraps the
user-provided buffer. To use it properly, initialize the request buffer with a
FIDL message in decoded form. *In particular, out-of-line objects have to be
packed according to the wire-format, and therefore any pointers in the message
have to point within the same buffer.*

When there is a response defined, the generated functions additionally ask for a
`response_buffer` as the last argument. The response buffer does not have to be
initialized.

```cpp
// Allocate buffer for in-place call
fidl::Buffer<SetHeadingRequest> request_buffer;
fidl::BytePart request_bytes = request_buffer.view();
memset(request_bytes.data(), 0, request_bytes.capacity());

// Manually construct the message
auto msg = reinterpret_cast<SetHeadingRequest*>(request_bytes.data());
msg->heading = 42;
// Here since our message is a simple struct,
// the request size is equal to the capacity.
request_bytes.set_actual(request_bytes.capacity());

// Wrap with a fidl::DecodedMessage
fidl::DecodedMessage<SetHeadingRequest> request(std::move(request_bytes));

// Finally, make the call.
auto result = SpaceShip::InPlace::SetHeading(channel, std::move(request));
// Check result.status(), result.error()
```

Despite the verbosity, there is actually very little work involved.
The buffer passed to the underlying `zx_channel_call` system call is in fact
`request_bytes`. The performance benefits become apparent when say the request
message contains a large inline array. One could set up the buffers once, then
make repeated calls while mutating the array by directly editing the buffer
in between.

Key Point: in-place calls only reduce overhead in the request part of the call.
Responses are already processed in-place even in the managed and
caller-allocating flavors.

## Server API

```cpp
class Interface {
 public:
  virtual void SetHeading(int16_t heading,
                          SetHeadingCompleter::Sync completer) = 0;

  class ScanForPlanetsCompleterBase {
   public:
    void Reply(fidl::VectorView<Planet> planets);
    void Reply(fidl::BytePart buffer, fidl::VectorView<Planet> planets);
    void Reply(fidl::DecodedMessage<ScanForPlanetsResponse> params);
  };

  using ScanForPlanetsCompleter = fidl::Completer<ScanForPlanetsCompleterBase>;

  virtual void ScanForPlanets(ScanForPlanetsCompleter::Sync completer) = 0;

  class DirectedScanCompleterBase {
   public:
    void Reply(fidl::VectorView<Planet> planets);
    void Reply(fidl::BytePart buffer, fidl::VectorView<Planet> planets);
    void Reply(fidl::DecodedMessage<DirectedScanResponse> params);
  };

  using DirectedScanCompleter = fidl::Completer<DirectedScanCompleterBase>;

  virtual void DirectedScan(int16_t heading, DirectedScanCompleter::Sync completer) = 0;
};

bool TryDispatch(Interface* impl, fidl_msg_t* msg, fidl::Transaction* txn);
```

The generated `Interface` class has pure virtual functions corresponding to the
method calls defined in the FIDL protocol. One may override these functions in
a subclass, and dispatch FIDL messages to a server instance by calling
`TryDispatch`.
The bindings runtime would invoke these handler functions appropriately.

```cpp
class MyServer final : fuchsia::fleet::SpaceShip::Interface {
 public:
  void SetHeading(int16_t heading,
                  SetHeadingCompleter::Sync completer) override {
    // Update the heading...
  }
  void ScanForPlanets(ScanForPlanetsCompleter::Sync completer) override {
    fidl::VectorView<Planet> discovered_planets = /* perform planet scan */;
    // Send the |discovered_planets| vector as the response.
    completer.Reply(std::move(discovered_planets));
  }
  void DirectedScan(int16_t heading, DirectedScanCompleter::Sync completer) override {
    fidl::VectorView<Planet> discovered_planets = /* perform a directed planet scan */;
    // Send the |discovered_planets| vector as the response.
    completer.Reply(std::move(discovered_planets));
  }
};
```

Each handler function has an additional last argument `completer`.
It captures the various ways one may complete a FIDL transaction, by sending a
reply, closing the channel with epitaph, etc.
For FIDL methods with a reply e.g. `ScanForPlanets`, the corresponding completer
defines up to three overloads of a `Reply()` function
(managed, caller-allocating, in-place), similar to the client side API.
The completer always defines a `Close(zx_status_t)` function, to close the
connection with a specified epitaph.

NOTE: Each `Completer` object must only be accessed by one thread at a time.
Simultaneous access from multiple threads will result in a crash.

### Responding asynchronously {#async-server}

Notice that the type for the completer `ScanForPlanetsCompleter::Sync` has
`::Sync`. This indicates the default mode of operation: the server must
synchronously make a reply before returning from the handler function.
Enforcing this allows optimizations: the bookkeeping metadata for making
a reply may be stack-allocated.
To asynchronously make a reply, one may call the `ToAsync()` method on a `Sync`
completer, converting it to `ScanForPlanetsCompleter::Async`. The `Async`
completer supports the same `Reply()` functions, and may out-live the scope of
the handler function by e.g. moving it into a lambda capture.

```cpp
void ScanForPlanets(ScanForPlanetsCompleter::Sync completer) override {
  // Suppose scanning for planets takes a long time,
  // and returns the result via a callback...
  EnqueuePlanetScan(some_parameters)
      .OnDone([completer = completer.ToAsync()] (auto planets) mutable {
        // Here the type of |completer| is |ScanForPlanetsCompleter::Async|.
        completer.Reply(std::move(planets));
      });
}
```

### Parallel message handling

NOTE: This use-case is currently possible only using the
[lib/fidl](/zircon/system/ulib/fidl) bindings.

By default, messages from a single binding are handled sequentially, i.e. a
single thread attached to the dispatcher (run loop) is woken up if necessary,
reads the message, executes the handler, and returns back to the dispatcher. The
`::Sync` completer provides an additional API, `EnableNextDispatch()`, which may
be used to selectively break this restriction. Specifically, a call to this API
will enable another thread waiting on the dispatcher to handle the next message
on the binding while the first thread is still in the handler. Note that
repeated calls to `EnableNextDispatch()` on the same `Completer` are idempotent.

```cpp
void DirectedScan(int16_t heading, ScanForPlanetsCompleter::Sync completer) override {
  // Suppose directed scans can be done in parallel. It would be suboptimal to block one scan until
  // another has completed.
  completer.EnableNextDispatch();
  fidl::VectorView<Planet> discovered_planets = /* perform a directed planet scan */;
  completer.Reply(std::move(discovered_planets));
}
```

# Reference

## Design

### Goals

*   Support encoding and decoding FIDL messages with C++17.
*   Provide fine-grained control over memory allocation.
*   More type-safety and more features than the C language bindings.
*   Match the size and efficiency of the C language bindings.
*   Depend only on a small subset of the standard library.
*   Minimize code bloat through table-driven encoding and decoding.
*   Reuse encoders, decoders, and coding tables generated for C language
    bindings.

## Pointers and memory ownership {#memory-ownership}

LLCPP objects use special smart pointers called `tracking_ptr` to keep track of memory ownership.
With `tracking_ptr`, LLCPP makes it possible for your code to easily set a value and forget
about ownership: `tracking_ptr` will take care of freeing memory when it goes out of scope.

These pointers have two states:

*   unowned (constructed from an `unowned_ptr_t`)
*   heap allocated and owned (constructed from a `std::unique_ptr`)

When the contents is owned, a `tracking_ptr` behaves like a `unique_ptr` and the pointer is
deleted on destruction. In the unowned state, `tracking_ptr` behaves like a raw pointer and
destruction is a no-op.

`tracking_ptr` is move-only and has an API closely matching `unique_ptr`.

### Types of object allocation
`tracking_ptr` makes it possible to create LLCPP objects with several allocation strategies.
The allocation strategies can be mixed and matched within the same code.

#### Heap allocation
To heap allocate objects, use the standard `std::make_unique`.

An example with an optional uint32 field represented as a `tracking_ptr`.

```
MyStruct s;
s.opt_uint32_field = std::make_unique<uint32_t>(123);
```

This applies to all union and table fields and data arrays within vectors and strings.
Vector and string data arrays must use the array specialization of `std::unique_ptr`,
which takes the element count as an argument.

```
VectorView<uint32_t> vec;
vec.set_data(std::make_unique<uint32_t[]>(10));
```

To copy a collection to a `VectorView`, use `heap_copy_vec`.

```
std::vector<uint32_t> vec;
fidl::VectorView<uint32_t> vv = heap_copy_vec(vec);
```

To copy a string to a `StringView`, use `heap_copy_str`.

```
std::string_view str = "hello world";
fidl::StringView sv = heap_copy_str(str);
```

#### Allocators
FIDL provides an `Allocator` API that enables creating `tracking_ptr`s to LLCPP objects through a
number of allocation algorithms. Currently, `BufferThenHeapAllocator`, `UnsafeBufferAllocator`, and
`HeapAllocator` are available in fidl namespace.

The `BufferThenHeapAllocator` allocates from an in-band fixed-size buffer (can be used for stack
allocation), but falls back to heap allocation if the in-band buffer has been exhausted (to avoid
unnecessary unfortunate surprises).  Be aware that excessive stack usage can cause its own problems,
so consider using a buffer size that comfortably fits on the stack, or consider putting the whole
BufferThenHeapAllocator on the heap if the buffer needs to be larger than fits on the stack, or
consider using HeapAllocator.  Allocations must be assumed to be gone upon destruction of the
`BufferThenHeapAllocator` used to make them.

The `HeapAllocator` always allocates from the heap, and is unique among allocators (so far) in that
any/all of the `HeapAllocator` allocations can out-live the `HeapAllocator` instance used to make
them.

The `UnsafeBufferAllocator` is unsafe in the sense that it lacks heap failover, so risks creating
unfortunate data-dependent surprises unless the buffer size is absolutely guaranteed to be large
enough including the internal destructor-tracking overhead.  If the internal buffer is exhausted,
make<>() will panic the entire process.  Consider using `BufferThenHeapAllocator` instead.  Do not
use `UnsafeBufferAllocator` without rigorously testing that the worst-case set of cumulative
allocations made via the allocator all fit without a panic, and consider how the rigor will be
maintained as code and FIDL tables are changed.

Example:

```
BufferThenHeapAllocator<2048> allocator;
MyStruct s;
s.opt_uint32_field = allocator.make<uint32_t>(123);
```

The arguments to `allocator.make` are identical to the arguments to `std::make_unique`.
This also applies to VectorViews.

```
BufferThenHeapAllocator<2048> allocator;
fidl::VectorView<uint32_t> vec;
vec.set_data(allocator.make<uint32_t[]>(10));
```

To copy a collection to a `VectorView` using an allocator, use `copy_vec`.

```
BufferThenHeapAllocator<2048> allocator;
std::vector<uint32_t> vec;
fidl::VectorView<uint32_t> vv = fidl::copy_vec(allocator, vec);
```

To create a copy of a string using an allocator, use `copy_str`.

```
BufferThenHeapAllocator<2048> allocator;
std::string_view str = "hello world";
fidl::StringView sv = fidl::copy_str(allocator, str);
```

#### Unowned pointers
In addition to the managed allocation strategies, it is also possible to directly
create pointers to memory unowned by FIDL. This is discouraged, as it is easy to
accidentally create use-after-free bugs. `unowned_ptr` exists to explicitly mark
pointers to FIDL-unowned memory.

The `unowned_ptr` helper is the recommended way to create `unowned_ptr_t`s,
which is more ergonomic than using the `unowned_ptr_t` constructor directly.

```
MyStruct s;
uint32_t i = 123;
s.opt_uint32_field = fidl::unowned_ptr(&i);
```

To create a `VectorView` from a collection using an unowned pointer to the
collection's data array, use `unowned_vec`.

```
std::vector<uint32_t> vec;
fidl::VectorView<uint32_t> vv = fidl::unowned_vec(vec);
```

To create a `StringView` from unowned memory, use `unowned_str`.

```
const char arr[] = {'h', 'e', 'l', 'l', 'o'};
fidl::StringView sv = fidl::unowned_str(arr, 5);
```

A `StringView` can also be created directly from string literals without using
`unowned_ptr`.

```
fidl::StringView sv = "hello world";
```

## Code generator

### Mapping FIDL types to low-level C++ types

This is the mapping from FIDL types to Low-Level C++ types which the code
generator produces.

FIDL                                        | Low-Level C++
--------------------------------------------|------------------------------------------------------
`bool`                                      | `bool`, *(requires sizeof(bool) == 1)*
`int8`                                      | `int8_t`
`uint8`                                     | `uint8_t`
`int16`                                     | `int16_t`
`uint16`                                    | `uint16_t`
`int32`                                     | `int32_t`
`uint32`                                    | `uint32_t`
`int64`                                     | `int64_t`
`uint64`                                    | `uint64_t`
`float32`                                   | `float`
`float64`                                   | `double`
`handle`, `handle?`                         | `zx::handle`
`handle<T>`,`handle<T>?`                    | `zx::T` *(subclass of zx::object\<T\>)*
`string`                                    | `fidl::StringView`
`string?`                                   | `fidl::StringView`
`vector<T>`                                 | `fidl::VectorView<T>`
`vector<T>?`                                | `fidl::VectorView<T>`
`array<T>:N`                                | `fidl::Array<T, N>`
*protocol, protocol?*                       | `zx::channel`
*request\<Protocol\>, request\<Protocol\>?* | `zx::channel`
*struct* Struct                             | *struct* Struct
*struct?* Struct                            | *struct* Struct*
*table* Table                               | *struct* Table
*union* Union                               | *struct* Union
*union?* Union                              | *struct* Union*
*union* Union                               | *struct* Union
*union?* Union                              | *struct* Union*
*enum* Foo                                  | *enum class Foo : data type*

#### fidl::StringView

Defined in [lib/fidl/llcpp/string_view.h](/zircon/system/ulib/fidl/include/lib/fidl/llcpp/string_view.h)

Holds a reference to a variable-length string stored within the buffer. C++
wrapper of **fidl_string**. Does not own the memory of the contents.

`fidl::StringView` may be constructed by supplying the pointer and number of
UTF-8 bytes (excluding trailing `\0`) separately. Alternatively, one could pass
a C++ string literal, or any value which implements `[const] char* data()`
and `size()`. The string view would borrow the contents of the container.

It is memory layout compatible with **fidl_string**.

#### fidl::VectorView\<T\>

Defined in [lib/fidl/llcpp/vector_view.h](/zircon/system/ulib/fidl/include/lib/fidl/llcpp/vector_view.h)

Holds a reference to a variable-length vector of elements stored within the
buffer. C++ wrapper of **fidl_vector**. Does not own the memory of elements.

`fidl::VectorView` may be constructed by supplying the pointer and number of
elements separately. Alternatively, one could pass any value which supports
[`std::data`](https://en.cppreference.com/w/cpp/iterator/data), such as a
standard container, or an array. The vector view would borrow the contents of
the container.

It is memory layout compatible with **fidl_vector**.

#### fidl::Array\<T, N\>

Defined in [lib/fidl/llcpp/array.h](/zircon/system/ulib/fidl/include/lib/fidl/llcpp/array.h)

Owns a fixed-length array of elements.
Similar to `std::array<T, N>` but intended purely for in-place use.

It is memory layout compatible with FIDL arrays, and is standard-layout.
The destructor closes handles if applicable e.g. it is an array of handles.

#### Tables

The following example table will be used in this section:

```
table MyTable {
  1: uint32 x;
  2: uint32 y;
};
```

Tables can be built using the associated table builder. For `MyTable`, the associated builder
would be `MyTable::Builder` which can be used as follows:

```
MyTable table = MyTable::Builder(std::make_unique<MyTable::Frame>())
                        .set_x(std::make_unique<uint32_t>(10))
                        .set_y(std::make_unique<uint32_t(20))
                        .build();
```

`MyTable::Frame` is the table's `Frame` - essentially its internal storage. The internal storage
needs to be allocated separately from the builder because LLCPP maintains the object layout of
the underlying wire format.

In addition to assigning fields with `std::unique_ptr`, any of the allocation strategies previously
metioned can be alternatively used.

## Bindings library

### Dependencies

The low-level C++ bindings depend only on a small subset of header-only parts
of the standard library. As such, they may be used in environments where linking
against the C++ standard library is discouraged or impossible.

### Helper types

#### fidl::DecodedMessage\<T\>

Defined in [lib/fidl/llcpp/decoded_message.h](/zircon/system/ulib/fidl/include/lib/fidl/llcpp/decoded_message.h)

Manages a FIDL message in [decoded form][wire-format-dual-forms].
The message type is specified in the template parameter `T`.
This class takes care of releasing all handles which were not consumed
(std::moved from the decoded message) when it goes out of scope.

`fidl::Encode(std::move(decoded_message))` encodes in-place.

#### fidl::EncodedMessage\<T\>

Defined in [lib/fidl/llcpp/encoded_message.h](/zircon/system/ulib/fidl/include/lib/fidl/llcpp/encoded_message.h)
Holds a FIDL message in [encoded form][wire-format-dual-forms],
that is, a byte array plus a handle table.
The bytes part points to an external caller-managed buffer, while the handles part
is owned by this class. Any handles will be closed upon destruction.

`fidl::Decode(std::move(encoded_message))` decodes in-place.

##### Example

```cpp
zx_status_t SayHello(const zx::channel& channel, fidl::StringView text,
                     zx::handle token) {
  assert(text.size() <= MAX_TEXT_SIZE);

  // Manually allocate the buffer used for this FIDL message,
  // here we assume the message size will not exceed 512 bytes.
  uint8_t buffer[512] = {};
  fidl::DecodedMessage<example::Animal::SayRequest> decoded(
      fidl::BytePart(buffer, 512));

  // Fill in header and contents
  example::Animal::SetTransactionHeaderFor::SayRequest(&decoded);

  decoded.message()->text = text;
  // Handle types have to be moved
  decoded.message()->token = std::move(token);

  // Encode the message in-place
  fidl::EncodeResult<example::Animal::SayRequest> encode_result =
      fidl::Encode(std::move(decoded));
  if (encode_result.status != ZX_OK) {
    return encode_result.status;
  }

  fidl::EncodedMessage<example::Animal::SayRequest>& encoded =
      encode_result.message;
  return channel.write(0, encoded.bytes().data(), encoded.bytes().size(),
                       encoded.handles().data(), encoded.handles().size());
}
```

<!-- xrefs -->
[c-family-comparison]: /docs/development/languages/fidl/guides/c-family-comparison.md
[wire-format]: /docs/reference/fidl/language/wire-format
[wire-format-decoded]: /docs/reference/fidl/language/wire-format/README.md#Decoded-Messages
[wire-format-encoded]: /docs/reference/fidl/language/wire-format/README.md#Encoded-Messages
[wire-format-dual-forms]: /docs/reference/fidl/language/wire-format/README.md#Encoded-Messages#Dual-Forms_Encoded-vs-Decoded
