blob: 9e0b0653f3fa874b6258711a8616514d04f8c602 [file] [log] [blame] [view]
# Fuchsia Interface Definition Language
Fuchsia Interface Definition Language (FIDL) is the language used to describe
interprocess communication (IPC) protocols used by Fuchsia programs. FIDL
provides a simplified declaration syntax for providers to define interfaces as a
**protocol**. Supported data types include integers, floats, booleans, strings,
and [handles][glossary.handle]. These can be organized into more complex arrays,
vectors, structs, tables, and unions.
Consider the following example FIDL protocol for an `Echo` interface:
```fidl
library fuchsia.examples;
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples/echo.test.fidl" region_tag="max" adjust_indentation="auto" %}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples/echo.test.fidl" region_tag="echo" adjust_indentation="auto" %}
```
FIDL protocols describe a set of **methods** invoked by sending messages over
a channel. Channel messages are inherently asynchronous, with the sender and
receiver operating independently of each other. FIDL methods introduce
higher-level semantics that enable more idiomatic programming on the client and
server side of a FIDL transaction.
FIDL supports the following method types:
* **Two-way methods:** A typical method call that accepts optional parameters
with a return type defined after the `->` operator. Two-way methods block
until a response is received. In the `Echo` example, the `EchoString()`
method is a two-way method.
* **One-way methods:** Asynchronous method calls that return immediately
without waiting for a response. Methods without a declared return type are
considered one-way from the client. In the `Echo` example, the `SendString()`
method is a one-way method.
* **Events:** When necessary, a server may send unsolicited messages to the
client, called events. Events declare their method name on the return side of
the `->` operator. In the `Echo` example, the `OnString()` method is an event.
Note: For more details on FIDL language syntax and supported types, see the
[FIDL Language specification](/docs/reference/fidl/language/language.md).
## Creating a FIDL library
**FIDL libraries** group FIDL source files together. A library acts as a
namespace for the protocols it contains, and FIDL source files can implicitly
access all other declarations within the same library. FIDL source files must
**import** any declarations from another library.
The Fuchsia build system provides the `fidl()` build target to compile FIDL
source files into a library. The name of the library target must match the
`library` declarations in each source file. See the following `BUILD.gn` example
for the `fuchsia.examples` library:
```gn
# Import the fidl GN template.
import("//build/fidl/fidl.gni")
# Define a FIDL library target.
fidl("fuchsia.examples") {
# FIDL source files contained in library
sources = [
"echo.fidl",
]
}
```
<aside class="key-point">
By default, the build system uses the <code>fidl()</code> GN target name as the
library name. You can override this behavior with the <code>name</code>
parameter.
</aside>
At build time, the FIDL Compiler (`fidlc`) frontend tool validates and compiles
the library source files into a JSON Intermediate Representation (IR). This JSON
IR format is the basis for the FIDL bindings.
## Generating FIDL bindings
Components consume FIDL protocols through generated code called
**FIDL bindings**. Bindings encode and decode requests and responses as
**FIDL messages** and transfer them over the underlying IPC channel. The
language-specific binding libraries provide wrappers around these structures to
align interactions with familiar programming idioms.
The client interface (sometimes referred to as a proxy) performs translation
between higher-level function calls and FIDL messages. On the server side,
bindings process incoming request messages and deliver them through an abstract
interface for components to implement.
![Diagram showing how FIDL bindings provide generated library code to translate
function calls into FIDL messages for transport across process boundaries.]
(images/fidl-bindings.png){: width="574"}
Note: For more details on the bindings specification and supported programming
languages, see the [Bindings Reference](/docs/reference/fidl/bindings/overview.md).
At build time, the `fidlgen` backend tools generate bindings for supported
programming languages from the JSON IR library produced by `fidlc`. For example,
`fidlgen_rust` generates Rust bindings from the JSON IR.
The `fidl()` library target creates individual binding targets for each
supported language. Due to the nature of GN, these bindings are not generated
at build time unless they are included as a dependency.
See the following example `BUILD.gn` snippet that includes the generated Rust
bindings target for the `fuchsia.examples` library (`fuchsia.examples-rustc`):
```gn
deps = [
"fidl/fuchsia.examples:fuchsia.examples-rustc",
...
]
```
## Exercise: Echo FIDL Library
In this section, you'll define a new FIDL library with a protocol called
`Echo` containing a single method that returns string values back to the
caller.
Start by creating a new directory for the FIDL library target:
```posix-terminal
mkdir vendor/fuchsia-codelab/echo-fidl
```
Add a new FIDL interface file called `echo.fidl` with the following contents:
```fidl
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/routing/fidl/echo.fidl" region_tag="fidl_echo" adjust_indentation="auto" %}
```
`EchoString` is a two-way method that accepts an optional (nullable) string
value and returns the same value.
Add a `BUILD.gn` file with the following contents to declare the library target:
```gn
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/routing/fidl/BUILD.gn" region_tag="fidl_echo" adjust_indentation="auto" %}
```
Add the library target to the build configuration:
```posix-terminal
fx set workstation.qemu-x64 --with //vendor/fuchsia-codelab/echo-fidl:echo
```
Run `fx build` to compile the FIDL interface:
```posix-terminal
fx build vendor/fuchsia-codelab/echo-fidl:echo
```
### Examine the FIDL bindings
The `fidl()` GN target compiles the FIDL interface and generates additional
build targets to provide the bindings in various languages. To examine the
bindings, you must compile the individual targets.
Compile the `fidl.examples.routing.echo` bindings for Rust:
```posix-terminal
fx build vendor/fuchsia-codelab/echo-fidl:echo-rustc
```
Use GN to locate the generated source file for the target and open it in an
editor:
```posix-terminal
fx gn desc out/default/ vendor/fuchsia-codelab/echo-fidl:echo-rustc sources
```
Explore the contents of the file. Below is a summary of some of the key
generated interfaces:
<table>
<tr>
<th><strong>Interface</strong>
</th>
<th><strong>Description</strong>
</th>
</tr>
<tr>
<td><code>EchoMarker</code>
</td>
<td>Used to open a proxy and request stream for a given protocol.
</td>
</tr>
<tr>
<td><code>EchoProxy</code>
</td>
<td>Asynchronous client that transforms protocol methods into FIDL request messages sent over the IPC channel.
</td>
</tr>
<tr>
<td><code>EchoSynchronousProxy</code>
</td>
<td>Synchronous client that transforms protocol methods into FIDL request messages sent over the IPC channel.
</td>
</tr>
<tr>
<td><code>EchoRequest</code>
</td>
<td>Structured types for handling incoming requests for each protocol method.
</td>
</tr>
<tr>
<td><code>EchoRequestStream</code>
</td>
<td>Stream to handle incoming FIDL request messages over the IPC channel.
</td>
</tr>
<tr>
<td><code>EchoEchoStringResponder</code>
</td>
<td>Callback to send a return value for each proxy request as a FIDL response message.
</td>
</tr>
</table>
<aside class="key-point">
<b>Asynchronous vs. synchronous clients</b>
<p>The FIDL toolchain generates client bindings that are asynchronous by default.
This means the client methods return immediately to the caller and responses
are delivered using a callback or future. Synchronous clients provide a
simplified API that guarantees responses are delivered before the client
method returns.</p>
<p>Synchronous clients are not available in all supported languages. For more
details, see the specifications for your chosen language in the
<a href="/docs/reference/fidl/bindings/overview">Bindings Reference</a>.</d>
</aside>
[glossary.handle]: /docs/glossary/README.md#handle