> For the complete documentation index, see [llms.txt](https://alex-robenko.gitbook.io/commsdsl-specification/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alex-robenko.gitbook.io/commsdsl-specification/fields/optional.md).

# optional Field

This field wraps other [fields](/commsdsl-specification/fields.md) and makes the wrapped field optional, i.e. the serialization of the latter may be skipped if it is marked as "missing". The **\<optional>** field has all the [common](/commsdsl-specification/fields/common.md) properties as well as extra properties and elements described below.

## Inner (Wrapped) Field

Every **\<optional>** must specify its inner [field](/commsdsl-specification/fields.md). The wrapped field can be defined as XML child of the **\<optional>** definition.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <optional name="SomeOptionalField">
            <int name="SomeOptionalField" type="uint32" />
        </optional>
    </fields>
</schema>
```

In case other properties of the **\<optional>** field are defined as child XML elements, then the element field definition needs to be wrapped by **\<field>** XML child.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <optional name="SomeOptionalField">
            <displayName value="Some descriptive name" />
            <field>
                <int name="SomeOptionalField" type="uint32" />
            </field>
        </optional>
    </fields>
</schema>
```

The **CommsDSL** also allows reference of externally defined field to be specified as inner (wrapped) field type using **field** [property](/commsdsl-specification/properties.md).

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <int name="SomeExternalField" type="uint32" />
        <optional name="SomeOptionalField" field="SomeExternalField" />
    </fields>
</schema>
```

## Default Mode

Every **\<optional>** field has 3 modes: **tenative** (default), **exist**, and **missing**. The **exist** and **missing** modes are self explanatory. The **tentative** mode is there to perform *read* operation on the inner field only if there are non-consumed bytes left in the input buffer. This mode can be useful with protocols that just add fields at the end of the [message](/commsdsl-specification/messages.md) in the new version, but the protocol itself doesn't report its version in any other way.

The default mode of the newly constructed **\<optional>** field can be specified using **defaultMode** [property](/commsdsl-specification/properties.md).

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <optional name="SomeOptionalField" defaultMode="missing">
            <int name="SomeOptionalField" type="uint32" />
        </optional>
    </fields>
</schema>
```

## Existence Condition

Many protocols introduce optional fields, and the existence of such fields depend on the value of some other field. Classic example would be having some kind of flags field (see [**\<set>**](/commsdsl-specification/fields/set.md)) where some bit specifies whether other field that follows exists or not. Such conditions can be expressed using **cond** [property](/commsdsl-specification/properties.md).

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" id="1">
        <set name="Flags">
            <bit name="Val1Exists" idx="0" />
        </set>
        <optional name="Val1" defaultMode="missing" cond="$Flags.Val1Exists">
            <int name="WrappedVal1" type="uint32" />
        </optional>
    </fields>
</schema>
```

**NOTE**, that **cond** property can be used only for **\<optional>** field that is a member of a [**\<bundle>**](/commsdsl-specification/fields/bundle.md) or a [**\<message>**](/commsdsl-specification/messages.md). The **cond** expression specifies condition when the **\<optional>** field exists, and must always reference other **sibling** field. Such reference is always prefixed with **$** character to indicate that the field is a **sibling** of the **\<optional>** and not some external field.

The allowed **cond** expressions are:

* $*set\_field\_name.bit\_name* - The wrapped field exists if specified bit is set to **true** (**1**).
* !$*set\_field\_name.bit\_name* - The wrapped field exists if specified bit is set to **false** (**0**).
* $*field\_name* *compare\_op* *value* - The wrapped field exists if comparison&#x20;

  of the specified field with specified value is true. The *compare\_op* can be:

  **=** (equality), **!=** (inequality), **<** (less than), **<=** (less than or equal),

  **>** (greater than), **>=** (greater than or equal).
* $*field\_name* *compare\_op* $*other\_field\_name* - The wrapped field exists if comparison&#x20;

  of the specified fields is true.&#x20;

**NOTE**, that XML doesn't allow usage of `<` or `>` symbols in condition values directly. They need to be substituted with `&lt;` and `&gt;` strings respectively.

For example, there are 2 normal fields followed by a third optional one. The latter exists, only if value of **F1** is less than value of **F2**

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" id="1">
        <int name="F1" type="uint16" />
        <int name="F2" type="uint16" />
        <optional name="F3" defaultMode="exists" cond="$F1 &lt; $F2">
            <int name="WrappedF3" type="uint32" />
        </optional>
    </fields>
</schema>
```

## Multiple Existence Conditions

The **CommsDSL** also allows usage of multiple existence condition statements. However, they need to be wrapped by either **\<and>** or **\<or>** XML child elements, which represent "**and**" and "**or**" logical conditions respectively.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" id="1">
        <int name="F1" type="uint16" />
        <int name="F2" type="uint16" />
        <optional name="F3" defaultMode="exists">
            <field>
                <int name="WrappedF3" type="uint32" />
            </field>
            <or>
                <cond value="$F1 = 0" />
                <and>
                    <cond value="$F1 = 1" />
                    <cond value="$F2 != 0" />
                </and>
            </or>
        </optional>
    </fields>
</schema>
```

In the example the **F3** field exists in one of the following conditions:

* Value of **F1** is 0.
* Value of **F1** is 1 and value of **F2** is not 0.

## Extra Display Property

By default GUI protocol analysis tools should allow manual update of the **\<optional>** field mode. However, if the mode is controlled by the values of other fields, it is possible to disable manual update of the mode by using **displayExtModeCtrl** (stands for "display external mode control") [property](/commsdsl-specification/properties.md) with [boolean](/commsdsl-specification/boolean.md) value.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <message name="Msg1" id="1">
        <set name="Flags">
            <bit name="Val1Exists" idx="0" />
        </set>
        <optional name="Val1" defaultMode="missing" cond="$Flags.Val1Exists">
            <displayExtModeCtrl value="true" />
            <field>
                <int name="WrappedVal1" type="uint32" />
            </field>
        </optional>
    </fields>
</schema>
```

Use [properties table](/commsdsl-specification/appendix/optional.md) for future references.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alex-robenko.gitbook.io/commsdsl-specification/fields/optional.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
