private void generateEnumProperty(
        final StringBuilder sb,
        final String containingClassName,
        final Token fieldToken,
        final String propertyName,
        final Token encodingToken,
        final FieldPrecedenceModel fieldPrecedenceModel,
        final String indent)
    {
        final String enumName = formatClassName(encodingToken.applicableTypeName());
        final PrimitiveType primitiveType = encodingToken.encoding().primitiveType();
        final String typeName = cppTypeName(primitiveType);
        final int offset = encodingToken.offset();

        new Formatter(sb).format("\n" +
            indent + "    SBE_NODISCARD static SBE_CONSTEXPR std::size_t %1$sEncodingLength() SBE_NOEXCEPT\n" +
            indent + "    {\n" +
            indent + "        return %2$d;\n" +
            indent + "    }\n",
            propertyName,
            fieldToken.encodedLength());

        if (fieldToken.isConstantEncoding())
        {
            final String constValue = fieldToken.encoding().constValue().toString();

            new Formatter(sb).format("\n" +
                indent + "    SBE_NODISCARD static SBE_CONSTEXPR %1$s::Value %2$sConstValue() SBE_NOEXCEPT\n" +
                indent + "    {\n" +
                indent + "        return %1$s::Value::%3$s;\n" +
                indent + "    }\n",
                enumName,
                propertyName,
                constValue.substring(constValue.indexOf(".") + 1));

            new Formatter(sb).format("\n" +
                indent + "    SBE_NODISCARD %1$s::Value %2$s() const\n" +
                indent + "    {\n" +
                "%3$s" +
                indent + "        return %1$s::Value::%4$s;\n" +
                indent + "    }\n",
                enumName,
                propertyName,
                generateEnumFieldNotPresentCondition(fieldToken.version(), enumName, indent),
                constValue.substring(constValue.indexOf(".") + 1));

            new Formatter(sb).format("\n" +
                indent + "    SBE_NODISCARD %1$s %2$sRaw() const SBE_NOEXCEPT\n" +
                indent + "    {\n" +
                indent + "        return static_cast<%1$s>(%3$s::Value::%4$s);\n" +
                indent + "    }\n",
                typeName,
                propertyName,
                enumName,
                constValue.substring(constValue.indexOf(".") + 1));
        }
        else
        {
            final String offsetStr = Integer.toString(offset);

            final CharSequence accessOrderListenerCall = generateAccessOrderListenerCall(
                fieldPrecedenceModel, indent + TWO_INDENT, fieldToken);

            final String noexceptDeclaration = noexceptDeclaration(fieldPrecedenceModel);

            new Formatter(sb).format("\n" +
                indent + "    SBE_NODISCARD %1$s %2$sRaw() const%6$s\n" +
                indent + "    {\n" +
                "%3$s" +
                "%4$s" +
                "%5$s" +
                indent + "    }\n",
                typeName,
                propertyName,
                generateFieldNotPresentCondition(fieldToken.version(), encodingToken.encoding(), indent),
                accessOrderListenerCall,
                generateLoadValue(primitiveType, offsetStr, encodingToken.encoding().byteOrder(), indent),
                noexceptDeclaration);

            new Formatter(sb).format("\n" +
                indent + "    SBE_NODISCARD %1$s::Value %2$s() const\n" +
                indent + "    {\n" +
                "%3$s" +
                "%7$s" +
                indent + "        %5$s val;\n" +
                indent + "        std::memcpy(&val, m_buffer + m_offset + %6$d, sizeof(%5$s));\n" +
                indent + "        return %1$s::get(%4$s(val));\n" +
                indent + "    }\n",
                enumName,
                propertyName,
                generateEnumFieldNotPresentCondition(fieldToken.version(), enumName, indent),
                formatByteOrderEncoding(encodingToken.encoding().byteOrder(), primitiveType),
                typeName,
                offset,
                accessOrderListenerCall);

            new Formatter(sb).format("\n" +
                indent + "    %1$s &%2$s(const %3$s::Value value)%8$s\n" +
                indent + "    {\n" +
                "%7$s" +
                indent + "        %4$s val = %6$s(value);\n" +
                indent + "        std::memcpy(m_buffer + m_offset + %5$d, &val, sizeof(%4$s));\n" +
                indent + "        return *this;\n" +
                indent + "    }\n",
                formatClassName(containingClassName),
                propertyName,
                enumName,
                typeName,
                offset,
                formatByteOrderEncoding(encodingToken.encoding().byteOrder(), primitiveType),
                accessOrderListenerCall,
                noexceptDeclaration);
        }
    }
\n");
        sb.append("     * The states in which a encoder/decoder/codec can live.\n");
        sb.append("     *\n");
        sb.append("     * <p>The state machine diagram below, encoded in the dot language, describes\n");
        sb.append("     * the valid state transitions according to the order in which fields may be\n");
        sb.append("     * accessed safely. Tools such as PlantUML and Graphviz can render it.\n");
        sb.append("     *\n");
        sb.append("     * <pre>{@code\n");
        fieldPrecedenceModel.generateGraph(sb, "     *   ");
        sb.append("     * }</pre>\n");
        sb.append("
sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/cpp/CppGenerator.java