= Language Reference
:toc:
:numbered:

The specification language describes protocol message formats based on types. For each type of the specification language a description of its syntax and semantics and an example is given. A simple variant of Backus-Naur Form is used to describe the syntax. Reserved keywords and literals are marked in *bold*. References to syntactic categories are xref:none[highlighted]. To convey some semantic information the name of some syntactic categories are prefixed by a non-highlighted part. Syntactic categories with prefixes are equivalent to the category without the prefix. The following basic elements are used to describe the syntax of the language:

[[syntax-name]]name: A name consists of alphanumeric characters and underscores. By convention a name starts with a capital and after each underscore follows a capital as well (e.g., `Mixed_Case_With_Underscores`).

[[syntax-number]]number: A number consists of numerical digits. An underscore can be added between two digits to improve readability (e.g., `1_234`).

[[syntax-string]]string: A string literal is a sequence of characters delimited by double quotes (e.g., `"String"`).

[[syntax-mathematical_expression]]mathematical_expression: A mathematical expression consists of numbers and names combined by mathematical operators (addition *+*, subtraction *-*, multiplication *\**, division */*, exponentiation **********).

[[syntax-boolean_expression]]boolean_expression: A boolean expression consists of relations (*<*, *<=*, *=*, */=*, *>=*, *>*) between names and numbers combined by boolean operators (conjunction *and*, disjunction *or*).

The type system is inspired by Ada, but differs in some details. In contrast to Ada, integer variables are considered type-compatible. Explicit type conversions of integer variables are neither required nor supported.

// Types [§T]

== Scalar Types

=== Integer Types

// Integers [§T-I]
// Modular Integers [§T-I-M]
// Range Integers [§T-I-R]

An integer type is used to represent numbers. Two types of integers are supported: modular type and range type.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-modular_type]]modular_type ::= *type* xref:syntax-name[name] *is* *mod* xref:syntax-modulus[modulus]

[[syntax-range_type]]range_type ::= *type* xref:syntax-name[name] *is* *range* xref:syntax-first[first] *..* xref:syntax-last[last] *with Size =>* xref:syntax-number[number]

[[syntax-modulus]]modulus ::= xref:syntax-mathematical_expression[mathematical_expression]

[[syntax-first]]first ::= xref:syntax-mathematical_expression[mathematical_expression]

[[syntax-last]]last ::= xref:syntax-mathematical_expression[mathematical_expression]
----

*Static Semantics*

A modular type represents the values from 0 to one less than the xref:syntax-modulus[modulus]. The bit size of a modular type is determined by calculating the binary logarithm of xref:syntax-modulus[modulus].

The set of values of a range type consists of all numbers from the lower bound to the upper bound. For a range type the bit size has to be specified explicitly.

*Example*

[source,ada,rflx,basic_declaration]
----
type Address is mod 2**48
----
[source,ada,rflx,basic_declaration]
----
type Type_Length is range 46 .. 2**16 - 1 with Size => 16
----

=== Enumeration Types

// Enumerations [§T-E]

An enumeration type represents a value out of a list of possible values.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-enumeration_type]]enumeration_type ::= *type* xref:syntax-name[name] *is* *(* xref:syntax-literals[literals] *)* *with* xref:syntax-enumeration_aspects[enumeration_aspects]

[[syntax-literals]]literals ::= xref:syntax-literal[literal] { **,** xref:syntax-literal[literal] }

[[syntax-literal]]literal ::= xref:syntax-name[name] [*=>* xref:syntax-number[number]]

[[syntax-enumeration_aspects]]enumeration_aspects ::= xref:syntax-enumeration_aspect[enumeration_aspect] { **,** xref:syntax-enumeration_aspect[enumeration_aspect] }

[[syntax-enumeration_aspect]]enumeration_aspect ::= xref:syntax-size_aspect[size_aspect] | xref:syntax-always_valid_aspect[always_valid_aspect]

[[syntax-always_valid_aspect]]always_valid_aspect ::= *Always_Valid* [ *=>* ( *True* | *False* ) ]
----

*Static Semantics*

The set of values of an enumeration type consists of the list of declared enumeration literals. Each enumeration literal has a distinct value. If no explicit value is given, the first literal is zero, and the value of each subsequent literal is incremented by one. Literals with and without explicit value must not be intermixed in one definition. The bit size of the enumeration type must be specified explicitly. Optionally, an enumeration type can be flagged as always valid. A message field with such type is always considered valid, whether or not its value corresponds to one of the specified literals.

*Example*

[source,ada,rflx,basic_declaration]
----
type Tag is (Msg_Error, Msg_Data) with Size => 1
----
[source,ada,rflx,basic_declaration]
----
type Ether_Type is
   (ET_IPv4            => 16#0800#,
    ET_ARP             => 16#0806#,
    ET_VLAN_Tag        => 16#8100#,
    ET_IPv6            => 16#86DD#,
    ET_VLAN_Tag_Double => 16#9100#)
with Size => 16, Always_Valid
----

=== Boolean

// Booleans [§T-B]

`Boolean` is a built-in enumeration type with the literals `False => 0` and `True => 1` with a size of 1 bit.

== Message Types

// Messages [§T-M]

A message type is a collection of fields. Additional xref:syntax-then_clause[then clauses] enable the definition of conditions and dependencies between fields.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-message_type]]message_type ::=
   *type* xref:syntax-name[name] *is*
    ( *message*
       [ xref:syntax-null_field[null_field] ]
         xref:syntax-field[field]
       { xref:syntax-field[field] }
      *end message* [ *with*
         xref:syntax-message_aspects[message_aspects] ]
    | *null message* )

[[syntax-type_name]]type_name ::= xref:syntax-qualified_name[qualified_name]

[[syntax-field]]field ::=
   field_xref:syntax-name[name] *:* xref:syntax-type_name[type_name]
    [ *with* xref:syntax-aspects[aspects] ]
    [ *if* xref:syntax-condition[condition] ]
    { xref:syntax-then_clause[then_clause] } *;*

[[syntax-null_field]]null_field ::= *null* xref:syntax-then_clause[then_clause] *;*

[[syntax-then_clause]]then_clause ::=
   *then* field_xref:syntax-name[name]
    [ *with* xref:syntax-aspects[aspects] ]
    [ *if* xref:syntax-condition[condition] ]

[[syntax-aspects]]aspects ::= xref:syntax-aspect[aspect] { *,* xref:syntax-aspect[aspect] }

[[syntax-aspect]]aspect ::= xref:syntax-first_aspect[first_aspect] | xref:syntax-size_aspect[size_aspect]

[[syntax-first_aspect]]first_aspect ::= *First* *=>* xref:syntax-mathematical_expression[mathematical_expression]

[[syntax-size_aspect]]size_aspect ::= *Size* *=>* xref:syntax-mathematical_expression[mathematical_expression]

[[syntax-condition]]condition ::= xref:syntax-boolean_expression[boolean_expression]

[[syntax-message_aspects]]message_aspects ::= xref:syntax-message_aspect[message_aspect] { *,* xref:syntax-message_aspect[message_aspect] }

[[syntax-message_aspect]]message_aspect ::= xref:syntax-checksum_aspect[checksum_aspect]

[[syntax-checksum_aspect]]checksum_aspect ::= *Checksum* *=>* *(* xref:syntax-checksum_definition[checksum_definition] { *,* xref:syntax-checksum_definition[checksum_definition] } *)*

[[syntax-checksum_definition]]checksum_definition ::= xref:syntax-name[name] *=>* *(* xref:syntax-checksum_element[checksum_element] { *,* xref:syntax-checksum_element[checksum_element] } *)*

[[syntax-checksum_element]]checksum_element ::= xref:syntax-name[name] | xref:syntax-name[name]*'Size* | xref:syntax-field_range[field_range]

[[syntax-field_range]]field_range ::= xref:syntax-field_range_first[field_range_first] *..* xref:syntax-field_range_last[field_range_last]

[[syntax-field_range_first]]field_range_first ::= xref:syntax-name[name]*'First* | xref:syntax-name[name]*'Last + 1*

[[syntax-field_range_last]]field_range_last ::= xref:syntax-name[name]*'Last* | xref:syntax-name[name]*'First - 1*
----

*Static Semantics*

A message type specifies the message format of a protocol. A message is represented by a graph-based model. Each node in the graph corresponds to one field in a message. The links in the graph define the order of the fields. A link is represented by a then clause in the specification. If no then clause is given, it is assumed that always the next field of the message follows. If no further field follows, it is assumed that the message ends with this field. The end of a message can also be denoted explicitly by adding a then clause to __null__. Optionally, a then clause can contain a condition under which the corresponding field follows and aspects which enable the definition of the size of the next field and the location of its first bit. These aspects can also be specified for the field directly. Each aspect can be specified either for the field or in all incoming then clauses, but not in both. The condition can refer to previous fields (including the field containing the then clause). A condition can also be added for the field directly. A field condition is equivalent to adding a condition to all then clauses. If a field condition as well as a condition at a then clause exists, both conditions are combined by a logical conjunction. If required, a null field can be used to specify the size of the first field in the message. An empty message can be represented by a null message.

The field type `Opaque` represents an unconstrained sequence of bytes. The size of opaque fields must be always defined by a size aspect. Opaque fields and sequence fields must be byte aligned. The size of a message must be a multiple of 8 bit.

A checksum aspect specifies which parts of a message is covered by a checksum. The definition of the checksum calculation is not part of the specification. Code based on the message specification must provide a function which is able to verify a checksum using the specified checksum elements. A checksum element can be a field value, a field size or a range of fields. The point where a checksum should be checked during parsing or generated during serialization must be defined for each checksum. For this purpose the `Valid_Checksum` attribute is added to a condition. All message parts on which the checksum depends have to be known at this point.

*Example*

[source,ada,rflx,basic_declaration]
----
type Frame is
   message
      Destination : Address;
      Source : Address;
      Type_Length_TPID : Type_Length
         then TPID
            with First => Type_Length_TPID'First
            if Type_Length_TPID = 16#8100#
         then Payload
            with Size => Type_Length_TPID * 8
            if Type_Length_TPID <= 1500
         then Ether_Type
            with First => Type_Length_TPID'First
            if Type_Length_TPID >= 1536 and Type_Length_TPID /= 16#8100#;
      TPID : TPID;
      TCI : TCI;
      Ether_Type : Ether_Type
         then Payload
            with Size => Message'Last - Ether_Type'Last;
      Payload : Opaque
         then null
            if Payload'Size / 8 >= 46 and Payload'Size / 8 <= 1500;
   end message
----
[source,ada,rflx,basic_declaration]
----
type Empty_Message is null message
----

== Type Refinements

// Type Refinements [§T-R]

A type refinement describes the relation of an opaque field in a message type to another message type.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-type_refinement]]type_refinement ::=
   *for* refined_xref:syntax-type_name[type_name] *use* **( **refined_field_xref:syntax-name[name] **=>** message_xref:syntax-type_name[type_name] **)**
    [ **if** xref:syntax-condition[condition] ]

[[syntax-qualified_name]]qualified_name ::= xref:syntax-name[name] { **::** xref:syntax-name[name] }

[[syntax-condition]]condition ::= xref:syntax-boolean_expression[boolean_expression]
----

*Static Semantics*

A type refinement describes under which condition a specific message can be expected inside of a payload field. Only fields of type `Opaque` can be refined. Types defined in other packages are referenced by a qualified name in the form `Package_Name::Message_Type_Name`. The condition can refer to fields of the refined type. To indicate that a refined field is empty (i.e. does not exit) under a certain condition, a null message can be used as message type.

*Example*

[source,ada,rflx,basic_declaration]
----
for Ethernet::Frame use (Payload => IPv4::Packet)
   if Ether_Type = Ethernet::IPV4
----

== Type Derivations

// Derived Messages [§T-D]

A type derivation enables the creation of a new message type based on an existing message type.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-type_derivation]]type_derivation ::= *type* xref:syntax-name[name] *is new* xref:syntax-base_type_name[base_type_name]

[[syntax-base_type_name]]base_type_name ::= xref:syntax-qualified_name[qualified_name]
----

*Static Semantics*

A derived message type derives its specification from a base type. Type refinements of a base message type are not inherited by the derived message type.

*Example*

[source,ada,rflx,basic_declaration]
----
type Specific_Extension is new Extension
----

== Sequence Types

// Sequences [§T-S]

A sequence type represents a list of similar elements.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-sequence_type]]sequence_type ::= *type* xref:syntax-name[name] *is sequence of* element_xref:syntax-type_name[type_name]
----

*Static Semantics*

A sequence consists of a number of elements with similar type. Scalar types as well as message types can be used as element type. When a sequence is used in a message type, its bit length has to be specified by a size aspect.

// Sequence of scalars [§T-S-S]
// Sequence of messages [§T-S-M]

*Example*

[source,ada,rflx,basic_declaration]
----
type Options is sequence of Option
----

== Protocol Sessions

// Protocol Sessions [§S]

A session defines the dynamic behavior of a protocol using a finite state machine. The external interface of a session is defined by parameters. The initial and final state is defined by aspects. The declaration part enables the declaration of session global variables. The main part of a session definition are the state definitions.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-session]]session ::=
   *generic*
    { xref:syntax-session_parameter[session_parameter] }
   *session* xref:syntax-name[name] *with*
      *Initial =>* state_xref:syntax-name[name],
      *Final =>* state_xref:syntax-name[name]
   *is*
    { xref:syntax-session_declaration[session_declaration] }
   *begin*
      xref:syntax-state[state]
    { xref:syntax-state[state] }
   *end* xref:syntax-name[name]
----

*Example*

[source,ada,rflx,basic_declaration]
----
generic
   X : Channel with Readable, Writable;
   type T is private;
   with function F return T;
   with function G (P : T) return Boolean;
session S with
   Initial => A,
   Final => B
is
   Y : Boolean := False;
begin
   state A
      with Desc => "rfc1149.txt+51:4-52:9"
   is
      Z : Boolean := Y;
      M : TLV::Message;
   begin
      X'Read (M);
   transition
      then B
         with Desc => "rfc1149.txt+45:4-47:8"
         if Z = True
            and G (F) = True
      then A
   end A;

   state B is null state;
end S
----

=== Session Parameters

// Session Parameters [§S-P]

Private types, functions and channels can be defined as session parameters.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-session_parameter]]session_parameter ::= ( xref:syntax-private_type_declaration[private_type_declaration] | xref:syntax-function_declaration[function_declaration] | xref:syntax-channel_declaration[channel_declaration] ) *;*
----

==== Private Types

// Private Types [§S-P-P]

A private type represents an externally defined type.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-private_type_declaration]]private_type_declaration ::= *type* xref:syntax-name[name] *is private*
----

*Example*

[source,ada,rflx,session_parameter]
----
type Hash is private
----

==== Functions

// Functions [§S-P-F]

Functions enable the execution of externally defined code.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-function_declaration]]function_declaration ::= *with function* xref:syntax-name[name] [ *(* xref:syntax-parameter[parameter] { *,* xref:syntax-parameter[parameter] } *)* ]

[[syntax-parameter]]parameter ::= parameter_xref:syntax-name[name] *:* xref:syntax-type_name[type_name]
----

*Static Semantics*

Allowed parameter types:

* Scalars
* Definite messages
* Opaque fields of messages

// Allowed parameter types [§S-P-F-P]
//
// * Scalars [§S-P-F-P-S]
// * Definite messages [§S-P-F-P-M]
// * Opaque fields of messages [§S-P-F-P-O]

Allowed return types:

* Scalars
* Definite messages

// Allowed return types [§S-P-F-R]:
//
// * Scalars [§S-P-F-R-S]
// * Definite messages [§S-P-F-R-M]

Definite messages are messages with no optional fields and a bounded size (i.e. all size aspects contain no reference to `Message`).

*SPARK*

For each function declaration in the session specification a formal procedure declaration is added to the corresponding generic session package. The return type and parameters of a function are represented by the first and subsequent parameters of the generated procedure declaration.

*Example*

[source,ada,rflx,session_parameter]
----
with function Decrypt (Key_Update_Message : Key_Update_Message; Sequence_Number : Sequence_Number; Encrypted_Record : Opaque) return TLS_Inner_Plaintext
----

==== Channels

// Channels [§S-P-C]

Channels provide a way for communicating with other systems using messages.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-channel_declaration]]channel_declaration ::= xref:syntax-name[name] *: Channel with* xref:syntax-channel_aspect[channel_aspect] { *,* xref:syntax-channel_aspect[channel_aspect] }

[[syntax-channel_aspect]]channel_aspect ::= *Readable* | *Writable*
----

*Static Semantics*

Channels can be readable or writable (non-exclusive).

// * Readable [§S-P-C-R]
// * Writable [§S-P-C-W]
// * Readable and writable [§S-P-C-RW]

*Example*

[source,ada,rflx,session_parameter]
----
Data_Channel : Channel with Readable, Writable
----

=== Declarations

// Declarations [§S-D]

Variables and renamings can be globally declared (i.e. for the scope of the complete session).

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-session_declaration]]session_declaration ::= ( xref:syntax-variable_declaration[variable_declaration] | xref:syntax-renaming_declaration[renaming_declaration] ) **;**
----

==== Variable Declaration

// Variable Declaration [§S-D-V]

A declared variable must have a type and can be optionally initialized using an expression.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-variable_declaration]]variable_declaration ::= variable_xref:syntax-name[name] *:* xref:syntax-type_name[type_name] [ *:=* initialization_xref:syntax-expression[expression] ]
----

// *Static Semantics*
//
// Types [§S-D-V-T]:
//
// * Scalar [§S-D-V-T-SC]
// * Message [§S-D-V-T-M]
// * Scalar Sequence [§S-D-V-T-SS]
// * Message Sequence [§S-D-V-T-MS]
//
// Initialization expressions [§S-D-V-E]:
//
// * No initialization [§S-D-V-E-N]
// * Mathematical Expressions [§S-D-V-E-ME]
// * Boolean Expressions [§S-D-V-E-BE]
// * Literals [§S-D-V-E-L]
// * Variables [§S-D-V-E-V]
// * Message Aggregates [§S-D-V-E-MA]
// * Aggregates [§S-D-V-E-A]
// * Valid Attributes [§S-D-V-E-VAT]
// * Opaque Attributes [§S-D-V-E-OAT]
// * Head Attributes [§S-D-V-E-HAT]
// * Has_Data Attributes [§S-D-V-E-HDAT]
// * Selected Expressions [§S-D-V-E-S]
// * List Comprehensions [§S-D-V-E-LC]
// * Bindings [§S-D-V-E-B]
// * Quantified Expressions [§S-D-V-E-Q]
// * Calls [§S-D-V-E-CL]
// * Conversions [§S-D-V-E-CV]

*Example*

[source,ada,rflx,declaration]
----
Error_Sent : Boolean := False
----

==== Renaming Declaration

// Renaming Declaration [§S-D-R]

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-renaming_declaration]]renaming_declaration ::= xref:syntax-name[name] *:* message_xref:syntax-type_name[type_name] *renames* message_variable_xref:syntax-name[name] *.* field_xref:syntax-name[name]
----

*Example*

[source,ada,rflx,declaration]
----
Client_Hello_Message : TLS_Handshake::Client_Hello renames Client_Hello_Handshake_Message.Payload
----

=== States

// States [§S-S]

A state defines the to be executed actions and the transitions to subsequent states.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-state]]state ::=
   *state* xref:syntax-name[name]
    [ *with* xref:syntax-description_aspect[description_aspect] ]
   *is*
    { xref:syntax-state_declaration[state_declaration] }
   *begin*
    { xref:syntax-state_action[state_action] }
   *transition*
    { xref:syntax-conditional_transition[conditional_transition] }
      xref:syntax-transition[transition]
 [ *exception*
     xref:syntax-transition[transition] ]
   *end* xref:syntax-name[name]
 | *state* xref:syntax-name[name] *is null state*

[[syntax-description_aspect]]description_aspect ::= *Desc =>* xref:syntax-string[string]
----

*Static Semantics*

// Exception Transition [§S-S-E]

An exception transition must be defined just in case any action might lead to a critical (potentially non-recoverable) error:

* Insufficient memory for setting a field of a message
* Insufficient memory for appending an element to a sequence or extending a sequence by another sequence

Exception transitions are currently also used for other cases. This behavior will change in the future (cf. https://github.com/Componolit/RecordFlux/issues/569[#569]).

// Null State [§S-S-N]

A null state does not contain any actions or transitions, and represents the final state of a session state machine.

*Dynamic Semantics*

After entering a state the declarations and actions of the state are executed. If a non-recoverable error occurs, the execution is aborted and the state is changed based on the exception transition. When all action were executed successfully, the conditions of the transitions are checked in the given order. If a condition is fulfilled, the corresponding transition is taken to change the state. If no condition could be fulfilled or no conditional transitions were defined, the default transition is used.

*Example*

[source,ada,rflx,state]
----
state A
   with Desc => "rfc1149.txt+51:4-52:9"
is
   Z : Boolean := Y;
   M : TLV::Message;
begin
   X'Read (M);
transition
   then B
      with Desc => "rfc1149.txt+45:4-47:8"
      if Z = True and G (F) = True
   then A
end A
----
[source,ada,rflx,state]
----
state B is null state
----

==== State Declarations

// State Declarations [§S-S-D]
// Variable declarations [§S-S-D-V]
// Renaming declarations [§S-S-D-R]

Variable declarations and renaming declarations in a state have a state-local scope, i.e., local declarations cannot be accessed from other states.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-state_declaration]]state_declaration ::= ( xref:syntax-variable_declaration[variable_declaration] | xref:syntax-renaming_declaration[renaming_declaration] ) *;*
----

*Static Semantics*

A local declaration must not hide a global declaration.

// Types [§S-S-D-V-T]:
//
// * Scalar [§S-S-D-V-T-SC]
// * Message [§S-S-D-V-T-M]
// * Scalar Sequence [§S-S-D-V-T-SS]
// * Message Sequence [§S-S-D-V-T-MS]
//
// Initialization expressions [§S-S-D-V-E]:
//
// * No initialization [§S-S-D-V-E-N]
// * Mathematical Expressions [§S-S-D-V-E-ME]
// * Boolean Expressions [§S-S-D-V-E-BE]
// * Literals [§S-S-D-V-E-L]
// * Variables [§S-S-D-V-E-V]
// * Message Aggregates [§S-S-D-V-E-MA]
// * Aggregates [§S-S-D-V-E-A]
// * Valid Attributes [§S-S-D-V-E-VAT]
// * Opaque Attributes [§S-S-D-V-E-OAT]
// * Head Attributes [§S-S-D-V-E-HAT]
// * Has_Data Attributes [§S-S-D-V-E-HDAT]
// * Selected Expressions [§S-S-D-V-E-S]
// * List Comprehensions [§S-S-D-V-E-LC]
// * Bindings [§S-S-D-V-E-B]
// * Quantified Expressions [§S-S-D-V-E-Q]
// * Calls [§S-S-D-V-E-CL]
// * Conversions [§S-S-D-V-E-CV]

==== State Transitions

// State Transitions [§S-S-T]

State transitions define the conditions for the change to subsequent states. An arbitrary number of conditional transitions can be defined. The last transition in a state definition is the default transition, which does not contain any condition.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-conditional_transition]]conditional_transition ::=
   xref:syntax-transition[transition]
      *if* conditional_xref:syntax-expression[expression]

[[syntax-transition]]transition ::=
   *then* state_xref:syntax-name[name]
    [ *with* xref:syntax-description_aspect[description_aspect] ]
----

// *Static Semantics*
//
// Condition expressions:
//
// * No condition [§S-S-T-N]
// * Mathematical Expressions [§S-S-T-ME]
// * Boolean Expressions [§S-S-T-BE]
// * Literals [§S-S-T-L]
// * Variables [§S-S-T-V]
// * Message Aggregates [§S-S-T-MA]
// * Aggregates [§S-S-T-A]
// * Valid Attributes [§S-S-T-VAT]
// * Opaque Attributes [§S-S-T-OAT]
// * Head Attributes [§S-S-T-HAT]
// * Has_Data Attributes [§S-S-T-HDAT]
// * Selected Expressions [§S-S-T-S]
// * List Comprehensions [§S-S-T-LC]
// * Bindings [§S-S-T-B]
// * Quantified Expressions [§S-S-T-Q]
// * Calls [§S-S-T-CL]
// * Conversions [§S-S-T-CV]

*Example*

[source,ada,rflx,conditional_transition]
----
then B
   with Desc => "rfc1149.txt+45:4-47:8"
   if Z = True and G (F) = True
----

==== State Actions

// State Actions [§S-S-A]

The state actions are executed after entering a state.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-state_action]]state_action ::= ( xref:syntax-assignment[assignment] | xref:syntax-append[append] | xref:syntax-extend[extend] | xref:syntax-reset[reset] | xref:syntax-read[read] | xref:syntax-write[write] ) *;*
----

===== Assignment Statements

// Assignment Statements [§S-S-A-A]

An assignment sets the value of variable.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-assignment]]assignment ::= variable_xref:syntax-name[name] *:=* xref:syntax-expression[expression]
----

// *Static Semantics*
//
// Expressions:
//
// * Mathematical Expressions [§S-S-A-A-ME]
// * Boolean Expressions [§S-S-A-A-BE]
// * Literals [§S-S-A-A-L]
// * Variables [§S-S-A-A-V]
// * Message Aggregates [§S-S-A-A-MA]
// * Aggregates [§S-S-A-A-A]
// * Valid Attributes [§S-S-A-A-VAT]
// * Opaque Attributes [§S-S-A-A-OAT]
// * Head Attributes [§S-S-A-A-HAT]
// * Has_Data Attributes [§S-S-A-A-HDAT]
// * Selected Expressions [§S-S-A-A-S]
// * List Comprehensions [§S-S-A-A-LC]
// * Bindings [§S-S-A-A-B]
// * Quantified Expressions [§S-S-A-A-Q]
// * Calls [§S-S-A-A-CL]
// * Conversions [§S-S-A-A-CV]

*Dynamic Semantics*

An assignment always creates a copy of the original object.

*Example*

[source,ada,rflx,assignment_statement]
----
Error_Sent := True
----

===== Append Attribute Statements

// Append Attribute Statements [§S-S-A-AP]

An element is added to the end of a sequence using the Append attribute.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-append]]append ::= sequence_xref:syntax-name[name]*'Append (* xref:syntax-expression[expression] *)*
----

// *Static Semantics*
//
// Expressions:
//
// * Mathematical Expressions [§S-S-A-AP-ME]
// * Boolean Expressions [§S-S-A-AP-BE]
// * Literals [§S-S-A-AP-L]
// * Variables [§S-S-A-AP-V]
// * Message Aggregates [§S-S-A-AP-MA]
// * Aggregates [§S-S-A-AP-A]
// * Valid Attributes [§S-S-A-AP-VAT]
// * Opaque Attributes [§S-S-A-AP-OAT]
// * Head Attributes [§S-S-A-AP-HAT]
// * Has_Data Attributes [§S-S-A-AP-HDAT]
// * Selected Expressions [§S-S-A-AP-S]
// * List Comprehensions [§S-S-A-AP-LC]
// * Bindings [§S-S-A-AP-B]
// * Quantified Expressions [§S-S-A-AP-Q]
// * Calls [§S-S-A-AP-CL]
// * Conversions [§S-S-A-AP-CV]

*Dynamic Semantics*

Appending an element to a sequence might lead to an exception transition.

*Example*

[source,ada,rflx,attribute_statement]
----
Parameter_Request_List'Append (DHCP::Domain_Name_Option)
----

===== Extend Attribute Statements

// Extend Attribute Statements [§S-S-A-EX]

The Extend attributes adds a sequence of elements to the end of a sequence.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-extend]]extend ::= sequence_xref:syntax-name[name]*'Extend (* xref:syntax-expression[expression] *)*
----

// *Static Semantics*
//
// Expressions:
//
// * Mathematical Expressions [§S-S-A-EX-ME]
// * Boolean Expressions [§S-S-A-EX-BE]
// * Literals [§S-S-A-EX-L]
// * Variables [§S-S-A-EX-V]
// * Message Aggregates [§S-S-A-EX-MA]
// * Aggregates [§S-S-A-EX-A]
// * Valid Attributes [§S-S-A-EX-VAT]
// * Opaque Attributes [§S-S-A-EX-OAT]
// * Head Attributes [§S-S-A-EX-HAT]
// * Has_Data Attributes [§S-S-A-EX-HDAT]
// * Selected Expressions [§S-S-A-EX-S]
// * List Comprehensions [§S-S-A-EX-LC]
// * Bindings [§S-S-A-EX-B]
// * Quantified Expressions [§S-S-A-EX-Q]
// * Calls [§S-S-A-EX-CL]
// * Conversions [§S-S-A-EX-CV]

*Dynamic Semantics*

Extending a sequence might lead to an exception transition.

*Example*

[source,ada,rflx,attribute_statement]
----
Parameter_Request_List'Extend (Parameters)
----

===== Reset Attribute Statements

// Reset Attribute Statements [§S-S-A-RS]

The state of a message or sequence can be cleared using the Reset attribute.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-reset]]reset ::= xref:syntax-name[name]*'Reset*
----

// *Static Semantics*
//
// Expressions:
//
// * Mathematical Expressions [§S-S-A-RS-ME]
// * Boolean Expressions [§S-S-A-RS-BE]
// * Literals [§S-S-A-RS-L]
// * Variables [§S-S-A-RS-V]
// * Message Aggregates [§S-S-A-RS-MA]
// * Aggregates [§S-S-A-RS-A]
// * Valid Attributes [§S-S-A-RS-VAT]
// * Opaque Attributes [§S-S-A-RS-OAT]
// * Head Attributes [§S-S-A-RS-HAT]
// * Has_Data Attributes [§S-S-A-RS-HDAT]
// * Selected Expressions [§S-S-A-RS-S]
// * List Comprehensions [§S-S-A-RS-LC]
// * Bindings [§S-S-A-RS-B]
// * Quantified Expressions [§S-S-A-RS-Q]
// * Calls [§S-S-A-RS-CL]
// * Conversions [§S-S-A-RS-CV]

*Dynamic Semantics*

The existing state of a message or sequence is removed (and the corresponding buffer is cleared).

*Example*

[source,ada,rflx,attribute_statement]
----
Message'Reset
----

===== Read Attribute Statements

// Read Attribute Statements [§S-S-A-RD]

The read attribute statement is used to retrieve a message from a channel.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-read]]read ::= channel_xref:syntax-name[name]*'Read (* xref:syntax-expression[expression] *)*
----

// *Static Semantics*
//
// Expressions:
//
// * Mathematical Expressions [§S-S-A-RD-ME]
// * Boolean Expressions [§S-S-A-RD-BE]
// * Literals [§S-S-A-RD-L]
// * Variables [§S-S-A-RD-V]
// * Message Aggregates [§S-S-A-RD-MA]
// * Aggregates [§S-S-A-RD-A]
// * Valid Attributes [§S-S-A-RD-VAT]
// * Opaque Attributes [§S-S-A-RD-OAT]
// * Head Attributes [§S-S-A-RD-HAT]
// * Has_Data Attributes [§S-S-A-RD-HDAT]
// * Selected Expressions [§S-S-A-RD-S]
// * List Comprehensions [§S-S-A-RD-LC]
// * Bindings [§S-S-A-RD-B]
// * Quantified Expressions [§S-S-A-RD-Q]
// * Calls [§S-S-A-RD-CL]
// * Conversions [§S-S-A-RD-CV]

*Example*

[source,ada,rflx,attribute_statement]
----
Data_Channel'Read (Message)
----

===== Write Attribute Statements

// Write Attribute Statements [§S-S-A-WR]

A message can be sent through a channel using a write attribute statement.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-write]]write ::= channel_xref:syntax-name[name]*'Write (* xref:syntax-expression[expression] *)*
----

// *Static Semantics*
//
// Expressions:
//
// * Mathematical Expressions [§S-S-A-WR-ME]
// * Boolean Expressions [§S-S-A-WR-BE]
// * Literals [§S-S-A-WR-L]
// * Variables [§S-S-A-WR-V]
// * Message Aggregates [§S-S-A-WR-MA]
// * Aggregates [§S-S-A-WR-A]
// * Valid Attributes [§S-S-A-WR-VAT]
// * Opaque Attributes [§S-S-A-WR-OAT]
// * Head Attributes [§S-S-A-WR-HAT]
// * Has_Data Attributes [§S-S-A-WR-HDAT]
// * Selected Expressions [§S-S-A-WR-S]
// * List Comprehensions [§S-S-A-WR-LC]
// * Bindings [§S-S-A-WR-B]
// * Quantified Expressions [§S-S-A-WR-Q]
// * Calls [§S-S-A-WR-CL]
// * Conversions [§S-S-A-WR-CV]

*Dynamic Semantics*

Writing an invalid message leads to an exception transition. This behavior will change in the future (cf. https://github.com/Componolit/RecordFlux/issues/569[#569]).

*Example*

[source,ada,rflx,attribute_statement]
----
Data_Channel'Write (Message)
----

=== Expressions

// Expressions [§S-E]

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-expression]]expression ::= xref:syntax-literal[literal] | xref:syntax-variable[variable] | xref:syntax-mathematical_expression[mathematical_expression] | xref:syntax-boolean_expression[boolean_expression] | xref:syntax-message_aggregate[message_aggregate] | xref:syntax-aggregate[aggregate] | xref:syntax-attribute_reference[attribute_reference] | xref:syntax-selected[selected] | xref:syntax-comprehension[comprehension] | xref:syntax-binding[binding] | xref:syntax-quantified_expression[quantified_expression] | xref:syntax-call[call] | xref:syntax-conversion[conversion]
----

==== Literals

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-literal]]literal ::= xref:syntax-name[name] | xref:syntax-number[number]
----

==== Variables

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-variable]]variable ::= xref:syntax-name[name]
----

==== Message Aggregates

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-message_aggregate]]message_aggregate ::= message_xref:syntax-type_name[type_name]*'(* xref:syntax-field_values[field_values] *)*

[[syntax-field_values]]field_values ::= xref:syntax-field_value[field_value] { *,* xref:syntax-field_value[field_value] } | *null message*

[[syntax-field_value]]field_value ::= field_xref:syntax-name[name] *=>* xref:syntax-expression[expression]
----

*Dynamic Semantics*

An invalid condition during message creation leads to an exception transition. This behavior will change in the future (cf. https://github.com/Componolit/RecordFlux/issues/569[#569]).

Insufficient memory during the message creation leads to an exception transition.

*Example*

[source,ada,rflx,extended_primary]
----
TLS_Record::TLS_Record'(Tag => TLS_Record::Alert, Legacy_Record_Version => TLS_Record::TLS_1_2, Length => Alert_Message'Size / 8, Fragment => Alert_Message'Opaque)
----
[source,ada,rflx,extended_primary]
----
Null_Message'(null message)
----

==== Aggregates

// Aggregates [§S-E-A]

An aggregate is a collection of elements.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-aggregate]]aggregate ::= *[* xref:syntax-number[number] { *,* xref:syntax-number[number] } *]*
----

// *Static Semantics*
//
// Types [§S-E-A-T]:
//
// * Scalar [§S-E-A-T-SC]
// * Message [§S-E-A-T-M]
//
// Expressions [§S-E-A-E]:
//
// * Mathematical Expressions [§S-E-A-E-ME]
// * Boolean Expressions [§S-E-A-E-BE]
// * Literals [§S-E-A-E-L]
// * Variables [§S-E-A-E-V]
// * Message Aggregates [§S-E-A-E-MA]
// * Aggregates [§S-E-A-E-A]
// * Valid Attributes [§S-E-A-E-VAT]
// * Opaque Attributes [§S-E-A-E-OAT]
// * Head Attributes [§S-E-A-E-HAT]
// * Has_Data Attributes [§S-E-A-E-HDAT]
// * Selected Expressions [§S-E-A-E-S]
// * List Comprehensions [§S-E-A-E-LC]
// * Bindings [§S-E-A-E-B]
// * Quantified Expressions [§S-E-A-E-Q]
// * Calls [§S-E-A-E-CL]
// * Conversions [§S-E-A-E-CV]

*Example*

[source,ada,rflx,extended_primary]
----
[0, 1, 2]
----
[source,ada,rflx,extended_primary]
----
[]
----

==== Attribute Expressions

// Attribute Expressions [§S-E-AT]

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-attribute_reference]]attribute_reference ::= xref:syntax-expression[expression]*'*xref:syntax-attribute_designator[attribute_designator]

[[syntax-attribute_designator]]attribute_designator ::= *Valid* | *Opaque* | *Head* | *Has_Data*
----

*Static Semantics*

// Valid attribute [§S-E-AT-V]

The Valid attribute allows to determine the validity of a message or sequence.

// Expressions:
//
// * Mathematical Expressions [§S-E-AT-V-ME]
// * Boolean Expressions [§S-E-AT-V-BE]
// * Literals [§S-E-AT-V-L]
// * Variables [§S-E-AT-V-V]
// * Message Aggregates [§S-E-AT-V-MA]
// * Aggregates [§S-E-AT-V-A]
// * Valid Attributes [§S-E-AT-V-VAT]
// * Opaque Attributes [§S-E-AT-V-OAT]
// * Head Attributes [§S-E-AT-V-HAT]
// * Has_Data Attributes [§S-E-AT-V-HDAT]
// * Selected Expressions [§S-E-AT-V-S]
// * List Comprehensions [§S-E-AT-V-LC]
// * Bindings [§S-E-AT-V-B]
// * Quantified Expressions [§S-E-AT-V-Q]
// * Calls [§S-E-AT-V-CL]
// * Conversions [§S-E-AT-V-CV]

// Opaque attribute [§S-E-AT-O]

The byte representation of a message can be retrieved using the Opaque attribute.

// Expressions:
//
// * Mathematical Expressions [§S-E-AT-O-ME]
// * Boolean Expressions [§S-E-AT-O-BE]
// * Literals [§S-E-AT-O-L]
// * Variables [§S-E-AT-O-V]
// * Message Aggregates [§S-E-AT-O-MA]
// * Aggregates [§S-E-AT-O-A]
// * Valid Attributes [§S-E-AT-O-VAT]
// * Opaque Attributes [§S-E-AT-O-OAT]
// * Head Attributes [§S-E-AT-O-HAT]
// * Has_Data Attributes [§S-E-AT-O-HDAT]
// * Selected Expressions [§S-E-AT-O-S]
// * List Comprehensions [§S-E-AT-O-LC]
// * Bindings [§S-E-AT-O-B]
// * Quantified Expressions [§S-E-AT-O-Q]
// * Calls [§S-E-AT-O-CL]
// * Conversions [§S-E-AT-O-CV]

// Heat attribute [§S-E-AT-H]

The Head attribute allows to get the first element of a sequence.

// Prefix types:
//
// * Scalar Sequence [§S-E-AT-H-SS]
// * Message Sequence [§S-E-AT-H-MS]
//
// Expressions:
//
// * Mathematical Expressions [§S-E-AT-H-ME]
// * Boolean Expressions [§S-E-AT-H-BE]
// * Literals [§S-E-AT-H-L]
// * Variables [§S-E-AT-H-V]
// * Message Aggregates [§S-E-AT-H-MA]
// * Aggregates [§S-E-AT-H-A]
// * Valid Attributes [§S-E-AT-H-VAT]
// * Opaque Attributes [§S-E-AT-H-OAT]
// * Head Attributes [§S-E-AT-H-HAT]
// * Has_Data Attributes [§S-E-AT-H-HDAT]
// * Selected Expressions [§S-E-AT-H-S]
// * List Comprehensions [§S-E-AT-H-LC]
// * Bindings [§S-E-AT-H-B]
// * Quantified Expressions [§S-E-AT-H-Q]
// * Calls [§S-E-AT-H-CL]
// * Conversions [§S-E-AT-H-CV]

// Has_Data attribute [§S-E-AT-HD]

Whether a channel contains data can be checked with the Has_Data attribute.

// Expressions:
//
// * Mathematical Expressions [§S-E-AT-HD-ME]
// * Boolean Expressions [§S-E-AT-HD-BE]
// * Literals [§S-E-AT-HD-L]
// * Variables [§S-E-AT-HD-V]
// * Message Aggregates [§S-E-AT-HD-MA]
// * Aggregates [§S-E-AT-HD-A]
// * Valid Attributes [§S-E-AT-HD-VAT]
// * Opaque Attributes [§S-E-AT-HD-OAT]
// * Head Attributes [§S-E-AT-HD-HAT]
// * Has_Data Attributes [§S-E-AT-HD-HDAT]
// * Selected Expressions [§S-E-AT-HD-S]
// * List Comprehensions [§S-E-AT-HD-LC]
// * Bindings [§S-E-AT-HD-B]
// * Quantified Expressions [§S-E-AT-HD-Q]
// * Calls [§S-E-AT-HD-CL]
// * Conversions [§S-E-AT-HD-CV]

*Dynamic Semantics*

The use of the Opaque attribute on an invalid message or the use of the Head attribute on an empty sequence leads to an exception transition. This behavior will change in the future (cf. https://github.com/Componolit/RecordFlux/issues/569[#569]).

*Example*

[source,ada,rflx,extended_suffix]
----
Message'Valid
----

==== Selected Expressions

// Selected Expressions [§S-E-S]

The Selected expression is used to get a value of a message field.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-selected]]selected ::= message_xref:syntax-expression[expression] *.* field_xref:syntax-name[name]
----

// *Static Semantics*
//
// Expressions:
//
// * Mathematical Expressions [§S-E-S-ME]
// * Boolean Expressions [§S-E-S-BE]
// * Literals [§S-E-S-L]
// * Variables [§S-E-S-V]
// * Message Aggregates [§S-E-S-MA]
// * Aggregates [§S-E-S-A]
// * Valid Attributes [§S-E-S-VAT]
// * Opaque Attributes [§S-E-S-OAT]
// * Head Attributes [§S-E-S-HAT]
// * Has_Data Attributes [§S-E-S-HDAT]
// * Selected Expressions [§S-E-S-S]
// * List Comprehensions [§S-E-S-LC]
// * Bindings [§S-E-S-B]
// * Quantified Expressions [§S-E-S-Q]
// * Calls [§S-E-S-CL]
// * Conversions [§S-E-S-CV]

*Dynamic Semantics*

Accesses to message fields that were detected as invalid during parsing lead to an exception transition. This behavior will change in the future (cf. https://github.com/Componolit/RecordFlux/issues/569[#569]).

*Example*

[source,ada,rflx,extended_suffix]
----
Ethernet_Frame.Payload
----

==== List Comprehensions

// List Comprehensions [§S-E-LC]

A list comprehension provides a way to create a new sequence based on an exisiting sequence.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-comprehension]]comprehension ::= *[* *for* xref:syntax-name[name] *in* iterable_xref:syntax-expression[expression] *=>* selector_xref:syntax-expression[expression] *when* condition_xref:syntax-expression[expression] *]*
----

// *Static Semantics*
//
// * Source: Scalar sequence [§S-E-LC-SSS]
// * Source: Message sequence [§S-E-LC-SMS]
// * Source: Variable [§S-E-LC-V]
// * Source: Selected [§S-E-LC-S]
// * Target: Scalar sequence [§S-E-LC-TSS]
// * Target: Message sequence [§S-E-LC-TMS]
// * Condition: Selected [§S-E-LC-CS]
// * Source sequence as target [§S-E-LC-SAT]
// * Global declarations [§S-E-LC-GD]
// * Local declarations [§S-E-LC-LD]
// * State transitions [§S-E-LC-T]
// * Assignment statements [§S-E-LC-A]

*Dynamic Semantics*

An access to an invalid element in iterable_xref:syntax-expression[expression] leads to an exception transition. This behavior will change in the future (cf. https://github.com/Componolit/RecordFlux/issues/569[#569]).

*Example*

[source,ada,rflx,extended_primary]
----
[for O in Offer.Options if O.Code = DHCP::DHCP_Message_Type_Option => O.DHCP_Message_Type]
----

==== Bindings

// Bindings [§S-E-B]

A binding can be used to name a subexpression and enables the use of a subexpression multiple times without the need for duplicating the expression or declaring a separate variable.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-binding]]binding ::=
   xref:syntax-expression[expression]
      *where*
         xref:syntax-name[name] *=* sub_xref:syntax-expression[expression] { *,*
         xref:syntax-name[name] *=* sub_xref:syntax-expression[expression] }
----

// *Static Semantics*
//
// Expressions:
//
// * Mathematical Expressions [§S-E-B-ME]
// * Boolean Expressions [§S-E-B-BE]
// * Literals [§S-E-B-L]
// * Variables [§S-E-B-V]
// * Message Aggregates [§S-E-B-MA]
// * Aggregates [§S-E-B-A]
// * Valid Attributes [§S-E-B-VAT]
// * Opaque Attributes [§S-E-B-OAT]
// * Head Attributes [§S-E-B-HAT]
// * Has_Data Attributes [§S-E-B-HDAT]
// * Selected Expressions [§S-E-B-S]
// * List Comprehensions [§S-E-B-LC]
// * Bindings [§S-E-B-B]
// * Quantified Expressions [§S-E-B-Q]
// * Calls [§S-E-B-CL]
// * Conversions [§S-E-B-CV]
//
// The type of the subexpression is inferred by the subexpression type and the expected type for all references of the name.

*Example*

[source,ada,rflx,extended_suffix]
----
TLS_Alert::Alert'(Level => Level, Description => Description)
   where
      Level = TLS_Alert::Fatal,
      Description = GreenTLS_Alert_Message.Description
----

==== Quantified Expressions

// Quantified Expressions [§S-E-Q]

Quantified expressions enable reasoning about properties of sequences.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-quantified_expression]]quantified_expression ::= *for* xref:syntax-quantifier[quantifier] *in* iterable_xref:syntax-expression[expression] *=>* predicate_xref:syntax-expression[expression]

[[syntax-quantifier]]quantifier ::= *all* | *some*
----

// *Static Semantics*
//
// Iterable expressions [§S-E-Q-I]:
//
// * Mathematical Expressions [§S-E-Q-I-ME]
// * Boolean Expressions [§S-E-Q-I-BE]
// * Literals [§S-E-Q-I-L]
// * Variables [§S-E-Q-I-V]
// * Message Aggregates [§S-E-Q-I-MA]
// * Aggregates [§S-E-Q-I-A]
// * Valid Attributes [§S-E-Q-I-VAT]
// * Opaque Attributes [§S-E-Q-I-OAT]
// * Head Attributes [§S-E-Q-I-HAT]
// * Has_Data Attributes [§S-E-Q-I-HDAT]
// * Selected Expressions [§S-E-Q-I-S]
// * List Comprehensions [§S-E-Q-I-LC]
// * Bindings [§S-E-Q-I-B]
// * Quantified Expressions [§S-E-Q-I-Q]
// * Calls [§S-E-Q-I-CL]
// * Conversions [§S-E-Q-I-CV]
//
// Predicate expressions [§S-E-Q-P]:
//
// * Mathematical Expressions [§S-E-Q-P-ME]
// * Boolean Expressions [§S-E-Q-P-BE]
// * Literals [§S-E-Q-P-L]
// * Variables [§S-E-Q-P-V]
// * Message Aggregates [§S-E-Q-P-MA]
// * Aggregates [§S-E-Q-P-A]
// * Valid Attributes [§S-E-Q-P-VAT]
// * Opaque Attributes [§S-E-Q-P-OAT]
// * Head Attributes [§S-E-Q-P-HAT]
// * Has_Data Attributes [§S-E-Q-P-HDAT]
// * Selected Expressions [§S-E-Q-P-S]
// * List Comprehensions [§S-E-Q-P-LC]
// * Bindings [§S-E-Q-P-B]
// * Quantified Expressions [§S-E-Q-P-Q]
// * Calls [§S-E-Q-P-CL]
// * Conversions [§S-E-Q-P-CV]

*Example*

[source,ada,rflx,extended_primary]
----
for all E in Server_Hello_Message.Extensions => E.Tag /= TLS_Handshake::ET_Supported_Versions
----

==== Calls

// Calls [§S-E-CL]

All functions which are declared in the session parameters can be called.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-call]]call ::= xref:syntax-name[name] [ *(* argument_xref:syntax-expression[expression] { *,* argument_xref:syntax-expression[expression] } *)* ]
----

// *Static Semantics*
//
// Argument expressions:
//
// * No argument [§S-E-CL-N]
// * Mathematical Expressions [§S-E-CL-ME]
// * Boolean Expressions [§S-E-CL-BE]
// * Literals [§S-E-CL-L]
// * Variables [§S-E-CL-V]
// * Message Aggregates [§S-E-CL-MA]
// * Aggregates [§S-E-CL-A]
// * Valid Attributes [§S-E-CL-VAT]
// * Opaque Attributes [§S-E-CL-OAT]
// * Head Attributes [§S-E-CL-HAT]
// * Has_Data Attributes [§S-E-CL-HDAT]
// * Selected Expressions [§S-E-CL-S]
// * List Comprehensions [§S-E-CL-LC]
// * Bindings [§S-E-CL-B]
// * Quantified Expressions [§S-E-CL-Q]
// * Calls [§S-E-CL-CL]
// * Conversions [§S-E-CL-CV]

*Example*

[source,ada,rflx,extended_primary]
----
Decrypt (Key_Update_Message, Sequence_Number, TLS_Record_Message.Encrypted_Record)
----

==== Conversions

// Conversions [§S-E-CV]

An opaque field of a message can be converted to a message.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-conversion]]conversion ::= message_xref:syntax-type_name[type_name] *(* message_xref:syntax-expression[expression] *.* field_xref:syntax-name[name] *)*
----

*Static Semantics*

A conversion is only allowed if a refinement for the message field and the intended target type exists.

// Expressions:
//
// * Mathematical Expressions [§S-E-CV-ME]
// * Boolean Expressions [§S-E-CV-BE]
// * Literals [§S-E-CV-L]
// * Variables [§S-E-CV-V]
// * Message Aggregates [§S-E-CV-MA]
// * Aggregates [§S-E-CV-A]
// * Valid Attributes [§S-E-CV-VAT]
// * Opaque Attributes [§S-E-CV-OAT]
// * Head Attributes [§S-E-CV-HAT]
// * Has_Data Attributes [§S-E-CV-HDAT]
// * Selected Expressions [§S-E-CV-S]
// * List Comprehensions [§S-E-CV-LC]
// * Bindings [§S-E-CV-B]
// * Quantified Expressions [§S-E-CV-Q]
// * Calls [§S-E-CV-CL]
// * Conversions [§S-E-CV-CV]

*Dynamic Semantics*

An invalid condition of a refinement leads to an exception transition. This behavior will change in the future (cf. https://github.com/Componolit/RecordFlux/issues/569[#569]).

*Example*

[source,ada,rflx,extended_primary]
----
Key_Update_Message (Handshake_Control_Message.Data)
----

== Packages

A package is used to structure a specification.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-package]]package ::=
   *package* xref:syntax-name[name] *is*
      { xref:syntax-basic_declaration[basic_declaration] }
   *end* xref:syntax-name[name] *;*

[[syntax-basic_declaration]]basic_declaration := ( xref:syntax-modular_type[modular_type] | xref:syntax-range_type[range_type] | xref:syntax-enumeration_type[enumeration_type] | xref:syntax-message_type[message_type] | xref:syntax-type_refinement[type_refinement] | xref:syntax-session[session] ) *;*
----

*Static Semantics*

A package is a collection of types and sessions. By convention one protocol is specified in one package.

*Example*

[source,ada,rflx]
----
package Ethernet is

   type Address is mod 2**48;
   type Type_Length is range 46 .. 2**16 - 1 with Size => 16;
   type TPID is range 16#8100# .. 16#8100# with Size => 16;
   type TCI is mod 2**16;
   type Ether_Type is
      (ET_IPv4            => 16#0800#,
       ET_ARP             => 16#0806#,
       ET_VLAN_Tag        => 16#8100#,
       ET_IPv6            => 16#86DD#,
       ET_VLAN_Tag_Double => 16#9100#)
   with Size => 16, Always_Valid;

   type Frame is
      message
         Destination : Address;
         Source : Address;
         Type_Length_TPID : Type_Length
            then TPID
               with First => Type_Length_TPID'First
               if Type_Length_TPID = 16#8100#
            then Payload
               with Size => Type_Length_TPID * 8
               if Type_Length_TPID <= 1500
            then Ether_Type
               with First => Type_Length_TPID'First
               if Type_Length_TPID >= 1536 and Type_Length_TPID /= 16#8100#;
         TPID : TPID;
         TCI : TCI;
         Ether_Type : Ether_Type
            then Payload
               with Size => Message'Last - Ether_Type'Last;
         Payload : Opaque
            then null
               if Payload'Size / 8 >= 46 and Payload'Size / 8 <= 1500;
      end message;

   generic
      Input : Channel with Readable;
      Output : Channel with Writable;
   session Validator with
      Initial => Validate,
      Final => Error
   is
      Frame : Ethernet::Frame;
   begin
      state Validate
      is
      begin
         Input'Read (Frame);
      transition
         then Forward
            if Frame'Valid
         then Validate
      end Validate;

      state Forward
      is
      begin
         Output'Write (Frame);
      transition
         then Validate
      exception
         then Error
      end Forward;

      state Error is null state;
   end Validator;

end Ethernet;
----

== Context Clauses

The context clause is used to specify the relation to other packages and consists of a list of with clauses.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-context]]context ::= { *with* package_xref:syntax-name[name] *;* }
----

*Static Semantics*

For each package referenced in a file, a corresponding with clause has to be added to the beginning of the file.

*Example*

[source,ada,rflx,context_clause]
----
with Ethernet;
with IPv4;
----

== Files

A RecordFlux specification file is recognized by the file extension `.rflx`. Each specification file contains exactly one package. The file name must match the package name in lower case characters.

*Syntax*

[subs="+macros,quotes"]
----
[[syntax-file]]file ::=
   xref:syntax-context[context]
   xref:syntax-package[package]
----

*Example*

File: `in_ethernet.rflx`

[source,ada,rflx,specification]
----
with Ethernet;
with IPv4;

package In_Ethernet is

   for Ethernet::Frame use (Payload => IPv4::Packet)
      if Ether_Type = Ethernet::ET_IPv4;

end In_Ethernet;
----
