blob: 337dd4da1af297855f62880118ca078c9cc36412 [file] [log] [blame] [view] [edit]
# FIDL language specification
This document is a specification of the Fuchsia Interface Definition Language
(**FIDL**) syntax.
For more information about FIDL's overall purpose, goals, and requirements,
see [Overview][fidl-overview].
Also, see a modified [EBNF description of the FIDL grammar][fidl-grammar].
[TOC]
## Syntax
FIDL provides a syntax for declaring named bits, constants, enums, structs,
tables, unions, and protocols. These declarations are collected into libraries
for distribution.
FIDL declarations are stored in plain text UTF-8 files. Each file consists of a
sequence of semicolon-delimited declarations. The order of declarations within a
FIDL file, or among FIDL files within a library, is irrelevant. FIDL does not
require (or support) forward declarations of any kind.
### Comments
FIDL comments start with two (`//`) or three (`///`) forward slashes, continue
to the end of the line, and can contain UTF-8 content (which is, of course, ignored).
The three-forward-slash variant is a "documentation comment", and causes the comment
text to be emitted into the generated code (as a comment, escaped correctly
for the target language).
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="comments" %}
```
Note that documentation comments can also be provided via the
[`[Doc]` attribute][doc-attribute].
### Keywords
The following are keywords in FIDL.
```
as, bits, compose, const, enum, library, protocol,
resource, struct, table, union, using, xunion.
```
### Identifiers
FIDL _identifiers_ label declarations and their members. FIDL identifiers must
match the regex `[a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])?`. In words: identifiers
must start with a letter, can contain letters, numbers, and underscores, but
cannot end with an underscore.
```fidl
// a struct named "Foo"
struct Foo { };
// an enum named "enum", containing a single member
enum enum { WITH_A_MEMBER = 1; };
```
Note: While using keywords as identifiers is supported, it can lead to
confusion, and should therefore be considered on a case-by-case basis. See the
`Names` section of the [Style Rubric][naming-style].
FIDL _library names_ label [FIDL libraries](#libraries). FIDL library names
consist of one or more elements each matching the regex `[a-z][a-z0-9]*`. In
words: library name elements must start with a lowercase letter, can contain
lowercase letters, and numbers (they cannot contain uppercase letters, nor
underscores). Library names are used in [Qualified
Identifiers](#qualified-identifiers).
```fidl
// a library named "foo"
library foo;
```
Identifiers and library names are case-sensitive.
### Qualified Identifiers {#qualified-identifiers}
FIDL always looks for unqualified symbols within the scope of the current
library. To reference symbols in other libraries, they must be qualified by
prefixing the identifier with the library name or alias thereof.
**objects.fidl:**
```fidl
library objects;
using textures as tex;
protocol Frob {
// "Thing" refers to "Thing" in the "objects" library
// "tex.Color" refers to "Color" in the "textures" library
Paint(Thing thing, tex.Color color);
};
struct Thing {
string name;
};
```
**textures.fidl:**
```fidl
library textures;
struct Color {
uint32 rgba;
};
```
### Literals
FIDL supports integer, floating point, boolean, string, and enumeration literals, using
a simplified syntax familiar to C programmers (see below for examples).
### Constants {#constants}
FIDL supports the following constant types: bits, booleans, signed and unsigned
integers, floating point values, strings, and enumerations.
The syntax is similar to C:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="consts" %}
```
These declarations introduce a name within their scope.
The constant's type must be either a primitive or an enum.
Constant expressions are either literals or the names of other
constant expressions.
> For greater clarity, there is no expression processing in FIDL; that is,
> you *cannot* declare a constant as having the value `6 + 5`, for
> example.
### Default Initialization
Primitive structure members may have initialization values specified
in the declaration.
For example:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="defaults" %}
```
If the programmer does not supply a background color, the default
value of `0xFF77FF` will be used.
However, if the program does not supply a foreground color, there is no
default.
The foreground color must be supplied; otherwise it's a logic error on
the programmer's part.
There is a subtlety about the semantics and what defaults mean:
* If the target language can support defaults (Dart, C++)
* then it MUST support defaults
* If the target language cannot support defaults (C, Rust, Go)
* then it MAY provide support that programmers can optionally
invoke (e.g., a macro in C).
### Declaration Separator
FIDL uses the semi-colon **';'** to separate adjacent declarations within the
file, much like C.
## Libraries {#libraries}
Libraries are named containers of FIDL declarations.
```fidl
// library identifier separated by dots
library fuchsia.composition;
// "using" to import library "fuchsia.buffers"
using fuchsia.buffers;
// "using" to import library "fuchsia.geometry" and create a shortform called "geo"
using fuchsia.geometry as geo;
```
Libraries may declare that they use other libraries with a "using" declaration.
This allows the library to refer to symbols defined in other libraries upon which
they depend. Symbols imported this way may be accessed by:
* qualifying them with the fully qualified library name (as in _"fuchsia.geometry.Rect"_),
* specifying just the library name (as in _"geometry.Rect"_), or,
* using a library alias (as in _"geo.Rect"_).
In the source tree, each library consists of a directory with some number of
**.fidl** files. The name of the directory is irrelevant to the FIDL compiler
but by convention it should resemble the library name itself. A directory should
not contain FIDL files for more than one library.
The scope of "library" and "using" declarations is limited to a single file.
Each individual file within a FIDL library must restate the "library"
declaration together with any "using" declarations needed by that file.
The library's name may be used by certain language bindings to provide scoping
for symbols emitted by the code generator.
For example, the C++ bindings generator places declarations for the
FIDL library "fuchsia.ui" within the C++ namespace
"fuchsia::ui". Similarly, for languages such as Dart and Rust, which
have their own module system, each FIDL library is compiled as a
module for that language.
## Types and Type Declarations
FIDL supports a number of builtin types as well as declarations of new types
(e.g. structs, unions, type aliases) and protocols.
### Primitives
* Simple value types.
* Not nullable.
The following primitive types are supported:
* Boolean **`bool`**
* Signed integer **`int8 int16 int32 int64`**
* Unsigned integer **`uint8 uint16 uint32 uint64`**
* IEEE 754 Floating-point **`float32 float64`**
Numbers are suffixed with their size in bits, **`bool`** is 1
byte.
We also alias **`byte`** to mean **`uint8`** as a [built-in alias](#built-in-aliases).
#### Use
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="primitives" %}
```
### Bits {#bits}
* Named bit types.
* Discrete subset of bit values chosen from an underlying integer primitive
type.
* Not nullable.
* Bits must have at least one member.
* Bits can either be [`strict` or `flexible`](#strict-vs-flexible).
<!-- TODO(fxbug.dev/64463): update default -->
* Bits default to `strict`.
#### Use
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="bits" %}
```
### Enums {#enums}
* Proper enumerated types.
* Discrete subset of named values chosen from an underlying integer primitive
type.
* Not nullable.
* Enums must have at least one member.
* Enums can be [`strict` or `flexible`](#strict-vs-flexible).
<!-- TODO(fxbug.dev/64463): update default -->
* Enums default to `strict`.
#### Declaration
The ordinal index is **required** for each enum element. The underlying type of
an enum must be one of: **int8, uint8, int16, uint16, int32, uint32, int64,
uint64**. If omitted, the underlying type is assumed to be **uint32**.
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="enums" %}
```
#### Use
Enum types are denoted by their identifier, which may be qualified if needed.
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="enum-use" %}
```
### Arrays
* Fixed-length sequences of homogeneous elements.
* Elements can be of any type including: primitives, enums, arrays, strings,
vectors, handles, structs, tables, unions.
* Not nullable themselves; may contain nullable types.
#### Use
Arrays are denoted **`array<T>:n`** where _T_ can
be any FIDL type (including an array) and _n_ is a positive
integer constant expression that specifies the number of elements in
the array.
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="arrays" %}
```
### Strings
* Variable-length sequence of UTF-8 encoded characters representing text.
* Nullable; null strings and empty strings are distinct.
* Can specify a maximum size, eg. **`string:40`** for a
maximum 40 byte string.
* May contain embedded `NUL` bytes, unlike traditional C strings.
#### Use
Strings are denoted as follows:
* **`string`** : non-nullable string ([validation error][lexicon-validate]
occurs if null is encountered)
* **`string?`** : nullable string
* **`string:N, string:N?`** : string, and nullable string, respectively,
with maximum length of _N_ bytes
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="strings" %}
```
> Strings should not be used to pass arbitrary binary data since bindings enforce
> valid UTF-8. Instead, consider `bytes` for small data or
> [`fuchsia.mem.Buffer`](/docs/concepts/api/fidl.md#consider-using-fuchsia_mem_buffer)
> for blobs. See
> [Should I use string or vector?](/docs/concepts/api/fidl.md#should-i-use-string-or-vector)
> for details.
### Vectors
* Variable-length sequence of homogeneous elements.
* Nullable; null vectors and empty vectors are distinct.
* Can specify a maximum size, eg. **`vector<T>:40`** for a
maximum 40 element vector.
* There is no special case for vectors of bools. Each bool element takes one
byte as usual.
* We have a [built-in alias](#built-in-aliases) for **`bytes`** to mean
`vector<uint8>`, and it can be size bound in a similar fashion e.g.
`bytes:1024`.
#### Use
Vectors are denoted as follows:
* **`vector<T>`** : non-nullable vector of element type
_T_ ([validation error][lexicon-validate] occurs if null is encountered)
* **`vector<T>?`** : nullable vector of element type
_T_
* **`vector<T>:N, vector<T>:N?`** : vector, and nullable vector, respectively,
with maximum length of _N_ elements
_T_ can be any FIDL type.
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="vectors" %}
```
### Handles {#handles}
* Transfers a Zircon capability by handle value.
* Stored as a 32-bit unsigned integer.
* Nullable by encoding as a zero-valued handle.
#### Use
Handles are denoted:
* **`handle`** : non-nullable Zircon handle of
unspecified type
* **`handle?`** : nullable Zircon handle of
unspecified type
* **`zx.handle:H`** : non-nullable Zircon handle
of type _H_
* **`zx.handle:H?`** : nullable Zircon handle of
type _H_
_H_ can be any [object](/docs/reference/kernel_objects/objects.md) supported by
Zircon, e.g. `channel`, `thread`, `vmo`. Please refer to the
[grammar](grammar.md) for a full list.
Structs, tables, and unions containing handles must be marked with the
[`resource` modifier](#value-vs-resource).
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="handles" %}
```
### Structs {#structs}
* Record type consisting of a sequence of typed fields.
* Declaration is not intended to be modified once deployed; use protocol
extension instead.
* Declaration can have the [`resource` modifier](#value-vs-resource).
* Reference may be nullable.
* Structs contain zero or more members.
#### Declaration
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="structs" %}
```
#### Use
Structs are denoted by their declared name (eg. **Circle**) and nullability:
* **`Circle`** : non-nullable Circle
* **`Circle?`** : nullable Circle
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="structs-use" %}
```
### Tables {#tables}
* Record type consisting of a sequence of typed fields with ordinals.
* Declaration is intended for forward and backward compatibility in the face of schema changes.
* Declaration can have the [`resource` modifier](#value-vs-resource).
* Tables cannot be nullable. The semantics of "missing value" is expressed by an empty table
i.e. where all members are absent, to avoid dealing with double nullability.
* Tables contain zero or more members.
#### Declaration
```fidl
table Profile {
1: vector<string> locales;
2: vector<string> calendars;
3: vector<string> time_zones;
};
```
#### Use
Tables are denoted by their declared name (eg. **Profile**):
* **`Profile`** : non-nullable Profile
Here, we show how `Profile` evolves to also carry temperature units.
A client aware of the previous definition of `Profile` (without temperature units)
can still send its profile to a server that has been updated to handle the larger
set of fields.
```fidl
enum TemperatureUnit {
CELSIUS = 1;
FAHRENHEIT = 2;
};
table Profile {
1: vector<string> locales;
2: vector<string> calendars;
3: vector<string> time_zones;
4: TemperatureUnit temperature_unit;
};
```
### Unions {#unions}
* Record type consisting of an ordinal and an envelope.
* Ordinal indicates member selection, envelope holds contents.
* Declaration can be modified after deployment, while maintaining ABI
compatibility. See the [Compatibility Guide][union-compat] for
source-compatibility considerations.
* Declaration can have the [`resource` modifier](#value-vs-resource).
* Reference may be nullable.
* Unions contain one or more members. A union with no members would have no
inhabitants and thus would make little sense in a wire format.
* Unions can either be [`strict` or `flexible`](#strict-vs-flexible).
<!-- TODO(fxbug.dev/64463): update default -->
* Unions default to `strict`.
#### Declaration
```fidl
{%includecode gerrit_repo="fuchsia/samples" gerrit_path="src/calculator/fidl/calculator.fidl" region_tag="union" %}
```
#### Use {#unions-use}
Unions are denoted by their declared name (e.g. **Result**) and nullability:
* **`Either`** : non-nullable Result
* **`Either?`** : nullable Result
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="unions-use" %}
```
### Strict vs. Flexible {#strict-vs-flexible}
FIDL declarations can either have **strict** or **flexible** behavior:
<!-- TODO(fxbug.dev/64463): Update this when defaults change. -->
* Bits, enums, and unions are strict unless declared with the `flexible`
modifier.
* Structs always have strict behavior.
* Tables always have flexible behavior.
For strict types only, serializing or deserializing a value that contains data
not described in the declaration is a [validation error][lexicon-validate].
In this example:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="strict-vs-flexible" %}
```
By virtue of being flexible, it is simpler for `FlexibleEither` to evolve to
carry a third variant. A client aware of the previous definition of
`FlexibleEither` without the third variant can still receive a union from a
server that has been updated to contain the larger set of variants. If the
union is of the unknown variant, bindings may expose it as unknown data (i.e. as
raw bytes and handles) to the user and allow re-encoding the unknown union (e.g.
to support proxy-like use cases). The methods provided for interacting with
unknown data for flexible types are described in detail in the [bindings
reference][bindings-reference].
More details are discussed in
[RFC-0033: Handling of Unknown Fields and Strictness][rfc-033].
Note: A type that is both flexible and a [value type](#value-vs-resource) will
not allow deserializing unknown data that contains handles.
### Value vs. Resource {#value-vs-resource}
Every FIDL type is either a **value type** or a **resource type**. Resource
types include:
* [handles](#handles)
* [protocol endpoints](#protocols-use)
* [aliases](#aliasing) of resource types
* arrays and vectors of resource types
* structs, tables, and unions marked with the `resource` modifier
* nullable references to any of the above types
All other types are value types.
Value types must not contain resource types. For example, this is incorrect:
```fidl
struct Foo { // ERROR: must be "resource struct Foo"
handle h;
};
```
Types can be marked with the `resource` modifier even if they do not contain
handles. You should do this if you intend to add handles to the type in the
future, since adding or removing the `resource` modifier requires
[source-compatibility considerations][resource-compat]. For example:
```fidl
// No handles now, but we will add some in the future.
resource table Record {
1: string str;
};
// "Foo" must be a resource because it contains "Record", which is a resource.
resource struct Foo {
Record record;
};
```
More details are discussed in [RFC-0057: Default No Handles][rfc-0057].
### Protocols {#protocols}
* Describe methods that can be invoked by sending messages over a channel.
* Methods are identified by their ordinal index. The compiler calculates the ordinal by
* Taking the SHA-256 hash of the string generated by concatenating:
* The UTF-8 encoded library name, with no trailing \0 character
* '.' (ASCII 0x2e)
* The UTF-8 encoded protocol name, with no trailing \0 character
* '/' (ASCII 0x2f)
* The UTF-8 encoded method name, with no trailing \0 character
* Extracting the upper 32 bits of the hash value, and
* Setting the upper bit of that value to 0.
* To coerce the compiler into generating a different value, methods can have
a `Selector` attribute. The value of the `Selector` attribute will be
used in the place of the method name above.
* Each method declaration states its arguments and results.
* If no results are declared, then the method is one-way: no response will
be generated by the server.
* If results are declared (even if empty), then the method is two-way:
each invocation of the method generates a response from the server.
* If only results are declared, the method is referred to as an
*event*. It then defines an unsolicited message from the server.
* Two-way methods may declare an error type that a server can send
instead of the response. This type must be an `int32`, `uint32`, or an
`enum` thereof.
* When a server of a protocol is about to close its side of the channel, it
may elect to send an **epitaph** message to the client to indicate the
disposition of the connection. The epitaph must be the last message
delivered through the channel. An epitaph message includes a 32-bit int
value of type **zx_status_t**. Negative values are reserved for system
error codes. Positive values are reserved for application errors. A status
of ZX_OK indicates successful operation.
#### Declaration
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="calculator" %}
```
#### Use {#protocols-use}
Protocols are denoted by their name, directionality of the channel, and
optionality:
* **`Protocol`** : non-nullable FIDL protocol (client endpoint of channel)
* **`Protocol?`** : nullable FIDL protocol (client endpoint of channel)
* **`request<Protocol>`** : non-nullable FIDL protocol
request (server endpoint of channel)
* **`request<Protocol>?`** : nullable FIDL protocol request
(server endpoint of channel)
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="endpoints" %}
```
### Protocol Composition {#protocol-composition}
A protocol can include methods from other protocols.
This is called composition: you compose one protocol from other protocols.
Composition is used in the following cases:
1. you have multiple protocols that all share some common behavior(s)
2. you have varying levels of functionality you want to expose to different audiences
#### Common behavior
In the first case, there might be behavior that's shared across multiple protocols.
For example, in a graphics system, several different protocols might all share a
common need to set a background and foreground color.
Rather than have each protocol define their own color setting methods, a common
protocol can be defined:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="composition-base" %}
```
It can then be shared by other protocols:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="composition-inherit" %}
```
In the above, there are three protocols, `SceneryController`, `Drawer`, and `Writer`.
`Drawer` is used to draw graphical objects, like circles and squares at given locations
with given sizes.
It composes the methods **SetBackground()** and **SetForeground()** from
the `SceneryController` protocol because it includes the `SceneryController` protocol
(by way of the `compose` keyword).
The `Writer` protocol, used to write text on the display, includes the `SceneryController`
protocol in the same way.
Now both `Drawer` and `Writer` include **SetBackground()** and **SetForeground()**.
This offers several advantages over having `Drawer` and `Writer` specify their own color
setting methods:
* the way to set background and foreground colors is the same, whether it's used
to draw a circle, square, or put text on the display.
* new methods can be added to `Drawer` and `Writer` without having to change their
definitions, simply by adding them to the `SceneryController` protocol.
The last point is particularly important, because it allows us to add functionality
to existing protocols.
For example, we might introduce an alpha-blending (or "transparency") feature to
our graphics system.
By extending the `SceneryController` protocol to deal with it, perhaps like so:
```fidl
protocol SceneryController {
SetBackground(Color color);
SetForeground(Color color);
SetAlphaChannel(int a);
};
```
we've now extended both `Drawer` and `Writer` to be able to support alpha blending.
#### Multiple compositions
Composition is not a one-to-one relationship &mdash; we can include multiple compositions
into a given protocol, and not all protocols need be composed of the same mix of
included protocols.
For example, we might have the ability to set font characteristics.
Fonts don't make sense for our `Drawer` protocol, but they do make sense for our `Writer`
protocol, and perhaps other protocols.
So, we define our `FontController` protocol:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="composition-multiple-1" %}
```
and then invite `Writer` to include it, by using the `compose` keyword:
```fidl
protocol Writer {
compose SceneryController;
compose FontController;
Text(int x, int y, string message);
};
```
Here, we've extended the `Writer` protocol with the `FontController` protocol's methods,
without disturbing the `Drawer` protocol (which doesn't need to know anything about fonts).
Protocol composition is similar to [mixin].
More details are discussed in [RFC-0023: Compositional Model][rfc-0023].
#### Layering
At the beginning of this section, we mentioned a second use for composition, namely
exposing various levels of functionality to different audiences.
In this example, we have two protocols that are independently useful, a `Clock` protocol
to get the current time and timezone:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="layering-clock" %}
```
And an `Horologist` protocol that sets the time and timezone:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="layering-horologist" %}
```
We may not necessarily wish to expose the more privileged `Horologist` protocol to just
any client, but we do want to expose it to the system clock component.
So, we create a protocol (`SystemClock`) that composes both:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="layering-systemclock" %}
```
### Aliasing {#aliasing}
Type aliasing is supported.
For example:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="aliasing" %}
```
In the above, the identifier `StoryID` is an alias for the declaration of a
`string` with a maximum size of `MAX_SIZE`. The identifier `Chapters` is an
alias for a vector declaration of five `StoryId` elements.
The identifiers `StoryID` and `Chapters` can be used wherever their aliased
definitions can be used.
Consider:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="aliasing-usage" %}
```
Here, the `Message` struct contains a string of `MAX_SIZE` bytes called `baseline`,
and a vector of up to `5` strings of `MAX_SIZE` called `chapters`.
Note that **`byte`** and **`bytes`** are built in aliases, [see below](#built-in-aliases).
### Built-ins
FIDL provides several built-ins:
* convenience types (**`byte`** and **`bytes`**)
* `zx library` [see below](#zx-library)
#### Built-in aliases {#built-in-aliases}
The types **`byte`** and **`bytes`** are built-in, and are conceptually
equivalent to:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference_builtin.test.fidl" region_tag="builtin" %}
```
When you refer to a name without specific scope, e.g.:
```fidl
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/fuchsia.examples.docs/language_reference.test.fidl" region_tag="builtin-aliases" %}
```
we treat this as `builtin.byte` automatically (so long as there isn't a
more-specific name in scope).
#### ZX Library {#zx-library}
The `fidlc` compiler automatically generates an internal [ZX library](library-zx.md)
for you that contains commonly used Zircon definitions.
<!-- xref -->
[mixin]: https://en.wikipedia.org/wiki/Mixin
[rfc-0023]: /docs/contribute/governance/rfcs/0023_compositional_model_protocols.md
[rfc-0033]: /docs/contribute/governance/rfcs/0033_handling_unknown_fields_strictness.md
[rfc-0057]: /docs/contribute/governance/rfcs/0057_default_no_handles.md
[fidl-overview]: /docs/concepts/fidl/overview.md
[fidl-grammar]: /docs/reference/fidl/language/grammar.md
[doc-attribute]: /docs/reference/fidl/language/attributes.md#Doc
[naming-style]: /docs/development/languages/fidl/guides/style.md#Names
[union-compat]: /docs/development/languages/fidl/guides/compatibility/README.md#union
[resource-compat]: /docs/development/languages/fidl/guides/compatibility/README.md#modifiers
[bindings-reference]: /docs/reference/fidl/bindings/overview.md
[lexicon-validate]: /docs/reference/fidl/language/lexicon.md#validate