blob: 1e4c80b732d9f3f4509b69bb69e4fef36599fd11 [file] [log] [blame] [view]
# Overview
This document is a description of the Fuchsia Interface Definition Language
(FIDL) purpose, high-level goals, and requirements.
## Related Documents
* [Wire Format Specification]
* [Language Specification]
* [Compiler Specification]
* [Style Guide]
* [API Rubric]
* [Linter to check API Readability / Style]
* [C Language Bindings]
* [Low-Level C++ Language Bindings]
* [High-Level C++ Language Bindings]
* [C/Low-Level/High-Level C++ Bindings Comparison]
* [Examples]: Some small example code used during development
* [Tutorial]: A tutorial on using FIDL services in several languages
<!-- Reference links because these are used again below. -->
[Wire Format Specification]: ../reference/wire-format/README.md
[Language Specification]: ../reference/language.md
[Compiler Specification]: ../reference/compiler.md
[Style Guide]: ../style.md
[API Rubric]: /docs/concepts/api/fidl.md
[Linter to Check API Readability / Style]: ../reference/linter.md
[C Language Bindings]: ../tutorial/tutorial-c.md
[Low-Level C++ Language Bindings]: ../tutorial/tutorial-llcpp.md
[High-Level C++ Language Bindings]: ../tutorial/tutorial-cpp.md
[C/Low-Level/High-Level C++ Bindings Comparison]: ../tutorial/c-family-comparison.md
[Examples]: /zircon/tools/fidl/examples
[Tutorial]: ../tutorial/README.md
[TOC]
The Fuchsia Interface Definition Language (FIDL) is the language used to
describe interprocess communication (IPC) protocols used by programs running on
the Fuchsia Operating System. FIDL is supported by a toolchain (compiler) and
runtime support libraries (bindings) to help developers use IPC effectively.
## Goals
Fuchsia extensively relies on IPC since it has a microkernel architecture
wherein most functionality is implemented in user space outside of the kernel,
including privileged components such as device drivers. Consequently the IPC
mechanism must be efficient, deterministic, robust, and easy to use.
**IPC efficiency** pertains to the computational overhead required to generate,
transfer, and consume messages between processes. IPC will be involved in all
aspects of system operation so it must be efficient. The FIDL compiler must
generate tight code without excess indirection or hidden costs. It should be at
least as good as hand-rolled code would be where it matters most.
**IPC determinism** pertains to the ability to perform transactions within a
known resource envelope. IPC will be used extensively by critical system
services such as filesystems which serve many clients and which must perform in
predictable ways. The FIDL wire format must offer strong static guarantees such
as ensuring that structure size and layout is invariant thereby alleviating the
need for dynamic memory allocation or complex validation rules.
**IPC robustness** pertains to the need to consider IPC as an essential part of
the operating system's ABI. Maintaining binary stability is crucial. Mechanisms
for protocol evolution must be designed conservatively so as not to violate the
invariants of existing services and their clients, particularly when the need
for determinism is also considered. The FIDL bindings must perform effective,
lightweight, and strict validation.
**IPC ease of use** pertains to the fact that IPC protocols are an essential
part of the operating system's API. It is important to provide good developer
ergonomics for accessing services via IPC. The FIDL code generator removes the
burden of writing IPC bindings by hand. Moreover, the FIDL code generator can
produce different bindings to suit the needs of different audiences and their
idioms.
# Requirements
## Purpose
* Describe data structures and protocols used by IPC on Zircon.
* Optimized for interprocess communication only; FIDL must not be persisted to
disk or used for network transfer across device boundaries.
* Efficiently transport messages consisting of data (bytes) and capabilities
(handles) over Zircon channels between processes running on the same
device.
* Designed specifically to facilitate effective use of Zircon primitives; not
intended for use on other platforms; not portable.
* Offers convenient APIs for creating, sending, receiving, and consuming
messages.
* Perform sufficient validation to maintain protocol invariants (but no more
than that).
## Efficiency
* Just as efficient (speed and memory) as using hand-rolled data structures
would be.
* Wire format uses uncompressed native datatypes with little-endianness and
correct alignment to support in-place access of message contents.
* No dynamic memory allocation is required to produce or to consume messages
when their size is statically known or bounded.
* Explicitly handle ownership with move-only semantics.
* Data structure packing order is canonical, unambiguous, and has minimum
padding.
* Avoid back-patching pointers.
* Avoid expensive validation.
* Avoid calculations which may overflow.
* Leverage pipelining of protocol requests for asynchronous operation.
* Structures are fixed size; variable-size data is stored out-of-line.
* Structures are not self-described; FIDL files describe their contents.
* No versioning of structures, but protocols can be extended with new methods
for evolution.
## Ergonomics
* Programming language bindings maintained by Fuchsia team:
* C, Low-Level C++, High-Level C++, Dart, Go, Rust
* Keeping in mind we might want to support other languages in the future, such
as:
* Java, JavaScript, etc.
* The bindings and generated code are available in native or idiomatic flavors
depending on the intended application.
* Use compile-time code generation to optimize message serialization,
deserialization, and validation.
* FIDL syntax is familiar, easily accessible, and programming language
agnostic.
* FIDL provides a library system to simplify deployment and use by other
developers.
* FIDL expresses the most common data types needed for system APIs; it does
not seek to provide a comprehensive one-to-one mapping of all types offered
by all programming languages.
## Implementation
* Compiler is written in C++ to be usable by components built in Zircon.
* Compiler is portable and can be built with a host toolchain.
* We will not support FIDL bindings for any platform other than Fuchsia.
## Where to Find the Code
- [The compiler](/zircon/tools/fidl)
- [C and low-level C++ bindings](/zircon/system/ulib/fidl)
- [High-level C++ bindings](/sdk/lib/fidl/cpp)
- [Go bindings](https://fuchsia.googlesource.com/third_party/go/+/master/src/syscall/zx/fidl/)
- [Rust bindings](/src/lib/fidl/rust)
## Constituent Parts of Specification
### FIDL Wire Format
The FIDL wire format specified how FIDL messages are represented in memory for
transmission over IPC.
The FIDL wire format is documented [Wire Format Specification].
### FIDL Language
The FIDL language is the syntax by which protocols are described in ***.fidl**
files.
The FIDL language is documented [Language Specification].
### FIDL Compiler
The FIDL compiler generates code for programs to use and implement protocols
described by the FIDL language.
The FIDL compiler is documented [Compiler Specification].
### FIDL Bindings
FIDL bindings are language-specific runtime support libraries and code
generators which provide APIs for manipulating FIDL data structures and
protocols.
Languages-specific topics:
* [C Language Bindings]
* [Low-Level C++ Language Bindings]
* [High-Level C++ Language Bindings]
Bindings are available in various flavors depending on the language:
* **Native bindings**: designed for highly sensitive contexts such as device
drivers and high-throughput servers, leverage in-place access, avoid memory
allocation, but may require somewhat more awareness of the constraints of
the protocol on the part of the developer.
* **Idiomatic bindings**: designed to be more developer-friendly by copying
data from the wire format into easier to use data types (such as heap-backed
strings or vectors), but correspondingly somewhat less efficient as a
result.
Bindings offer several various ways of invoking protocol methods depending on
the language:
* **Send/receive**: read or write messages directly to a channel, no built-in
wait loop (C)
* **Callback-based**: received messages are dispatched asynchronously as
callbacks on an event loop (C++, Dart)
* **Port-based**: received messages are delivered to a port or future (Rust)
* **Synchronous call**: waits for reply and return it (Go, C++ unit tests)
Bindings provide some or all of the following principal operations:
* **Encode**: in-place transform native data structures into the wire format
(coupled with validation)
* **Decode**: in-place transform wire format data into native data structures
(coupled with validation)
* **Copy/Move To Idiomatic Form**: copy contents of native data structures
into idiomatic data structures, handles are moved
* **Copy/Move To Native Form**: copy contents of idiomatic data structures
into native data structures, handles are moved
* **Clone**: copy native or idiomatic data structures (that do not contain
move-only types)
* **Call**: invoke protocol method
## Workflow
This section describes the workflow of authors, publishers, and consumers of IPC
protocols described using FIDL.
# Authoring FIDL
The author of a FIDL based protocol creates one or more ***.fidl files** to
describe their data structures, protocols, and methods.
FIDL files are grouped into one or more **FIDL libraries** by the author. Each
library represents a group of logically related functionality with a unique
library name. FIDL files within the same library implicitly have access to all
other declarations within the same library. The order of declarations within the
FIDL files that make up a library is not significant.
FIDL files of one library can access declarations within another FIDL library by
**importing** the other FIDL module. Importing other FIDL libraries makes their
symbols available for use thereby enabling the construction of protocols derived
from them. Imported symbols must be qualified by the library name or by an alias
to prevent namespace collisions.
# Publishing FIDL
The publisher of a FIDL based protocol is responsible for making FIDL libraries
available to consumers. For example, the author may disseminate FIDL libraries
in a public source repository or distribute them as part of an SDK.
Consumers need only point the FIDL compiler at the directory which contains the
FIDL files for a library (and its dependencies) to generate code for that
library. The precise details for how this is done will generally be addressed by
the consumer's build system.
# Consuming FIDL
The consumer of a FIDL based protocol uses the FIDL compiler to generate code
suitable for use with their language runtime specific bindings. For certain
language runtimes, the consumer may have a choice of a few different flavors of
generated code all of which are interoperable at the wire format level but
perhaps not at the source level.
In the Fuchsia world build environment, generating code from FIDL libraries will
be done automatically for all relevant languages by individual FIDL build
targets for each library.
In the Fuchsia SDK environment, generating code from FIDL libraries will be done
as part of compiling the applications which use them.