Skip to content

Commit

Permalink
[#486] Update langauge guide and schema evolution guide
Browse files Browse the repository at this point in the history
  • Loading branch information
Mi-La committed Oct 4, 2023
1 parent 717431a commit f98c914
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 19 deletions.
75 changes: 61 additions & 14 deletions doc/ZserioLanguageOverview.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ described in zserio, giving the developer overall control of the data schema use

[SQLite Extension](#sqlite-extension)

[Annotations](#annotations)

[Compiler Directives](#compiler-directives)

[Background & History](#background--history)
Expand Down Expand Up @@ -153,7 +155,7 @@ signed values. This is a special type of integer that uses only the bytes needed
The value ranges of the variable integer types are:

Data Type | Value Range | Max Value | Max Bytes
------------ | -------------------------------------------------- | --------- |----------
------------ | -------------------------------------------------- | --------- |----------
varint16 | `-16383 to 16383` | `2^14-1` | `2`
varint32 | `-268435455 to 268435455` | `2^28-1` | `4`
varint64 | `-72057594037927935 to 72057594037927935` | `2^56-1` | `8`
Expand Down Expand Up @@ -256,10 +258,10 @@ const int32 j = -5678;

## Enumeration Types

An enumeration type has a base type which is an integer type or a bit field type. The members of an enumeration
have a name and a value which may be assigned explicitly or implicitly. A member that does not have
An enumeration type has a base type which is an integer type or a bit field type. The items of an enumeration
have a name and a value which may be assigned explicitly or implicitly. An item that does not have
an initializer gets assigned the value of its predecessor incremented by 1, or the value 0 if it is the first
member.
item.

**Example**

Expand All @@ -273,27 +275,29 @@ enum bit:3 Color
};
```

In the example above, `BLUE` has the value 3. When decoding a member of type `Color`, the decoder will read
In the example above, `BLUE` has the value 3. When decoding an item of type `Color`, the decoder will read
3 bits from the stream and report an error when the integer value of these 3 bits is not one of 0, 2, 3 or 7.

An enumeration type provides its own lexical scope, similar to Java and dissimilar to C++. The member names
An enumeration type provides its own lexical scope, similar to Java and dissimilar to C++. The item names
must be unique within each enumeration type, but may be reused in other contexts with different meanings.
Referring to the example, any other enumeration type `Foo` may also contain a member named `NONE`.
Referring to the example, any other enumeration type `Foo` may also contain an item named `NONE`.

In expressions outside of the defining type, enumeration members must always be prefixed by the type name
In expressions outside of the defining type, enumeration items must always be prefixed by the type name
and a dot, e.g. `Color.NONE`.

The enumeration value represented by integer type can be referenced as `valueof(enumeration)`,
see [valueof Operator](#valueof-operator).

Enumeration items can be [`@deprecated`](#deprecated-annotation) or [`@removed`](#removed-annotation).

[top](#language-guide)

## Bitmask Types

A bitmask type has a base type which is an unsigned integer or unsigned bit field type. The members of a bitmask
have a name and a value which may be assigned explicitly or implicitly. A member that does not have
A bitmask type has a base type which is an unsigned integer or unsigned bit field type. The values of a bitmask
have a name and a value which may be assigned explicitly or implicitly. A value that does not have
an initializer gets assigned the value calculated from its predecessor by finding the first unused bit.
If the unspecified member is the first one, it will be assigned to 1.
If the unspecified value is the first one, it will be assigned to 1.

**Example**

Expand All @@ -309,8 +313,8 @@ bitmask uint8 Permission
In the example above, `EXECUTABLE` is auto-assigned to 1, `READABLE` is manually assigned to 2 and the
`WRITABLE` is assigned by finding the first unused bit to value 4.

A bitmask type provides its own lexical scope. The member names must be unique within each bitmask type.
In expressions outside of the defining type, bitmask members must always be prefixed by the type name and a dot,
A bitmask type provides its own lexical scope. The value names must be unique within each bitmask type.
In expressions outside of the defining type, bitmask values must always be prefixed by the type name and a dot,
e.g. `Permission.WRITABLE`.

Bitmasks support all basic bit operations:
Expand Down Expand Up @@ -339,7 +343,7 @@ In the example above, the `availability` parameter defines available version for
`versionString` are present only if the `availability` contains the `VERSION_NUMBER` and `VERSION_STRING` masks
respectively.

>Note that the bitmask can contain a member which is manually assigned to 0 and which represents an empty
>Note that the bitmask can contain a value which is manually assigned to 0 and which represents an empty
bitmask (e.g. `NONE = 0`). Such `NONE` mask can be useful in expressions.

The bitmask value represented by integer type can be referenced as `valueof(Permission.EXECUTABLE)`,
Expand Down Expand Up @@ -2018,6 +2022,49 @@ union | `BLOB`

[top](#language-guide)

## Annotations

Zserio annotations are syntactic metadata that can be added to Zserio sources. Annotations usually have no
direct effect but can be used by generators to modify generated code appropriately. Annotations starts with `@`
and are placed before a language element.

### Deprecated Annotation

Annotation `@deprecated` denotes that the language element is being deprecated and should not be used anymore.
Generators are allowed to generate a code which will fire a warning when an appropriate generated element is
used by an application.

```
enum uint8 Traffic
{
NONE = 0,
@deprecated HEAVY,
LIGHT
MID
};
```

> Since `2.12.0` (supported only by enumeration items).
### Removed Annotation

Annotation `@removed` denotes that the language element was removed from the schema and is left there only for
the sake of backward compatibility. Generators are allowed to omit (or hide) an appropriate generated element
in a way that it will be still possible to read old BLOBS, while it should be forbidden to use such elements
during serialization.

```
enum uint8 Traffic
{
NONE = 0,
@removed HEAVY,
LIGHT
MID
};
```

> Since `2.12.0` (supported only by enumeration items).
## Compiler Directives

### Compatibility Check
Expand Down
46 changes: 41 additions & 5 deletions doc/ZserioSchemaEvolutionGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,31 @@ left in the bit stream.
struct TopLevelStructure
{
uint32 fieldInVersion1;
varuint newFieldInVersion2; // old appl will stop parsing here
varuint newFieldInVersion2; // old application will stop parsing here
};
```

Old applications will parse successfully new `TopLevelStructure` by reading only the first field
`fieldInVersion1` leaving field `newFieldInVersion2` unread in the bit stream.

### Enumeration Item Removal

The forward compatible enumeration item removal is possible by annotation
[`@removed`](ZserioLanguageOverview.md#removed-annotation). This annotation ensures that enumeration item values
do not change and will be compatible for old applications.

**Example**

```
enum bit:8 DarkColor
{
NONE,
DARK_RED,
@removed DARK_BLUE, // old application will never parse this enumeration item
DARK_GREEN
};
```

## Backward Compatible Changes

### Top Level Structure Extension
Expand All @@ -53,7 +71,7 @@ This keyword will indicate an optional extension which does not have to be encod
struct TopLevelStructure
{
uint32 fieldInVersion1;
extend varuint newFieldInVersion2; // new appl will check end of stream here
extend varuint newFieldInVersion2; // new application will check end of stream here
};
```

Expand All @@ -79,13 +97,13 @@ choice UInt16Choice(uint16 selector) on selector
VariantB b;
case 3:
VariantC newInVersion2; // new appl will never parse this case
VariantC newInVersion2; // new application will never parse this case
// default case must be either omitted or must be empty!
};
```

### Enumeration Extension
### Enumeration Item Addition

The backward compatibility of adding a new enumeration item without change of existed enumeration items works
automatically. This is because all old enumeration items are known for a new application.
Expand All @@ -98,8 +116,26 @@ enum bit:8 DarkColor
NONE,
DARK_RED,
DARK_BLUE,
DARK_GREEN,
DARK_NEW_IN_VERSION2 // new application will never parse this item
};
```

### Enumeration Item Removal

The backward compatible enumeration item removal is possible by annotation
[`@removed`](ZserioLanguageOverview.md#removed-annotation). This annotation ensures that enumeration item values
do not change and that new applications will still parse removed enumeration items.

**Example**

```
enum bit:8 DarkColor
{
NONE,
DARK_RED,
@removed DARK_BLUE, // new application will parse this item (but should fire an error during serialization)
DARK_GREEN
DARK_NEW_IN_VERSION2; // new appl will never parse this item
};
```

Expand Down

0 comments on commit f98c914

Please sign in to comment.