> 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/enum.md).

# enum Field

This field stores and abstracts away value of integral [enumerated type](https://en.wikipedia.org/wiki/Enumerated_type), where every valid value has its name. The **\<enum>** field has all the [common](/commsdsl-specification/fields/common.md) properties as well as extra properties and elements described below.

## Underlying Type

Every **\<enum>** field must provide its underlying storage type using **type** [property](/commsdsl-specification/properties.md). Available values are:

* **int8** - 1 byte signed integer.
* **uint8** - 1 byte unsigned integer.
* **int16** - 2 bytes signed integer.
* **uint16** - 2 bytes unsigned integer.
* **int32** - 4 bytes signed integer.
* **uint32** - 4 bytes unsigned integer.
* **int64** - 8 bytes signed integer.
* **uint64** - 8 bytes unsigned integer.
* **intvar** - up to 8 bytes variable length signed integer
* **uintvar** - up to 8 bytes variable length unsigned integer

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <enum name="SomeEnumField" type="uint8">
            ...
        </enum>
    </fields>
</schema>
```

The variable length types are encoded using **Base-128** form, such as [LEB128](https://en.wikipedia.org/wiki/LEB128) for *little* endian or similar for *big* endian.

## Valid Values

All the valid values must be listed as **\<validValue>** child of the **\<enum>** XML element.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <enum name="SomeEnumField" type="uint8">
            <validValue name="Val1" val="0" />
            <validValue name="Val2" val="5" />
            <validValue name="Val3" val="0x1b" />
        </enum>
    </fields>
</schema>
```

Every **\<validValue>** must define a valid [name](/commsdsl-specification/names.md) (using **name** [property](/commsdsl-specification/properties.md)) as well as [numeric](/commsdsl-specification/numeric.md) value (using **val** [property](/commsdsl-specification/properties.md)), that fits chosen [underlying type](/commsdsl-specification/fields/enum.md#underlying-type). The **\<validValue>**-es may be listed in any order, not necessarily sorted.

Every **\<validValue>** has extra optional properties:

* **description** - Extra description and documentation on how to use the value.
* **displayName** - String specifying how to name the value in various analysis tools.
* **sinceVersion** - Version of the protocol when the value was introduced.
* **deprecated** - Version of the protocol when the value was deprecated.

All these extra properties are described in detail in [Common Properties of Fields](/commsdsl-specification/fields/common.md).

## Default Value

The default value of the **\<enum>** field when constructed can be specified using **defaultValue** property. If not specified, defaults to **0**.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <enum name="SomeEnumField" type="uint8" defaultValue="5">
            <validValue name="Val1" val="0" />
            <validValue name="Val2" val="5" />
            <validValue name="Val3" val="0x1b" />
        </enum>
    </fields>
</schema>
```

The default value can also be specified using the name of one of the **\<validValue>**-es:

```
<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <enum name="SomeEnumField" type="uint8" defaultValue="Val2">
            <validValue name="Val1" val="0" />
            <validValue name="Val2" val="5" />
            <validValue name="Val3" val="0x1b" />
        </enum>
    </fields>
</schema>
```

## Endian

The default serialization endian of the protocol is specified in **endian** property of the [schema](/commsdsl-specification/schema.md). It is possible to override the default endian value with extra **endian** property.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <fields>
        <enum name="SomeEnumField" type="uint16" endian="little">
            <validValue name="Val1" val="0" />
            <validValue name="Val2" val="5" />
            <validValue name="Val3" val="0x1b" />
        </enum>
    </fields>
</schema>
```

## Serialization Length

The [underlying type](/commsdsl-specification/fields/enum.md#underlying-type) dictates the serialization length of the **\<enum>** field. However, there may be protocols that limit serialization length of the field to non-standard lengths, such as **3** bytes. In this case use **length** property to specify custom serialization length.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <fields>
        <enum name="SomeEnumField" type="uint32" length="3">
            <validValue name="Val1" val="0x0" />
            <validValue name="Val2" val="0x0a0b0c" />
            <validValue name="Val3" val="0xffffff" />
        </enum>
    </fields>
</schema>
```

**IMPORTANT**: When **length** property is used with variable length [underlying types](/commsdsl-specification/fields/enum.md#underlying-type) (**intvar** and **uintvar**), it means **maximum** allowed length.

## Length in Bits

**\<enum>** field can be a member of [\<bitfield>](/commsdsl-specification/fields/bitfield.md) field. In this case the serialization length may be specified in bits using **bitLength** [property](/commsdsl-specification/properties.md).

```
<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <fields>
        <bitfield name="SomeBitfield">
            <enum name="SomeEnumMember" type="uint8" bitLength="3">
                <validValue name="Val1" val="0" />
                <validValue name="Val2" val="1" />
                <validValue name="Val3" val="2" />
            </enum>

            <enum name="SomeOtherEnumMember" type="uint8" bitLength="5">
                <validValue name="Val1" val="5" />
                <validValue name="Val2" val="12" />
                <validValue name="Val3" val="20" />
            </enum>
        </bitfield>
    </fields>
</schema>
```

## Hex Assignment

The code generator is expected to generate appropriate **enum** types using **decimal** values assigned to enumeration names. However, some protocol specifications may list valid values using **hexadecimal** format. To make the reading of the generated code more convenient, use **hexAssign** [property](/commsdsl-specification/properties.md) with [boolean](/commsdsl-specification/boolean.md) value to force code generator make the assignments using hexadecimal values.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <fields>
        <enum name="SomeEnumField" type="uint8" hexAssign="true">
            <validValue name="Val1" val="0" />
            <validValue name="Val2" val="5" />
            <validValue name="Val3" val="0x1b" />
        </enum>
    </fields>
</schema>
```

The generated enum type is expected to look something like this:

```cpp
enum class SomeEnumFieldVal
{
    Val1 = 0x00,
    Val2 = 0x05,
    Val3 = 0x1b
};
```

instead of

```cpp
enum class SomeEnumFieldVal
{
    Val1 = 0,
    Val2 = 5,
    Val3 = 27
};
```

## Allow Non-Unique Values

By default, non-unqiue values are not allowed, the code generator must report an error if two different **\<validValue>**-es use the same value of the **val** property. It is done as protection against copy-paste errors. However, **CommsDSL** allows usage of non-unique values in case **nonUniqueAllowed** [property](/commsdsl-specification/properties.md) has been set to **true**.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <fields>
        <enum name="SomeEnumField" type="uint8" nonUniqueAllowed="true">
            <validValue name="Val1" val="0" />
            <validValue name="Val2" val="5" />
            <validValue name="OtherNameForVal2" val="5" />
        </enum>
    </fields>
</schema>
```

## Version Based Validity

The code generator is expected to generate functionality checking that **\<enum>** field contains a valid value. By default any specified **\<validValue>** is considered to be valid regardless of version it was introduced and/or deprecated. However, it is possible to force code generator to generate validity check code that takes into account reported version of the protocol by using **validCheckVersion** [property](/commsdsl-specification/properties.md), which is set to **true**.

```
<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big" version="5">
    <fields>
        <enum name="SomeEnumField" type="uint8" validCheckVersion="true">
            <validValue name="Val1" val="0" />
            <validValue name="Val2" val="5" />
            <validValue name="Val3" val="10" sinceVersion="2" />
            <validValue name="Val4" val="15" sinceVersion="3" deprecated="4"/>
        </enum>
    </fields>
</schema>
```

In the example above values **0** and **5** will always be considered valid. However value **10** will be considered valid only if reported protocol version is greater than or equal to **2**. The value **15** will be considered valid only for protocol version **3**.

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