This is the grammar for FIDL source files. The grammar is expressed in a modified BNF format.
A nonterminal symbol matches a sequence of other symbols, delimited by commas.
nonterminal = list , of , symbols ;
Some symbols are terminals, which are either in all caps or are in double quotes.
another-nonterminal = THESE , ARE , TERMINALS , AND , SO , IS , "this" ;
Alternation is expressed with a pipe.
choice = this | that | the-other ;
An option (zero or one) is expressed with parentheses.
optional = ( maybe , these ) , but , definitely , these ;
Repetition (zero or more) is expressed with parentheses and a star.
zero-or-more = ( list-part )* ;
Repetition (one or more) is expressed with parentheses and a plus.
one-or-more = ( list-part )+ ;
Whitespace and comments are ignored during lexing, and thus not present in the following grammar.
Comments can start with two slashes (‘//’) or three slashes (‘///’), or they can be embodied within a [Doc]
attribute. The three-slash variant and the [Doc]
attribute behave the same way, propagating the comments to the generated target.
The fidldoc tool processes comments propagated into the JSON-based Intermediate Representation (IR) to generate reference documentation pages for FIDL files.
See the FIDL style guide for more details on comments.
file
is the starting symbol.
file = library-header , ( using-list ) , declaration-list ; library-header = ( attribute-list ) , "library" , compound-identifier , ";" ; using-list = ( using , ";" )* ; using = "using" , compound-identifier , ( "as" , IDENTIFIER ) ; compound-identifier = IDENTIFIER ( "." , IDENTIFIER )* ; declaration-list = ( declaration , ";" )* ; declaration = const-declaration | layout-declaration | protocol-declaration | type-alias-declaration | resource-declaration | service-declaration ; const-declaration = ( attribute-list ) , "const" , IDENTIFIER , type-constructor , "=" , constant ; layout-declaration = ( attribute-list ) , "type" , IDENTIFIER , "=" , inline-layout ; [NOTE 1] inline-layout = ( attribute-list ) , ( declaration-modifiers )* , layout-kind , ( layout-subtype ) , layout-body ; declaration-modifiers = "flexible" | "strict" | "resource" ; [NOTE 2] layout-subtype = ":" , type-constructor ; [NOTE 3] layout-kind = "struct" | "bits" | "enum" | "union" | "table" ; layout-body = value-layout | struct-layout | ordinal-layout ; value-layout = "{" , ( value-layout-member , ";" )+ , "}" ; value-layout-member = ( attribute-list ) , IDENTIFIER , "=" , constant ; [NOTE 4] struct-layout = "{" , ( struct-layout-member, ";" )* , "}" ; struct-layout-member = ( attribute-list ) , member-field ; ordinal-layout = "{" , ( ordinal-layout-member , ";" )* , "}" ; [NOTE 5] ordinal-layout-member = ( attribute-list ) , ordinal , ":" , member-field ; [NOTE 6] protocol-declaration = ( attribute-list ) , "protocol" , IDENTIFIER , "{" , ( protocol-member , ";" )* , "}" ; protocol-member = protocol-method | protocol-event | protocol-compose ; protocol-method = ( attribute-list ) , IDENTIFIER , parameter-list, ( "->" , parameter-list , ( "error" type-constructor ) ) ; [NOTE 7] protocol-event = ( attribute-list ) , "->" , IDENTIFIER , parameter-list ; parameter-list = "(" , ( type-constructor ) , ")" ; [NOTE 8] protocol-compose = "compose" , compound-identifier ; type-alias-declaration = ( attribute-list ) , "alias" , IDENTIFIER , "=" , type-constructor ; resource-declaration = ( attribute-list ) , "resource_definition" , IDENTIFIER , ":", "uint32" , "{" , resource-properties , "}" ; resource-properties = "properties" , "{" , ( member-field , ";" )* , "}" , ";" service-declaration = ( attribute-list ) , "service" , IDENTIFIER , "{" , ( service-member , ";" )* , "}" ; service-member = ( attribute-list ) , member-field ; [NOTE 9] member-field = IDENTIFIER , type-constructor ; attribute-list = ( attribute )* ; attribute = "@", IDENTIFIER , ( "(" , constant | attribute-args, ")" ) ; attribute-args = attribute-arg | attribute-arg, "," attribute-args ; attribute-arg = IDENTIFIER , "=" , constant ; type-constructor = layout , ( "<" , layout-parameters , ">" ) , ( ":" type-constraints ) ; layout = compound-identifier | inline-layout ; layout-parameters = layout-parameter | layout-parameter , "," , layout-parameters ; layout-parameter = type-constructor | constant ; type-constraints = type-constraint | "<" type-constraint-list ">" ; type-constraint-list = type-constraint | type-constraint , "," , type-constraint-list ; type-constraint = constant ; constant = compound-identifier | literal ; ordinal = NUMERIC-LITERAL ; literal = STRING-LITERAL | NUMERIC-LITERAL | "true" | "false" ;
STRING-LITERAL
The grammar for STRING-LITERAL
is as follows:
STRING-LITERAL = "\"" ( unicode-value )* "\"" ; unicode-value = literal-char | escaped-basic | escaped-unicode ; literal-char = any unicode character except CR, LF, "\" or "\"" ; escaped-basic = "\" ( "\" | "\"" | "n" | "r" | "t" ) ; escaped-unicode = "\u{" ( hex-digit ){1,6} "}" ;
Attributes for an anonymous layout introduction can be placed in one of two locations:
type
keyword, orinline-layout
.Placing attributes in both locations for a single layout definition is not allowed by the compiler.
The grammar allows ( declaration-modifiers )*
on all declarations, but the compiler limits this as follows:
flexible
and strict
modifiers cannot be used together.flexible
and strict
modifiers can only be used when the layout-kind
is bits
, enum
, or union
.resource
modifier can only be when the layout-kind
is struct
, table
, or union
.The grammar allows ( layout-subtype )
on all declarations, but the compiler limits this to only be allowed when the layout-kind
is bits
or enum
.
Further, layout-subtype
allows the more liberal type-constructor
in the grammar, but the compiler limits this to signed or unsigned integer types (see primitives) for enums and unsigned integer types for bits.
The value-layout-member
allows the more liberal constant
in the grammar, but the compiler limits the values the constant
may take:
subtype
, in the context of an enum
.subtype
and is a power of two, in the context of a bits
.The ordinal-layout
grammar allows any number of members, but strict unions specifically must have at least one member.
Also, though ordinals can be any numeric literal, the compiler enforces that the specified ordinals for any union or table cover a contiguous range starting from 1.
The protocol-method
error stanza allows the more liberal type-constructor
in the grammar, but the compiler limits this to an int32
, uint32
, or an enum thereof.
The parameter-list
allows the more liberal type-constructor
in the grammar, but the compiler only supports layouts that are structs, tables, or unions.
The service-member
allows the more liberal type-constructor
in the grammar, but the compiler limits this to protocols.