# Messages

Every message is defined using **\<message>** XML element.

## Message Name

Every message definition must specify its [name](names) using **name** [property](properties).

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" ...>
        ...
    </message>
</schema>
```

## Numeric ID

Every message definition must specify its [numeric](numeric) ID using **id** [property](properties).

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" id="0x1">
        ...
    </message>
</schema>
```

It is highly recommended to define "message ID" numeric values as external [\<enum>](fields/enum) field and reuse its values.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <enum name="MsgId" type="uint8" semanticType="messageId">
            <validValue name="Msg1" val=0x1" />
            <validValue name="Msg2" val=0x2" />
        </enum>
    </fields>

    <message name="Msg1" id="MsgId.Msg1">
        ...
    </message>

    <message name="Msg2" id="MsgId.Msg2">
        ...
    </message>
</schema>
```

## Description

It is possible to provide a description of the message about what it is and how it is expected to be used. This description is only for documentation purposes and may find it's way into the generated code as a comment for the generated class. The [property](properties) is **description**.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" id="1">
        <description>
            Some long
            multiline
            description
        </description>
        ...
    </message>
</schema>
```

## Display Name

When various analysis tools display message details, the preference is to display proper space separated name (which is defined using **displayName** [property](properties)) rather than using a [name](names).

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" id="1" displayName="Message 1">
        ...
    </message>
</schema>
```

In case **displayName** is empty, the analysis tools are expected to use value of **name** [property](properties) instead.

It is recommended to share the **displayName** with relevant **\<validValue>** of **\<enum>** that lists numeric IDs of the messages:

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <string name="Msg1Name" defaultValue="Message 1" />
        <string name="Msg2Name" defaultValue="Message 2" />

        <enum name="MsgId" type="uint8" semanticType="messageId">
            <validValue name="Msg1" val="1" displayName="^Msg1Name" />
            <validValue name="Msg2" val="2" displayName="^Msg2Name" />
        </enum>

        <message name="Msg1" id="MsgId.Msg1" displayName="^Msg1Name">
            ...
        </message>

        <message name="Msg2" id="MsgId.Msg2" displayName="^Msg2Name">
            ...
        </message>
    </fields>
</schema>
```

## Fields

Every **\<message>** has zero or more [fields](fields) that can be specified as child XML elements.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <int name="SomeCommonField" type="uint16" defaultValue="10" />
    </fields>

    <message name="Msg1" id="1">
        <int name="F1" type="uint8" />
        <enum name="F2" type="uint8">
            ...
        </enum>
        <ref field="SomeCommonField" name="F3" />
        <string name="F4" length="8" />
        ...
    </message>
</schema>
```

If there is any other [property](properties) defined as XML child of the **\<message>**, then all the fields must be wrapped in **\<fields>** XML element for separation.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <message name="Msg1" id="1">
        <displayName value="Message 1" />
        <fields>
            <int name="F1" type="uint8" />
        </fields>
    </message>
</schema>
```

Sometimes different messages have the same fields. In order to avoid duplication, use **copyFieldsFrom** property to specify original message.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" id="1">
        <int name="F1" type="uint32" />
    </message>

    <message name="Msg2" id="2" copyFieldsFrom="Msg1" />
</schema>
```

In the example above _Msg2_ will have the same fields as _Msg1_.

After copying fields from other message, all other defined fields will be appended to copied ones.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" id="1">
        <int name="F1" type="uint32" />
    </message>

    <message name="Msg2" id="2" copyFieldsFrom="Msg1">
        <float name="F2" type="float" />
    </message>
</schema>
```

In the example above _Msg2_ will have 2 fields: _F1_ and _F2_.

## Ordering

There are protocols that may define various forms of the same message, which share the same numeric ID, but are differentiated by a serialization length or value of some particular field inside the message. It can be convenient to define such variants as separate classes. In case there are multiple **\<message>**-es with the same [numeric ID](#numeric-id), it is required to specify order in which they are expected to be processed (read). The ordering is specified using **order** [property](properties) with unsigned [numeric](numeric) value. The message object with lower **order** value gets created and its _read_ operation attempted **before** message object with higher value.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" nonUniqueMsgIdAllowed="true">
    <message name="Msg1Form1" id="1" order="0" >
        ...
    </message>

    <message name="Msg1Form2" id="1" order="1">
        ...
    </message>    
</schema>
```

**NOTE** that there is a need to set **nonUniqueMsgIdAllowed** property of the [schema](schema) to **true** to allow multiple message objects with the same numeric ID.

All the **order** values for the same numeric ID must be unique, but not necessarily sequential.

## Versioning

**CommsDSL** allows providing an information in what version the message was added to the protocol, as well as in what version it was deprecated, and whether it was removed (not supported any more) after deprecation.

To specify the version in which message was introduced, use **sinceVersion** property. To specify the version in which the message was deprecated, use **deprecated** property. To specify whether the message was removed after being deprecated use **removed** property in addition to **deprecated**.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big" version="5" >
    <message name="SomeMessage" id="100" sinceVersion="2" >
        ...
    </message>

    <message name="SomeOtherMessage" id="101" sinceVersion="3" deprecated="4" removed="true">
        ...
    </message>

</schema>
```

In the example above _SomeMessage_ was introduced in version _2_, and _SomeOtherMessage_ was introduced in version _3_, but deprecated and removed in version _4_.

**NOTE**, that all the specified versions mustn't be greater that the version of the [schema](schema). Also value of **sinceVersion** must be **less** than value of **deprecated**.

The code generator is expected to be able to generate support for specific versions and include / exclude support for some messages based on their version information.

## Platforms

Some protocols may be used in multiple independent platforms, while having some platform-specific messages. The **CommsDSL** allows listing of the supported platforms using [\<platform>](platforms) XML nodes. Every message may list platforms in which it must be supported using **platforms** [property](properties). In case the property's value is empty (default), the message is supported in **all** the available platforms (if any defined). The **platforms** property value is coma-separated list of platform names with preceding **+** if the listed platforms are the one supported, or **-** if the listed platforms need to be **excluded** from all available ones.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <platform name="Plat1" />
    <platform name="Plat2" />
    <platform name="Plat3" />
    <platform name="Plat4" />

    <message name="Msg1" id="1" platforms="+Plat1,Plat4">
        ...
    </message>

    <message name="Msg2" id="2" platforms="-Plat1, Plat2">
        ...
    </message>
</schema>
```

In the example above _Msg1_ is supported only for platforms _Plat1_ and _Plat4_, while _Msg2_ is **NOT** supported in _Plat1_, and _Plat2_ (i.e. supported in _Plat3_ and _Plat4_).

The main consideration for what format to choose should be whether the platforms support for the message should or should **NOT** be added automatically when new **\<platform>** is defined.

## Sender

In most protocols there are uni-directional messages. The **CommsDSL** allows definition of entity that sends a particular message using **sender** property. Available values are **both** (default), **server**, and **client**. The code generator may use provided information and generate some auxiliary code and/or data structures to be used for _client_ and/or _server_ implementation.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" id="1" sender="client">
        ...
    </message>

    <message name="Msg2" id="2" sender="server">
        ...
    </message>

    <message name="Msg3" id="2">
        ...
    </message>
</schema>
```

In the example above _Msg1_ and _Msg2_ are uni-directional messages, while _Msg3_ is bi-directional.

## Customization

The code generator is expected to allow some level of compile time customization of the generated code, such as enable/disable generation of particular virtual functions. The code generator is also expected to provide command line options to choose required level of customization. Sometimes it may be required to allow generated message class to be customizable regardless of the customization level requested from the code generator. **CommsDSL** provides **customizable** property with [boolean](boolean) value to force any message to being customizable at compile time.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" id="1" customizable="true">
        ...
    </message>
</schema>
```

## Alias Names to Member Fields

Sometimes an existing member field may be renamed and/or moved. It is possible to create alias names for the fields to keep the old client code being able to compile and work. Please refer to [Aliases](aliases) chapter for more details.

Use [properties table](appendix/message) for future references.
