Init Commit: Moved bproto to seperate repo
This commit is contained in:
221
docs/syntax.md
Normal file
221
docs/syntax.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# Syntax Documentation
|
||||
|
||||
bproto uses a custom syntax `bproto` (file extension `.bproto`).
|
||||
Each protocol is described in a single bproto file.
|
||||
|
||||
For Beginners, a simple example of a protocol definition and usage can be found [here](/docs/quickstart.md).
|
||||
|
||||
The protocol definitions consist of the following basic components: **messages**, **enums**, **bitfields**, and the **protocol tag line**.
|
||||
|
||||
## Table of Contents
|
||||
- [Syntax Documentation](#syntax-documentation)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Names and IDs](#names-and-ids)
|
||||
- [Protocol Tag Line](#protocol-tag-line)
|
||||
- [Message](#message)
|
||||
- [Fields](#fields)
|
||||
- [Datatypes](#datatypes)
|
||||
- [Bitfields](#bitfields)
|
||||
- [Enumerations](#enumerations)
|
||||
- [Comments](#comments)
|
||||
|
||||
## Names and IDs
|
||||
Names of enums, bitfields, messages, and fields support any letter (lower and uppercase), numbers, and underscores.
|
||||
|
||||
Regular expression: `[a-zA-Z0-9_]+`
|
||||
|
||||
Numbers/IDs are decimal encoded numbers. Trailing zeros are ignored.
|
||||
|
||||
Regular expression: `[0-9]+`
|
||||
|
||||
## Protocol Tag Line
|
||||
This is a short description of the protocol consisting of a name and a version number.
|
||||
This must be the first line of any bproto definition file.
|
||||
|
||||
**Syntax:**
|
||||
```bproto
|
||||
protocol <name> version <version>
|
||||
```
|
||||
**Example:**
|
||||
```bproto
|
||||
protocol myCustomAirplaneProtocol version 2
|
||||
```
|
||||
|
||||
The name should identify the protocol in the implementation context (like `robotControlProtocol` or `weatherStationTelemetryDataStream`).
|
||||
The version number is used to differentiate between different iterations of the protocol. Different versions of the same protocol are incompatible.
|
||||
|
||||
For detailed information on naming conventions and versioning strategies, please refer to the [compatibility documentation](/docs/compatibility.md#naming-conventions).
|
||||
|
||||
## Message
|
||||
|
||||
A message is a collection of fields that can be serialized and deserialized to be sent over the wire or channel.
|
||||
A message should only be a transport container and should not, if possible, be stored permanently.
|
||||
|
||||
**Syntax:**
|
||||
```bproto
|
||||
message [<Message ID>] <Message Name> {
|
||||
// List of fields
|
||||
[<field ID #0>] <field name #0> : <field type #0>,
|
||||
[<field ID #1>] <field name #1> : <field type #1>,
|
||||
....
|
||||
[<field ID #N>] <field name #N> : <field type #N>,
|
||||
}
|
||||
```
|
||||
**Example:**
|
||||
```bproto
|
||||
message [1] EngineSensorData {
|
||||
[0] engine_thrust_left : float32,
|
||||
[1] engine_thrust_right : float32,
|
||||
[2] fuel_tanks_fill : uint32[8], // Fill levels of 8 fuel tanks
|
||||
[3] engine_fault_left : bool,
|
||||
[4] engine_fault_right : bool
|
||||
}
|
||||
```
|
||||
|
||||
- **Message ID:** Unique identifier within a protocol definition used to differentiate different messages from each other. The Message ID should be between 0 and 255.
|
||||
- **Message Name:** Unique name given to this message. This will be used to identify a field in the protocol implementation.
|
||||
|
||||
### Fields
|
||||
A message can have as many fields as necessary. These are comparable to members in a class or fields in a C-struct.
|
||||
A field has an `ID`, `Name`, and a `datatype`.
|
||||
|
||||
**Syntax:**
|
||||
`[<ID>] <Name> : <datatype>`
|
||||
**Example:**
|
||||
``[2] fanSpeed : float32``
|
||||
|
||||
- **Name:** This is a unique name given to the field. This will be used to identify a field in the protocol implementation.
|
||||
- **ID:** A unique identifier used to order the fields in the encoding/decoding. More about serialization can be found [here](/docs/serialization.md#message-field-data-encoding).
|
||||
- **datatype:** What type of data to store in this field.
|
||||
|
||||
### Datatypes
|
||||
Datatypes in bproto are independent of language and are translated into the target language-specific type.
|
||||
Every Field in a message must have a datatype.
|
||||
|
||||
Here is a list of datatypes available:
|
||||
|
||||
| bproto Datatype | Encode Size (bytes) | Python | C | Value Range | Description |
|
||||
| --------------- | ------------------- | ------- | ---------- | ------------------------------------------------------- | ---------------------------- |
|
||||
| `uint8` | 1 | `int` | `uint8_t` | 0 to 255 | Unsigned 8-bit integer |
|
||||
| `uint16` | 2 | `int` | `uint16_t` | 0 to 65,535 | Unsigned 16-bit integer |
|
||||
| `uint32` | 4 | `int` | `uint32_t` | 0 to 4,294,967,295 | Unsigned 32-bit integer |
|
||||
| `int64` | 8 | `int` | `uint64_t` | 0 to 18,446,744,073,709,551,615 | Unsigned 64-bit integer |
|
||||
| `int8` | 1 | `int` | `int8_t` | -128 to 127 | Signed 8-bit integer |
|
||||
| `int16` | 2 | `int` | `int16_t` | -32,768 to 32,767 | Signed 16-bit integer |
|
||||
| `int32` | 4 | `int` | `int32_t` | -2,147,483,648 to 2,147,483,647 | Signed 32-bit integer |
|
||||
| `int64` | 8 | `int` | `int64_t` | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | Signed 64-bit integer |
|
||||
| `float32` | 4 | `float` | `float` | 1.2E-38 to 3.4E+38 | 32-bit floating point number |
|
||||
| `float64` | 8 | `float` | `double` | 2.3E-308 to 1.7E+308 | 64-bit floating point number |
|
||||
| `string[<N>]` | N | `str` | `char[]` | N/A | Fixed-size string |
|
||||
| `char` | 1 | `str` | `char` | Single character | Single character |
|
||||
| `bool` | 1 | `bool` | `bool` | true or false | Boolean value |
|
||||
|
||||
Every datatype in this list can be used in a fixed-size array by using this format:
|
||||
|
||||
**Syntax:**
|
||||
`<datatype>[<array_size>]`
|
||||
**Example:**
|
||||
`float[]`
|
||||
|
||||
A special case is `string`.
|
||||
Strings _must_ be declared as an array because their size must be known from the start.
|
||||
|
||||
There are also `bits` and `enum` corresponding to **bitfields** and **enums**.
|
||||
They are a bit special and are not able to be used as an array.
|
||||
Bitfields and enums can be declared inline.
|
||||
More details can be found in the sections about [enums](#enumerations) and [bitfields](#bitfields).
|
||||
|
||||
How different datatypes are encoded can be found [here](/docs/serialization.md#message-field-data-encoding).
|
||||
|
||||
## Bitfields
|
||||
A compact representation of multiple boolean flags within a single byte or group of bytes, optimizing space for binary communication.
|
||||
Bitfields are treated as datatypes.
|
||||
|
||||
**Syntax:**
|
||||
```bproto
|
||||
bits <bitfield name> {
|
||||
<1st bit>, <2nd bit>, ...
|
||||
}
|
||||
```
|
||||
**Example:**
|
||||
```bproto
|
||||
bits engine_enables {
|
||||
engine_left, engine_right
|
||||
}
|
||||
```
|
||||
|
||||
Each bit can be either 0 or 1 (true or false), represented as a bool in the target language.
|
||||
More details on how Bitfields are encoded in the corresponding language can be found [here](/docs/datatype_language_details.md#bitfields).
|
||||
|
||||
Bitfields, like Enumerations, can be declared inline in a [message](#message).
|
||||
|
||||
**Syntax:**
|
||||
```bproto
|
||||
[<Field ID>] <Field Name> : bits {
|
||||
<1st bit>, <2nd bit>, ...
|
||||
}
|
||||
```
|
||||
**Example:**
|
||||
```bproto
|
||||
[1] lightsEnable: bits {
|
||||
Front, Spot, Key, BackLight
|
||||
}
|
||||
```
|
||||
|
||||
Bitfield naming when using them inline is found [here](/docs/datatype_language_details.md#inline).
|
||||
|
||||
## Enumerations
|
||||
A set of named integer values that represent discrete states or options.
|
||||
Enums enhance code clarity by using descriptive names instead of raw numeric values.
|
||||
Enumerations or Enums in bproto are comparable to C or Python enums.
|
||||
More details on how Enums are encoded in the corresponding language can be found [here](/docs/datatype_language_details.md#enums).
|
||||
Enums are treated as datatypes in bproto.
|
||||
|
||||
Each Enum item represents a positive (or zero) numeric value.
|
||||
These can be implicitly generated by bproto, incrementing by 1.
|
||||
The value of the Enum value therefore depends on the declaration order.
|
||||
This may lead to bugs and issues when updating one client/receiver's protocol but not the counterparts.
|
||||
For more info about this problem, see [here](/docs/serialization.md#message-field-data-encoding).
|
||||
|
||||
Enum values can also be set explicitly, which eliminates this problem.
|
||||
|
||||
**Syntax:**
|
||||
```bproto
|
||||
enum <enum name> {
|
||||
<Name #0> (= <Value #0>),
|
||||
<Name #1> (= <Value #1>),
|
||||
...
|
||||
<Name #N> (= <Value #N>),
|
||||
}
|
||||
```
|
||||
**Example:**
|
||||
```bproto
|
||||
dangerLvl: enum {
|
||||
WARNING,
|
||||
MELTDOWN,
|
||||
ERROR = 10,
|
||||
}
|
||||
```
|
||||
|
||||
**Syntax:**
|
||||
```bproto
|
||||
[<Field ID>] <Field Name> : enum {
|
||||
<Name #0> (= <Value #0>),
|
||||
<Name #1> (= <Value #1>),
|
||||
...
|
||||
<Name #N> (= <Value #N>),
|
||||
}
|
||||
```
|
||||
**Example:**
|
||||
```bproto
|
||||
[6] dangerLvl: enum {
|
||||
WARNING,
|
||||
MELTDOWN = 5,
|
||||
ERROR,
|
||||
}
|
||||
```
|
||||
|
||||
Enumeration naming when using them inline is found [here](/docs/datatype_language_details.md#inline).
|
||||
|
||||
## Comments
|
||||
bproto supports C-style comments (with `// ...` and `/* ... */`).
|
||||
Reference in New Issue
Block a user