/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

// THIS FILE IS GENERATED BY ZAP

#include <app-common/zap-generated/cluster-objects.h>

namespace chip {
namespace app {
namespace Clusters {

namespace detail {
// Structs shared across multiple clusters.
namespace Structs {
namespace LabelStruct {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLabel)), label));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kValue)), value));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kLabel):
            ReturnErrorOnFailure(DataModel::Decode(reader, label));
            break;
        case to_underlying(Fields::kValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, value));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace LabelStruct
} // namespace Structs
} // namespace detail

namespace Identify {

namespace Commands {
namespace Identify {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIdentifyTime)), identifyTime));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kIdentifyTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, identifyTime));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Identify.
namespace TriggerEffect {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEffectIdentifier)), effectIdentifier));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEffectVariant)), effectVariant));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kEffectIdentifier):
            ReturnErrorOnFailure(DataModel::Decode(reader, effectIdentifier));
            break;
        case to_underlying(Fields::kEffectVariant):
            ReturnErrorOnFailure(DataModel::Decode(reader, effectVariant));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TriggerEffect.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::IdentifyTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, identifyTime));
        break;
    case Attributes::IdentifyType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, identifyType));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace Identify
namespace Groups {

namespace Commands {
namespace AddGroup {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupName)), groupName));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kGroupName):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupName));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AddGroup.
namespace AddGroupResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AddGroupResponse.
namespace ViewGroup {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ViewGroup.
namespace ViewGroupResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupName)), groupName));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kGroupName):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupName));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ViewGroupResponse.
namespace GetGroupMembership {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupList)), groupList));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupList):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupList));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetGroupMembership.
namespace GetGroupMembershipResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCapacity)), capacity));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupList)), groupList));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCapacity):
            ReturnErrorOnFailure(DataModel::Decode(reader, capacity));
            break;
        case to_underlying(Fields::kGroupList):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupList));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetGroupMembershipResponse.
namespace RemoveGroup {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RemoveGroup.
namespace RemoveGroupResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RemoveGroupResponse.
namespace RemoveAllGroups {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RemoveAllGroups.
namespace AddGroupIfIdentifying {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupName)), groupName));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kGroupName):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupName));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AddGroupIfIdentifying.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::NameSupport::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nameSupport));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace Groups
namespace Scenes {
namespace Structs {
namespace AttributeValuePair {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAttributeId)), attributeId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAttributeValue)), attributeValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kAttributeId):
            ReturnErrorOnFailure(DataModel::Decode(reader, attributeId));
            break;
        case to_underlying(Fields::kAttributeValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, attributeValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace AttributeValuePair
namespace ExtensionFieldSet {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kClusterId)), clusterId));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAttributeValueList)), attributeValueList));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kClusterId):
            ReturnErrorOnFailure(DataModel::Decode(reader, clusterId));
            break;
        case to_underlying(Fields::kAttributeValueList):
            ReturnErrorOnFailure(DataModel::Decode(reader, attributeValueList));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ExtensionFieldSet
} // namespace Structs

namespace Commands {
namespace AddScene {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneName)), sceneName));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kExtensionFieldSets)), extensionFieldSets));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kSceneName):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneName));
            break;
        case to_underlying(Fields::kExtensionFieldSets):
            ReturnErrorOnFailure(DataModel::Decode(reader, extensionFieldSets));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AddScene.
namespace AddSceneResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AddSceneResponse.
namespace ViewScene {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ViewScene.
namespace ViewSceneResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneName)), sceneName));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kExtensionFieldSets)), extensionFieldSets));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kSceneName):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneName));
            break;
        case to_underlying(Fields::kExtensionFieldSets):
            ReturnErrorOnFailure(DataModel::Decode(reader, extensionFieldSets));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ViewSceneResponse.
namespace RemoveScene {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RemoveScene.
namespace RemoveSceneResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RemoveSceneResponse.
namespace RemoveAllScenes {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RemoveAllScenes.
namespace RemoveAllScenesResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RemoveAllScenesResponse.
namespace StoreScene {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StoreScene.
namespace StoreSceneResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StoreSceneResponse.
namespace RecallScene {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RecallScene.
namespace GetSceneMembership {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetSceneMembership.
namespace GetSceneMembershipResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCapacity)), capacity));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneList)), sceneList));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kCapacity):
            ReturnErrorOnFailure(DataModel::Decode(reader, capacity));
            break;
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneList):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneList));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetSceneMembershipResponse.
namespace EnhancedAddScene {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneName)), sceneName));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kExtensionFieldSets)), extensionFieldSets));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kSceneName):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneName));
            break;
        case to_underlying(Fields::kExtensionFieldSets):
            ReturnErrorOnFailure(DataModel::Decode(reader, extensionFieldSets));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace EnhancedAddScene.
namespace EnhancedAddSceneResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace EnhancedAddSceneResponse.
namespace EnhancedViewScene {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace EnhancedViewScene.
namespace EnhancedViewSceneResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneId)), sceneId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneName)), sceneName));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kExtensionFieldSets)), extensionFieldSets));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kSceneId):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneId));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kSceneName):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneName));
            break;
        case to_underlying(Fields::kExtensionFieldSets):
            ReturnErrorOnFailure(DataModel::Decode(reader, extensionFieldSets));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace EnhancedViewSceneResponse.
namespace CopyScene {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMode)), mode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupIdFrom)), groupIdFrom));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneIdFrom)), sceneIdFrom));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupIdTo)), groupIdTo));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneIdTo)), sceneIdTo));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, mode));
            break;
        case to_underlying(Fields::kGroupIdFrom):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupIdFrom));
            break;
        case to_underlying(Fields::kSceneIdFrom):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneIdFrom));
            break;
        case to_underlying(Fields::kGroupIdTo):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupIdTo));
            break;
        case to_underlying(Fields::kSceneIdTo):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneIdTo));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace CopyScene.
namespace CopySceneResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupIdFrom)), groupIdFrom));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSceneIdFrom)), sceneIdFrom));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kGroupIdFrom):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupIdFrom));
            break;
        case to_underlying(Fields::kSceneIdFrom):
            ReturnErrorOnFailure(DataModel::Decode(reader, sceneIdFrom));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace CopySceneResponse.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::SceneCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, sceneCount));
        break;
    case Attributes::CurrentScene::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentScene));
        break;
    case Attributes::CurrentGroup::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentGroup));
        break;
    case Attributes::SceneValid::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, sceneValid));
        break;
    case Attributes::NameSupport::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nameSupport));
        break;
    case Attributes::LastConfiguredBy::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lastConfiguredBy));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace Scenes
namespace OnOff {

namespace Commands {
namespace Off {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Off.
namespace On {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace On.
namespace Toggle {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Toggle.
namespace OffWithEffect {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEffectId)), effectId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEffectVariant)), effectVariant));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kEffectId):
            ReturnErrorOnFailure(DataModel::Decode(reader, effectId));
            break;
        case to_underlying(Fields::kEffectVariant):
            ReturnErrorOnFailure(DataModel::Decode(reader, effectVariant));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace OffWithEffect.
namespace OnWithRecallGlobalScene {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace OnWithRecallGlobalScene.
namespace OnWithTimedOff {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOnOffControl)), onOffControl));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOnTime)), onTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOffWaitTime)), offWaitTime));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kOnOffControl):
            ReturnErrorOnFailure(DataModel::Decode(reader, onOffControl));
            break;
        case to_underlying(Fields::kOnTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, onTime));
            break;
        case to_underlying(Fields::kOffWaitTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, offWaitTime));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace OnWithTimedOff.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::OnOff::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, onOff));
        break;
    case Attributes::GlobalSceneControl::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, globalSceneControl));
        break;
    case Attributes::OnTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, onTime));
        break;
    case Attributes::OffWaitTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, offWaitTime));
        break;
    case Attributes::StartUpOnOff::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, startUpOnOff));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace OnOff
namespace OnOffSwitchConfiguration {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::SwitchType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, switchType));
        break;
    case Attributes::SwitchActions::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, switchActions));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace OnOffSwitchConfiguration
namespace LevelControl {

namespace Commands {
namespace MoveToLevel {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLevel)), level));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kLevel):
            ReturnErrorOnFailure(DataModel::Decode(reader, level));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveToLevel.
namespace Move {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMoveMode)), moveMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRate)), rate));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMoveMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, moveMode));
            break;
        case to_underlying(Fields::kRate):
            ReturnErrorOnFailure(DataModel::Decode(reader, rate));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Move.
namespace Step {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepMode)), stepMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepSize)), stepSize));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStepMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepMode));
            break;
        case to_underlying(Fields::kStepSize):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepSize));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Step.
namespace Stop {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Stop.
namespace MoveToLevelWithOnOff {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLevel)), level));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kLevel):
            ReturnErrorOnFailure(DataModel::Decode(reader, level));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveToLevelWithOnOff.
namespace MoveWithOnOff {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMoveMode)), moveMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRate)), rate));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMoveMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, moveMode));
            break;
        case to_underlying(Fields::kRate):
            ReturnErrorOnFailure(DataModel::Decode(reader, rate));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveWithOnOff.
namespace StepWithOnOff {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepMode)), stepMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepSize)), stepSize));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStepMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepMode));
            break;
        case to_underlying(Fields::kStepSize):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepSize));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StepWithOnOff.
namespace StopWithOnOff {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StopWithOnOff.
namespace MoveToClosestFrequency {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFrequency)), frequency));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kFrequency):
            ReturnErrorOnFailure(DataModel::Decode(reader, frequency));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveToClosestFrequency.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::CurrentLevel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentLevel));
        break;
    case Attributes::RemainingTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, remainingTime));
        break;
    case Attributes::MinLevel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minLevel));
        break;
    case Attributes::MaxLevel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxLevel));
        break;
    case Attributes::CurrentFrequency::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentFrequency));
        break;
    case Attributes::MinFrequency::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minFrequency));
        break;
    case Attributes::MaxFrequency::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxFrequency));
        break;
    case Attributes::Options::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, options));
        break;
    case Attributes::OnOffTransitionTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, onOffTransitionTime));
        break;
    case Attributes::OnLevel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, onLevel));
        break;
    case Attributes::OnTransitionTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, onTransitionTime));
        break;
    case Attributes::OffTransitionTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, offTransitionTime));
        break;
    case Attributes::DefaultMoveRate::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, defaultMoveRate));
        break;
    case Attributes::StartUpCurrentLevel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, startUpCurrentLevel));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace LevelControl
namespace BinaryInputBasic {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::ActiveText::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeText));
        break;
    case Attributes::Description::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, description));
        break;
    case Attributes::InactiveText::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, inactiveText));
        break;
    case Attributes::OutOfService::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, outOfService));
        break;
    case Attributes::Polarity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, polarity));
        break;
    case Attributes::PresentValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, presentValue));
        break;
    case Attributes::Reliability::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, reliability));
        break;
    case Attributes::StatusFlags::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, statusFlags));
        break;
    case Attributes::ApplicationType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, applicationType));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace BinaryInputBasic
namespace PulseWidthModulation {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace PulseWidthModulation
namespace Descriptor {
namespace Structs {
namespace DeviceType {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kType)), type));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRevision)), revision));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kType):
            ReturnErrorOnFailure(DataModel::Decode(reader, type));
            break;
        case to_underlying(Fields::kRevision):
            ReturnErrorOnFailure(DataModel::Decode(reader, revision));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace DeviceType
} // namespace Structs

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::DeviceList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, deviceList));
        break;
    case Attributes::ServerList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, serverList));
        break;
    case Attributes::ClientList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clientList));
        break;
    case Attributes::PartsList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, partsList));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace Descriptor
namespace Binding {
namespace Structs {
namespace TargetStruct {
CHIP_ERROR Type::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    return DoEncode(writer, tag, NullOptional);
}

CHIP_ERROR Type::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex accessingFabricIndex) const
{
    return DoEncode(writer, tag, MakeOptional(accessingFabricIndex));
}

CHIP_ERROR Type::DoEncode(TLV::TLVWriter & writer, TLV::Tag tag, const Optional<FabricIndex> & accessingFabricIndex) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNode)), node));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroup)), group));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndpoint)), endpoint));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCluster)), cluster));
    if (accessingFabricIndex.HasValue())
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    }
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNode):
            ReturnErrorOnFailure(DataModel::Decode(reader, node));
            break;
        case to_underlying(Fields::kGroup):
            ReturnErrorOnFailure(DataModel::Decode(reader, group));
            break;
        case to_underlying(Fields::kEndpoint):
            ReturnErrorOnFailure(DataModel::Decode(reader, endpoint));
            break;
        case to_underlying(Fields::kCluster):
            ReturnErrorOnFailure(DataModel::Decode(reader, cluster));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace TargetStruct
} // namespace Structs

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::Binding::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, binding));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace Binding
namespace AccessControl {
namespace Structs {
namespace Target {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCluster)), cluster));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndpoint)), endpoint));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDeviceType)), deviceType));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCluster):
            ReturnErrorOnFailure(DataModel::Decode(reader, cluster));
            break;
        case to_underlying(Fields::kEndpoint):
            ReturnErrorOnFailure(DataModel::Decode(reader, endpoint));
            break;
        case to_underlying(Fields::kDeviceType):
            ReturnErrorOnFailure(DataModel::Decode(reader, deviceType));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace Target
namespace AccessControlEntry {
CHIP_ERROR Type::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    return DoEncode(writer, tag, NullOptional);
}

CHIP_ERROR Type::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex accessingFabricIndex) const
{
    return DoEncode(writer, tag, MakeOptional(accessingFabricIndex));
}

CHIP_ERROR Type::DoEncode(TLV::TLVWriter & writer, TLV::Tag tag, const Optional<FabricIndex> & accessingFabricIndex) const
{
    bool includeSensitive = !accessingFabricIndex.HasValue() || (accessingFabricIndex.Value() == fabricIndex);
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    if (includeSensitive)
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPrivilege)), privilege));
    }
    if (includeSensitive)
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAuthMode)), authMode));
    }
    if (includeSensitive)
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSubjects)), subjects));
    }
    if (includeSensitive)
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTargets)), targets));
    }
    if (accessingFabricIndex.HasValue())
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    }
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kPrivilege):
            ReturnErrorOnFailure(DataModel::Decode(reader, privilege));
            break;
        case to_underlying(Fields::kAuthMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, authMode));
            break;
        case to_underlying(Fields::kSubjects):
            ReturnErrorOnFailure(DataModel::Decode(reader, subjects));
            break;
        case to_underlying(Fields::kTargets):
            ReturnErrorOnFailure(DataModel::Decode(reader, targets));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace AccessControlEntry
namespace ExtensionEntry {
CHIP_ERROR Type::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    return DoEncode(writer, tag, NullOptional);
}

CHIP_ERROR Type::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex accessingFabricIndex) const
{
    return DoEncode(writer, tag, MakeOptional(accessingFabricIndex));
}

CHIP_ERROR Type::DoEncode(TLV::TLVWriter & writer, TLV::Tag tag, const Optional<FabricIndex> & accessingFabricIndex) const
{
    bool includeSensitive = !accessingFabricIndex.HasValue() || (accessingFabricIndex.Value() == fabricIndex);
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    if (includeSensitive)
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kData)), data));
    }
    if (accessingFabricIndex.HasValue())
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    }
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kData):
            ReturnErrorOnFailure(DataModel::Decode(reader, data));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ExtensionEntry
} // namespace Structs

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::Acl::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acl));
        break;
    case Attributes::Extension::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, extension));
        break;
    case Attributes::SubjectsPerAccessControlEntry::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, subjectsPerAccessControlEntry));
        break;
    case Attributes::TargetsPerAccessControlEntry::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, targetsPerAccessControlEntry));
        break;
    case Attributes::AccessControlEntriesPerFabric::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, accessControlEntriesPerFabric));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace AccessControlEntryChanged {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAdminNodeID)), adminNodeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAdminPasscodeID)), adminPasscodeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kChangeType)), changeType));
    ReturnErrorOnFailure(
        DataModel::EncodeForRead(writer, TLV::ContextTag(to_underlying(Fields::kLatestValue)), GetFabricIndex(), latestValue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kAdminNodeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, adminNodeID));
            break;
        case to_underlying(Fields::kAdminPasscodeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, adminPasscodeID));
            break;
        case to_underlying(Fields::kChangeType):
            ReturnErrorOnFailure(DataModel::Decode(reader, changeType));
            break;
        case to_underlying(Fields::kLatestValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, latestValue));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AccessControlEntryChanged.
namespace AccessControlExtensionChanged {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAdminNodeID)), adminNodeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAdminPasscodeID)), adminPasscodeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kChangeType)), changeType));
    ReturnErrorOnFailure(
        DataModel::EncodeForRead(writer, TLV::ContextTag(to_underlying(Fields::kLatestValue)), GetFabricIndex(), latestValue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kAdminNodeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, adminNodeID));
            break;
        case to_underlying(Fields::kAdminPasscodeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, adminPasscodeID));
            break;
        case to_underlying(Fields::kChangeType):
            ReturnErrorOnFailure(DataModel::Decode(reader, changeType));
            break;
        case to_underlying(Fields::kLatestValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, latestValue));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AccessControlExtensionChanged.
} // namespace Events

} // namespace AccessControl
namespace BridgedActions {
namespace Structs {
namespace ActionStruct {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kType)), type));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndpointListID)), endpointListID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSupportedCommands)), supportedCommands));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        case to_underlying(Fields::kType):
            ReturnErrorOnFailure(DataModel::Decode(reader, type));
            break;
        case to_underlying(Fields::kEndpointListID):
            ReturnErrorOnFailure(DataModel::Decode(reader, endpointListID));
            break;
        case to_underlying(Fields::kSupportedCommands):
            ReturnErrorOnFailure(DataModel::Decode(reader, supportedCommands));
            break;
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ActionStruct
namespace EndpointListStruct {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndpointListID)), endpointListID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kType)), type));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndpoints)), endpoints));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kEndpointListID):
            ReturnErrorOnFailure(DataModel::Decode(reader, endpointListID));
            break;
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        case to_underlying(Fields::kType):
            ReturnErrorOnFailure(DataModel::Decode(reader, type));
            break;
        case to_underlying(Fields::kEndpoints):
            ReturnErrorOnFailure(DataModel::Decode(reader, endpoints));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace EndpointListStruct
} // namespace Structs

namespace Commands {
namespace InstantAction {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace InstantAction.
namespace InstantActionWithTransition {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace InstantActionWithTransition.
namespace StartAction {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StartAction.
namespace StartActionWithDuration {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDuration)), duration));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        case to_underlying(Fields::kDuration):
            ReturnErrorOnFailure(DataModel::Decode(reader, duration));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StartActionWithDuration.
namespace StopAction {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StopAction.
namespace PauseAction {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace PauseAction.
namespace PauseActionWithDuration {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDuration)), duration));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        case to_underlying(Fields::kDuration):
            ReturnErrorOnFailure(DataModel::Decode(reader, duration));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace PauseActionWithDuration.
namespace ResumeAction {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ResumeAction.
namespace EnableAction {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace EnableAction.
namespace EnableActionWithDuration {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDuration)), duration));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        case to_underlying(Fields::kDuration):
            ReturnErrorOnFailure(DataModel::Decode(reader, duration));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace EnableActionWithDuration.
namespace DisableAction {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace DisableAction.
namespace DisableActionWithDuration {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDuration)), duration));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        case to_underlying(Fields::kDuration):
            ReturnErrorOnFailure(DataModel::Decode(reader, duration));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace DisableActionWithDuration.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::ActionList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, actionList));
        break;
    case Attributes::EndpointList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, endpointList));
        break;
    case Attributes::SetupUrl::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, setupUrl));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace StateChanged {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNewState)), newState));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        case to_underlying(Fields::kNewState):
            ReturnErrorOnFailure(DataModel::Decode(reader, newState));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StateChanged.
namespace ActionFailed {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActionID)), actionID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInvokeID)), invokeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNewState)), newState));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kError)), error));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActionID):
            ReturnErrorOnFailure(DataModel::Decode(reader, actionID));
            break;
        case to_underlying(Fields::kInvokeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, invokeID));
            break;
        case to_underlying(Fields::kNewState):
            ReturnErrorOnFailure(DataModel::Decode(reader, newState));
            break;
        case to_underlying(Fields::kError):
            ReturnErrorOnFailure(DataModel::Decode(reader, error));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ActionFailed.
} // namespace Events

} // namespace BridgedActions
namespace Basic {
namespace Structs {
namespace CapabilityMinimaStruct {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCaseSessionsPerFabric)), caseSessionsPerFabric));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSubscriptionsPerFabric)), subscriptionsPerFabric));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCaseSessionsPerFabric):
            ReturnErrorOnFailure(DataModel::Decode(reader, caseSessionsPerFabric));
            break;
        case to_underlying(Fields::kSubscriptionsPerFabric):
            ReturnErrorOnFailure(DataModel::Decode(reader, subscriptionsPerFabric));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace CapabilityMinimaStruct
} // namespace Structs

namespace Commands {
namespace MfgSpecificPing {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MfgSpecificPing.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::DataModelRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dataModelRevision));
        break;
    case Attributes::VendorName::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, vendorName));
        break;
    case Attributes::VendorID::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, vendorID));
        break;
    case Attributes::ProductName::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, productName));
        break;
    case Attributes::ProductID::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, productID));
        break;
    case Attributes::NodeLabel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nodeLabel));
        break;
    case Attributes::Location::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, location));
        break;
    case Attributes::HardwareVersion::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, hardwareVersion));
        break;
    case Attributes::HardwareVersionString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, hardwareVersionString));
        break;
    case Attributes::SoftwareVersion::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersion));
        break;
    case Attributes::SoftwareVersionString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersionString));
        break;
    case Attributes::ManufacturingDate::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, manufacturingDate));
        break;
    case Attributes::PartNumber::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, partNumber));
        break;
    case Attributes::ProductURL::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, productURL));
        break;
    case Attributes::ProductLabel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, productLabel));
        break;
    case Attributes::SerialNumber::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, serialNumber));
        break;
    case Attributes::LocalConfigDisabled::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, localConfigDisabled));
        break;
    case Attributes::Reachable::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, reachable));
        break;
    case Attributes::UniqueID::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, uniqueID));
        break;
    case Attributes::CapabilityMinima::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, capabilityMinima));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace StartUp {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSoftwareVersion)), softwareVersion));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kSoftwareVersion):
            ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersion));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StartUp.
namespace ShutDown {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ShutDown.
namespace Leave {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Leave.
namespace ReachableChanged {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kReachableNewValue)), reachableNewValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kReachableNewValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, reachableNewValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ReachableChanged.
} // namespace Events

} // namespace Basic
namespace OtaSoftwareUpdateProvider {

namespace Commands {
namespace QueryImage {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kVendorId)), vendorId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kProductId)), productId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSoftwareVersion)), softwareVersion));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kProtocolsSupported)), protocolsSupported));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kHardwareVersion)), hardwareVersion));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLocation)), location));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRequestorCanConsent)), requestorCanConsent));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMetadataForProvider)), metadataForProvider));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kVendorId):
            ReturnErrorOnFailure(DataModel::Decode(reader, vendorId));
            break;
        case to_underlying(Fields::kProductId):
            ReturnErrorOnFailure(DataModel::Decode(reader, productId));
            break;
        case to_underlying(Fields::kSoftwareVersion):
            ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersion));
            break;
        case to_underlying(Fields::kProtocolsSupported):
            ReturnErrorOnFailure(DataModel::Decode(reader, protocolsSupported));
            break;
        case to_underlying(Fields::kHardwareVersion):
            ReturnErrorOnFailure(DataModel::Decode(reader, hardwareVersion));
            break;
        case to_underlying(Fields::kLocation):
            ReturnErrorOnFailure(DataModel::Decode(reader, location));
            break;
        case to_underlying(Fields::kRequestorCanConsent):
            ReturnErrorOnFailure(DataModel::Decode(reader, requestorCanConsent));
            break;
        case to_underlying(Fields::kMetadataForProvider):
            ReturnErrorOnFailure(DataModel::Decode(reader, metadataForProvider));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace QueryImage.
namespace QueryImageResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDelayedActionTime)), delayedActionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kImageURI)), imageURI));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSoftwareVersion)), softwareVersion));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSoftwareVersionString)), softwareVersionString));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUpdateToken)), updateToken));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserConsentNeeded)), userConsentNeeded));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMetadataForRequestor)), metadataForRequestor));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kDelayedActionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, delayedActionTime));
            break;
        case to_underlying(Fields::kImageURI):
            ReturnErrorOnFailure(DataModel::Decode(reader, imageURI));
            break;
        case to_underlying(Fields::kSoftwareVersion):
            ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersion));
            break;
        case to_underlying(Fields::kSoftwareVersionString):
            ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersionString));
            break;
        case to_underlying(Fields::kUpdateToken):
            ReturnErrorOnFailure(DataModel::Decode(reader, updateToken));
            break;
        case to_underlying(Fields::kUserConsentNeeded):
            ReturnErrorOnFailure(DataModel::Decode(reader, userConsentNeeded));
            break;
        case to_underlying(Fields::kMetadataForRequestor):
            ReturnErrorOnFailure(DataModel::Decode(reader, metadataForRequestor));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace QueryImageResponse.
namespace ApplyUpdateRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUpdateToken)), updateToken));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNewVersion)), newVersion));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kUpdateToken):
            ReturnErrorOnFailure(DataModel::Decode(reader, updateToken));
            break;
        case to_underlying(Fields::kNewVersion):
            ReturnErrorOnFailure(DataModel::Decode(reader, newVersion));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ApplyUpdateRequest.
namespace ApplyUpdateResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAction)), action));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDelayedActionTime)), delayedActionTime));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kAction):
            ReturnErrorOnFailure(DataModel::Decode(reader, action));
            break;
        case to_underlying(Fields::kDelayedActionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, delayedActionTime));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ApplyUpdateResponse.
namespace NotifyUpdateApplied {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUpdateToken)), updateToken));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSoftwareVersion)), softwareVersion));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kUpdateToken):
            ReturnErrorOnFailure(DataModel::Decode(reader, updateToken));
            break;
        case to_underlying(Fields::kSoftwareVersion):
            ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersion));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace NotifyUpdateApplied.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace OtaSoftwareUpdateProvider
namespace OtaSoftwareUpdateRequestor {
namespace Structs {
namespace ProviderLocation {
CHIP_ERROR Type::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    return DoEncode(writer, tag, NullOptional);
}

CHIP_ERROR Type::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex accessingFabricIndex) const
{
    return DoEncode(writer, tag, MakeOptional(accessingFabricIndex));
}

CHIP_ERROR Type::DoEncode(TLV::TLVWriter & writer, TLV::Tag tag, const Optional<FabricIndex> & accessingFabricIndex) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kProviderNodeID)), providerNodeID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndpoint)), endpoint));
    if (accessingFabricIndex.HasValue())
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    }
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kProviderNodeID):
            ReturnErrorOnFailure(DataModel::Decode(reader, providerNodeID));
            break;
        case to_underlying(Fields::kEndpoint):
            ReturnErrorOnFailure(DataModel::Decode(reader, endpoint));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ProviderLocation
} // namespace Structs

namespace Commands {
namespace AnnounceOtaProvider {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kProviderNodeId)), providerNodeId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kVendorId)), vendorId));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAnnouncementReason)), announcementReason));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMetadataForNode)), metadataForNode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndpoint)), endpoint));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kProviderNodeId):
            ReturnErrorOnFailure(DataModel::Decode(reader, providerNodeId));
            break;
        case to_underlying(Fields::kVendorId):
            ReturnErrorOnFailure(DataModel::Decode(reader, vendorId));
            break;
        case to_underlying(Fields::kAnnouncementReason):
            ReturnErrorOnFailure(DataModel::Decode(reader, announcementReason));
            break;
        case to_underlying(Fields::kMetadataForNode):
            ReturnErrorOnFailure(DataModel::Decode(reader, metadataForNode));
            break;
        case to_underlying(Fields::kEndpoint):
            ReturnErrorOnFailure(DataModel::Decode(reader, endpoint));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AnnounceOtaProvider.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::DefaultOtaProviders::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, defaultOtaProviders));
        break;
    case Attributes::UpdatePossible::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, updatePossible));
        break;
    case Attributes::UpdateState::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, updateState));
        break;
    case Attributes::UpdateStateProgress::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, updateStateProgress));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace StateTransition {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPreviousState)), previousState));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNewState)), newState));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kReason)), reason));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTargetSoftwareVersion)), targetSoftwareVersion));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kPreviousState):
            ReturnErrorOnFailure(DataModel::Decode(reader, previousState));
            break;
        case to_underlying(Fields::kNewState):
            ReturnErrorOnFailure(DataModel::Decode(reader, newState));
            break;
        case to_underlying(Fields::kReason):
            ReturnErrorOnFailure(DataModel::Decode(reader, reason));
            break;
        case to_underlying(Fields::kTargetSoftwareVersion):
            ReturnErrorOnFailure(DataModel::Decode(reader, targetSoftwareVersion));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StateTransition.
namespace VersionApplied {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSoftwareVersion)), softwareVersion));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kProductID)), productID));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kSoftwareVersion):
            ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersion));
            break;
        case to_underlying(Fields::kProductID):
            ReturnErrorOnFailure(DataModel::Decode(reader, productID));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace VersionApplied.
namespace DownloadError {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSoftwareVersion)), softwareVersion));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBytesDownloaded)), bytesDownloaded));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kProgressPercent)), progressPercent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPlatformCode)), platformCode));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kSoftwareVersion):
            ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersion));
            break;
        case to_underlying(Fields::kBytesDownloaded):
            ReturnErrorOnFailure(DataModel::Decode(reader, bytesDownloaded));
            break;
        case to_underlying(Fields::kProgressPercent):
            ReturnErrorOnFailure(DataModel::Decode(reader, progressPercent));
            break;
        case to_underlying(Fields::kPlatformCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, platformCode));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace DownloadError.
} // namespace Events

} // namespace OtaSoftwareUpdateRequestor
namespace LocalizationConfiguration {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::ActiveLocale::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeLocale));
        break;
    case Attributes::SupportedLocales::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, supportedLocales));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace LocalizationConfiguration
namespace TimeFormatLocalization {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::HourFormat::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, hourFormat));
        break;
    case Attributes::ActiveCalendarType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeCalendarType));
        break;
    case Attributes::SupportedCalendarTypes::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, supportedCalendarTypes));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace TimeFormatLocalization
namespace UnitLocalization {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::TemperatureUnit::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, temperatureUnit));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace UnitLocalization
namespace PowerSourceConfiguration {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::Sources::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, sources));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace PowerSourceConfiguration
namespace PowerSource {
namespace Structs {
namespace BatChargeFaultChangeType {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCurrent)), current));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPrevious)), previous));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCurrent):
            ReturnErrorOnFailure(DataModel::Decode(reader, current));
            break;
        case to_underlying(Fields::kPrevious):
            ReturnErrorOnFailure(DataModel::Decode(reader, previous));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace BatChargeFaultChangeType
namespace BatFaultChangeType {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCurrent)), current));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPrevious)), previous));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCurrent):
            ReturnErrorOnFailure(DataModel::Decode(reader, current));
            break;
        case to_underlying(Fields::kPrevious):
            ReturnErrorOnFailure(DataModel::Decode(reader, previous));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace BatFaultChangeType
namespace WiredFaultChangeType {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCurrent)), current));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPrevious)), previous));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCurrent):
            ReturnErrorOnFailure(DataModel::Decode(reader, current));
            break;
        case to_underlying(Fields::kPrevious):
            ReturnErrorOnFailure(DataModel::Decode(reader, previous));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace WiredFaultChangeType
} // namespace Structs

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::Status::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, status));
        break;
    case Attributes::Order::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, order));
        break;
    case Attributes::Description::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, description));
        break;
    case Attributes::WiredAssessedInputVoltage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, wiredAssessedInputVoltage));
        break;
    case Attributes::WiredAssessedInputFrequency::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, wiredAssessedInputFrequency));
        break;
    case Attributes::WiredCurrentType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, wiredCurrentType));
        break;
    case Attributes::WiredAssessedCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, wiredAssessedCurrent));
        break;
    case Attributes::WiredNominalVoltage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, wiredNominalVoltage));
        break;
    case Attributes::WiredMaximumCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, wiredMaximumCurrent));
        break;
    case Attributes::WiredPresent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, wiredPresent));
        break;
    case Attributes::ActiveWiredFaults::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeWiredFaults));
        break;
    case Attributes::BatVoltage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batVoltage));
        break;
    case Attributes::BatPercentRemaining::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batPercentRemaining));
        break;
    case Attributes::BatTimeRemaining::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batTimeRemaining));
        break;
    case Attributes::BatChargeLevel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batChargeLevel));
        break;
    case Attributes::BatReplacementNeeded::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batReplacementNeeded));
        break;
    case Attributes::BatReplaceability::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batReplaceability));
        break;
    case Attributes::BatPresent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batPresent));
        break;
    case Attributes::ActiveBatFaults::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeBatFaults));
        break;
    case Attributes::BatReplacementDescription::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batReplacementDescription));
        break;
    case Attributes::BatCommonDesignation::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batCommonDesignation));
        break;
    case Attributes::BatANSIDesignation::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batANSIDesignation));
        break;
    case Attributes::BatIECDesignation::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batIECDesignation));
        break;
    case Attributes::BatApprovedChemistry::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batApprovedChemistry));
        break;
    case Attributes::BatCapacity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batCapacity));
        break;
    case Attributes::BatQuantity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batQuantity));
        break;
    case Attributes::BatChargeState::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batChargeState));
        break;
    case Attributes::BatTimeToFullCharge::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batTimeToFullCharge));
        break;
    case Attributes::BatFunctionalWhileCharging::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batFunctionalWhileCharging));
        break;
    case Attributes::BatChargingCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, batChargingCurrent));
        break;
    case Attributes::ActiveBatChargeFaults::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeBatChargeFaults));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace PowerSource
namespace GeneralCommissioning {
namespace Structs {
namespace BasicCommissioningInfo {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFailSafeExpiryLengthSeconds)),
                                           failSafeExpiryLengthSeconds));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMaxCumulativeFailsafeSeconds)),
                                           maxCumulativeFailsafeSeconds));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kFailSafeExpiryLengthSeconds):
            ReturnErrorOnFailure(DataModel::Decode(reader, failSafeExpiryLengthSeconds));
            break;
        case to_underlying(Fields::kMaxCumulativeFailsafeSeconds):
            ReturnErrorOnFailure(DataModel::Decode(reader, maxCumulativeFailsafeSeconds));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace BasicCommissioningInfo
} // namespace Structs

namespace Commands {
namespace ArmFailSafe {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kExpiryLengthSeconds)), expiryLengthSeconds));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBreadcrumb)), breadcrumb));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kExpiryLengthSeconds):
            ReturnErrorOnFailure(DataModel::Decode(reader, expiryLengthSeconds));
            break;
        case to_underlying(Fields::kBreadcrumb):
            ReturnErrorOnFailure(DataModel::Decode(reader, breadcrumb));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ArmFailSafe.
namespace ArmFailSafeResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kErrorCode)), errorCode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDebugText)), debugText));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kErrorCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, errorCode));
            break;
        case to_underlying(Fields::kDebugText):
            ReturnErrorOnFailure(DataModel::Decode(reader, debugText));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ArmFailSafeResponse.
namespace SetRegulatoryConfig {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNewRegulatoryConfig)), newRegulatoryConfig));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCountryCode)), countryCode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBreadcrumb)), breadcrumb));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNewRegulatoryConfig):
            ReturnErrorOnFailure(DataModel::Decode(reader, newRegulatoryConfig));
            break;
        case to_underlying(Fields::kCountryCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, countryCode));
            break;
        case to_underlying(Fields::kBreadcrumb):
            ReturnErrorOnFailure(DataModel::Decode(reader, breadcrumb));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SetRegulatoryConfig.
namespace SetRegulatoryConfigResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kErrorCode)), errorCode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDebugText)), debugText));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kErrorCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, errorCode));
            break;
        case to_underlying(Fields::kDebugText):
            ReturnErrorOnFailure(DataModel::Decode(reader, debugText));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SetRegulatoryConfigResponse.
namespace CommissioningComplete {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace CommissioningComplete.
namespace CommissioningCompleteResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kErrorCode)), errorCode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDebugText)), debugText));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kErrorCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, errorCode));
            break;
        case to_underlying(Fields::kDebugText):
            ReturnErrorOnFailure(DataModel::Decode(reader, debugText));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace CommissioningCompleteResponse.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::Breadcrumb::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, breadcrumb));
        break;
    case Attributes::BasicCommissioningInfo::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, basicCommissioningInfo));
        break;
    case Attributes::RegulatoryConfig::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, regulatoryConfig));
        break;
    case Attributes::LocationCapability::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, locationCapability));
        break;
    case Attributes::SupportsConcurrentConnection::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, supportsConcurrentConnection));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace GeneralCommissioning
namespace NetworkCommissioning {
namespace Structs {
namespace NetworkInfo {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNetworkID)), networkID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kConnected)), connected));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNetworkID):
            ReturnErrorOnFailure(DataModel::Decode(reader, networkID));
            break;
        case to_underlying(Fields::kConnected):
            ReturnErrorOnFailure(DataModel::Decode(reader, connected));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace NetworkInfo
namespace ThreadInterfaceScanResult {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPanId)), panId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kExtendedPanId)), extendedPanId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNetworkName)), networkName));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kChannel)), channel));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kVersion)), version));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kExtendedAddress)), extendedAddress));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRssi)), rssi));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLqi)), lqi));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kPanId):
            ReturnErrorOnFailure(DataModel::Decode(reader, panId));
            break;
        case to_underlying(Fields::kExtendedPanId):
            ReturnErrorOnFailure(DataModel::Decode(reader, extendedPanId));
            break;
        case to_underlying(Fields::kNetworkName):
            ReturnErrorOnFailure(DataModel::Decode(reader, networkName));
            break;
        case to_underlying(Fields::kChannel):
            ReturnErrorOnFailure(DataModel::Decode(reader, channel));
            break;
        case to_underlying(Fields::kVersion):
            ReturnErrorOnFailure(DataModel::Decode(reader, version));
            break;
        case to_underlying(Fields::kExtendedAddress):
            ReturnErrorOnFailure(DataModel::Decode(reader, extendedAddress));
            break;
        case to_underlying(Fields::kRssi):
            ReturnErrorOnFailure(DataModel::Decode(reader, rssi));
            break;
        case to_underlying(Fields::kLqi):
            ReturnErrorOnFailure(DataModel::Decode(reader, lqi));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ThreadInterfaceScanResult
namespace WiFiInterfaceScanResult {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSecurity)), security));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSsid)), ssid));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBssid)), bssid));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kChannel)), channel));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kWiFiBand)), wiFiBand));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRssi)), rssi));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kSecurity):
            ReturnErrorOnFailure(DataModel::Decode(reader, security));
            break;
        case to_underlying(Fields::kSsid):
            ReturnErrorOnFailure(DataModel::Decode(reader, ssid));
            break;
        case to_underlying(Fields::kBssid):
            ReturnErrorOnFailure(DataModel::Decode(reader, bssid));
            break;
        case to_underlying(Fields::kChannel):
            ReturnErrorOnFailure(DataModel::Decode(reader, channel));
            break;
        case to_underlying(Fields::kWiFiBand):
            ReturnErrorOnFailure(DataModel::Decode(reader, wiFiBand));
            break;
        case to_underlying(Fields::kRssi):
            ReturnErrorOnFailure(DataModel::Decode(reader, rssi));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace WiFiInterfaceScanResult
} // namespace Structs

namespace Commands {
namespace ScanNetworks {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSsid)), ssid));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBreadcrumb)), breadcrumb));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kSsid):
            ReturnErrorOnFailure(DataModel::Decode(reader, ssid));
            break;
        case to_underlying(Fields::kBreadcrumb):
            ReturnErrorOnFailure(DataModel::Decode(reader, breadcrumb));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ScanNetworks.
namespace ScanNetworksResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNetworkingStatus)), networkingStatus));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDebugText)), debugText));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kWiFiScanResults)), wiFiScanResults));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kThreadScanResults)), threadScanResults));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNetworkingStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, networkingStatus));
            break;
        case to_underlying(Fields::kDebugText):
            ReturnErrorOnFailure(DataModel::Decode(reader, debugText));
            break;
        case to_underlying(Fields::kWiFiScanResults):
            ReturnErrorOnFailure(DataModel::Decode(reader, wiFiScanResults));
            break;
        case to_underlying(Fields::kThreadScanResults):
            ReturnErrorOnFailure(DataModel::Decode(reader, threadScanResults));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ScanNetworksResponse.
namespace AddOrUpdateWiFiNetwork {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSsid)), ssid));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredentials)), credentials));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBreadcrumb)), breadcrumb));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kSsid):
            ReturnErrorOnFailure(DataModel::Decode(reader, ssid));
            break;
        case to_underlying(Fields::kCredentials):
            ReturnErrorOnFailure(DataModel::Decode(reader, credentials));
            break;
        case to_underlying(Fields::kBreadcrumb):
            ReturnErrorOnFailure(DataModel::Decode(reader, breadcrumb));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AddOrUpdateWiFiNetwork.
namespace AddOrUpdateThreadNetwork {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOperationalDataset)), operationalDataset));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBreadcrumb)), breadcrumb));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kOperationalDataset):
            ReturnErrorOnFailure(DataModel::Decode(reader, operationalDataset));
            break;
        case to_underlying(Fields::kBreadcrumb):
            ReturnErrorOnFailure(DataModel::Decode(reader, breadcrumb));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AddOrUpdateThreadNetwork.
namespace RemoveNetwork {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNetworkID)), networkID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBreadcrumb)), breadcrumb));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNetworkID):
            ReturnErrorOnFailure(DataModel::Decode(reader, networkID));
            break;
        case to_underlying(Fields::kBreadcrumb):
            ReturnErrorOnFailure(DataModel::Decode(reader, breadcrumb));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RemoveNetwork.
namespace NetworkConfigResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNetworkingStatus)), networkingStatus));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDebugText)), debugText));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNetworkIndex)), networkIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNetworkingStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, networkingStatus));
            break;
        case to_underlying(Fields::kDebugText):
            ReturnErrorOnFailure(DataModel::Decode(reader, debugText));
            break;
        case to_underlying(Fields::kNetworkIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, networkIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace NetworkConfigResponse.
namespace ConnectNetwork {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNetworkID)), networkID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBreadcrumb)), breadcrumb));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNetworkID):
            ReturnErrorOnFailure(DataModel::Decode(reader, networkID));
            break;
        case to_underlying(Fields::kBreadcrumb):
            ReturnErrorOnFailure(DataModel::Decode(reader, breadcrumb));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ConnectNetwork.
namespace ConnectNetworkResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNetworkingStatus)), networkingStatus));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDebugText)), debugText));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kErrorValue)), errorValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNetworkingStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, networkingStatus));
            break;
        case to_underlying(Fields::kDebugText):
            ReturnErrorOnFailure(DataModel::Decode(reader, debugText));
            break;
        case to_underlying(Fields::kErrorValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, errorValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ConnectNetworkResponse.
namespace ReorderNetwork {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNetworkID)), networkID));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNetworkIndex)), networkIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBreadcrumb)), breadcrumb));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNetworkID):
            ReturnErrorOnFailure(DataModel::Decode(reader, networkID));
            break;
        case to_underlying(Fields::kNetworkIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, networkIndex));
            break;
        case to_underlying(Fields::kBreadcrumb):
            ReturnErrorOnFailure(DataModel::Decode(reader, breadcrumb));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ReorderNetwork.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::MaxNetworks::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxNetworks));
        break;
    case Attributes::Networks::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, networks));
        break;
    case Attributes::ScanMaxTimeSeconds::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, scanMaxTimeSeconds));
        break;
    case Attributes::ConnectMaxTimeSeconds::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, connectMaxTimeSeconds));
        break;
    case Attributes::InterfaceEnabled::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, interfaceEnabled));
        break;
    case Attributes::LastNetworkingStatus::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lastNetworkingStatus));
        break;
    case Attributes::LastNetworkID::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lastNetworkID));
        break;
    case Attributes::LastConnectErrorValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lastConnectErrorValue));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace NetworkCommissioning
namespace DiagnosticLogs {

namespace Commands {
namespace RetrieveLogsRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIntent)), intent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRequestedProtocol)), requestedProtocol));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransferFileDesignator)), transferFileDesignator));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kIntent):
            ReturnErrorOnFailure(DataModel::Decode(reader, intent));
            break;
        case to_underlying(Fields::kRequestedProtocol):
            ReturnErrorOnFailure(DataModel::Decode(reader, requestedProtocol));
            break;
        case to_underlying(Fields::kTransferFileDesignator):
            ReturnErrorOnFailure(DataModel::Decode(reader, transferFileDesignator));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RetrieveLogsRequest.
namespace RetrieveLogsResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kContent)), content));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTimeStamp)), timeStamp));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTimeSinceBoot)), timeSinceBoot));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kContent):
            ReturnErrorOnFailure(DataModel::Decode(reader, content));
            break;
        case to_underlying(Fields::kTimeStamp):
            ReturnErrorOnFailure(DataModel::Decode(reader, timeStamp));
            break;
        case to_underlying(Fields::kTimeSinceBoot):
            ReturnErrorOnFailure(DataModel::Decode(reader, timeSinceBoot));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RetrieveLogsResponse.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace DiagnosticLogs
namespace GeneralDiagnostics {
namespace Structs {
namespace NetworkInterfaceType {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIsOperational)), isOperational));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOffPremiseServicesReachableIPv4)),
                                           offPremiseServicesReachableIPv4));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOffPremiseServicesReachableIPv6)),
                                           offPremiseServicesReachableIPv6));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kHardwareAddress)), hardwareAddress));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIPv4Addresses)), IPv4Addresses));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIPv6Addresses)), IPv6Addresses));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kType)), type));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        case to_underlying(Fields::kIsOperational):
            ReturnErrorOnFailure(DataModel::Decode(reader, isOperational));
            break;
        case to_underlying(Fields::kOffPremiseServicesReachableIPv4):
            ReturnErrorOnFailure(DataModel::Decode(reader, offPremiseServicesReachableIPv4));
            break;
        case to_underlying(Fields::kOffPremiseServicesReachableIPv6):
            ReturnErrorOnFailure(DataModel::Decode(reader, offPremiseServicesReachableIPv6));
            break;
        case to_underlying(Fields::kHardwareAddress):
            ReturnErrorOnFailure(DataModel::Decode(reader, hardwareAddress));
            break;
        case to_underlying(Fields::kIPv4Addresses):
            ReturnErrorOnFailure(DataModel::Decode(reader, IPv4Addresses));
            break;
        case to_underlying(Fields::kIPv6Addresses):
            ReturnErrorOnFailure(DataModel::Decode(reader, IPv6Addresses));
            break;
        case to_underlying(Fields::kType):
            ReturnErrorOnFailure(DataModel::Decode(reader, type));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace NetworkInterfaceType
} // namespace Structs

namespace Commands {
namespace TestEventTrigger {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEnableKey)), enableKey));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEventTrigger)), eventTrigger));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kEnableKey):
            ReturnErrorOnFailure(DataModel::Decode(reader, enableKey));
            break;
        case to_underlying(Fields::kEventTrigger):
            ReturnErrorOnFailure(DataModel::Decode(reader, eventTrigger));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestEventTrigger.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::NetworkInterfaces::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, networkInterfaces));
        break;
    case Attributes::RebootCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rebootCount));
        break;
    case Attributes::UpTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, upTime));
        break;
    case Attributes::TotalOperationalHours::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, totalOperationalHours));
        break;
    case Attributes::BootReasons::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, bootReasons));
        break;
    case Attributes::ActiveHardwareFaults::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeHardwareFaults));
        break;
    case Attributes::ActiveRadioFaults::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeRadioFaults));
        break;
    case Attributes::ActiveNetworkFaults::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeNetworkFaults));
        break;
    case Attributes::TestEventTriggersEnabled::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, testEventTriggersEnabled));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace HardwareFaultChange {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCurrent)), current));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPrevious)), previous));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCurrent):
            ReturnErrorOnFailure(DataModel::Decode(reader, current));
            break;
        case to_underlying(Fields::kPrevious):
            ReturnErrorOnFailure(DataModel::Decode(reader, previous));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace HardwareFaultChange.
namespace RadioFaultChange {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCurrent)), current));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPrevious)), previous));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCurrent):
            ReturnErrorOnFailure(DataModel::Decode(reader, current));
            break;
        case to_underlying(Fields::kPrevious):
            ReturnErrorOnFailure(DataModel::Decode(reader, previous));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RadioFaultChange.
namespace NetworkFaultChange {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCurrent)), current));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPrevious)), previous));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCurrent):
            ReturnErrorOnFailure(DataModel::Decode(reader, current));
            break;
        case to_underlying(Fields::kPrevious):
            ReturnErrorOnFailure(DataModel::Decode(reader, previous));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace NetworkFaultChange.
namespace BootReason {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBootReason)), bootReason));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kBootReason):
            ReturnErrorOnFailure(DataModel::Decode(reader, bootReason));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace BootReason.
} // namespace Events

} // namespace GeneralDiagnostics
namespace SoftwareDiagnostics {
namespace Structs {
namespace ThreadMetrics {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kId)), id));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStackFreeCurrent)), stackFreeCurrent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStackFreeMinimum)), stackFreeMinimum));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStackSize)), stackSize));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kId):
            ReturnErrorOnFailure(DataModel::Decode(reader, id));
            break;
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        case to_underlying(Fields::kStackFreeCurrent):
            ReturnErrorOnFailure(DataModel::Decode(reader, stackFreeCurrent));
            break;
        case to_underlying(Fields::kStackFreeMinimum):
            ReturnErrorOnFailure(DataModel::Decode(reader, stackFreeMinimum));
            break;
        case to_underlying(Fields::kStackSize):
            ReturnErrorOnFailure(DataModel::Decode(reader, stackSize));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ThreadMetrics
} // namespace Structs

namespace Commands {
namespace ResetWatermarks {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ResetWatermarks.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::ThreadMetrics::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, threadMetrics));
        break;
    case Attributes::CurrentHeapFree::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentHeapFree));
        break;
    case Attributes::CurrentHeapUsed::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentHeapUsed));
        break;
    case Attributes::CurrentHeapHighWatermark::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentHeapHighWatermark));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace SoftwareFault {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kId)), id));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFaultRecording)), faultRecording));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kId):
            ReturnErrorOnFailure(DataModel::Decode(reader, id));
            break;
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        case to_underlying(Fields::kFaultRecording):
            ReturnErrorOnFailure(DataModel::Decode(reader, faultRecording));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SoftwareFault.
} // namespace Events

} // namespace SoftwareDiagnostics
namespace ThreadNetworkDiagnostics {
namespace Structs {
namespace NeighborTable {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kExtAddress)), extAddress));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAge)), age));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRloc16)), rloc16));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLinkFrameCounter)), linkFrameCounter));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMleFrameCounter)), mleFrameCounter));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLqi)), lqi));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAverageRssi)), averageRssi));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLastRssi)), lastRssi));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFrameErrorRate)), frameErrorRate));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMessageErrorRate)), messageErrorRate));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRxOnWhenIdle)), rxOnWhenIdle));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFullThreadDevice)), fullThreadDevice));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFullNetworkData)), fullNetworkData));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIsChild)), isChild));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kExtAddress):
            ReturnErrorOnFailure(DataModel::Decode(reader, extAddress));
            break;
        case to_underlying(Fields::kAge):
            ReturnErrorOnFailure(DataModel::Decode(reader, age));
            break;
        case to_underlying(Fields::kRloc16):
            ReturnErrorOnFailure(DataModel::Decode(reader, rloc16));
            break;
        case to_underlying(Fields::kLinkFrameCounter):
            ReturnErrorOnFailure(DataModel::Decode(reader, linkFrameCounter));
            break;
        case to_underlying(Fields::kMleFrameCounter):
            ReturnErrorOnFailure(DataModel::Decode(reader, mleFrameCounter));
            break;
        case to_underlying(Fields::kLqi):
            ReturnErrorOnFailure(DataModel::Decode(reader, lqi));
            break;
        case to_underlying(Fields::kAverageRssi):
            ReturnErrorOnFailure(DataModel::Decode(reader, averageRssi));
            break;
        case to_underlying(Fields::kLastRssi):
            ReturnErrorOnFailure(DataModel::Decode(reader, lastRssi));
            break;
        case to_underlying(Fields::kFrameErrorRate):
            ReturnErrorOnFailure(DataModel::Decode(reader, frameErrorRate));
            break;
        case to_underlying(Fields::kMessageErrorRate):
            ReturnErrorOnFailure(DataModel::Decode(reader, messageErrorRate));
            break;
        case to_underlying(Fields::kRxOnWhenIdle):
            ReturnErrorOnFailure(DataModel::Decode(reader, rxOnWhenIdle));
            break;
        case to_underlying(Fields::kFullThreadDevice):
            ReturnErrorOnFailure(DataModel::Decode(reader, fullThreadDevice));
            break;
        case to_underlying(Fields::kFullNetworkData):
            ReturnErrorOnFailure(DataModel::Decode(reader, fullNetworkData));
            break;
        case to_underlying(Fields::kIsChild):
            ReturnErrorOnFailure(DataModel::Decode(reader, isChild));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace NeighborTable
namespace OperationalDatasetComponents {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kActiveTimestampPresent)), activeTimestampPresent));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPendingTimestampPresent)), pendingTimestampPresent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMasterKeyPresent)), masterKeyPresent));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNetworkNamePresent)), networkNamePresent));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kExtendedPanIdPresent)), extendedPanIdPresent));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMeshLocalPrefixPresent)), meshLocalPrefixPresent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDelayPresent)), delayPresent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPanIdPresent)), panIdPresent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kChannelPresent)), channelPresent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPskcPresent)), pskcPresent));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSecurityPolicyPresent)), securityPolicyPresent));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kChannelMaskPresent)), channelMaskPresent));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kActiveTimestampPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, activeTimestampPresent));
            break;
        case to_underlying(Fields::kPendingTimestampPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, pendingTimestampPresent));
            break;
        case to_underlying(Fields::kMasterKeyPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, masterKeyPresent));
            break;
        case to_underlying(Fields::kNetworkNamePresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, networkNamePresent));
            break;
        case to_underlying(Fields::kExtendedPanIdPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, extendedPanIdPresent));
            break;
        case to_underlying(Fields::kMeshLocalPrefixPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, meshLocalPrefixPresent));
            break;
        case to_underlying(Fields::kDelayPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, delayPresent));
            break;
        case to_underlying(Fields::kPanIdPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, panIdPresent));
            break;
        case to_underlying(Fields::kChannelPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, channelPresent));
            break;
        case to_underlying(Fields::kPskcPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, pskcPresent));
            break;
        case to_underlying(Fields::kSecurityPolicyPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, securityPolicyPresent));
            break;
        case to_underlying(Fields::kChannelMaskPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, channelMaskPresent));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace OperationalDatasetComponents
namespace RouteTable {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kExtAddress)), extAddress));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRloc16)), rloc16));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRouterId)), routerId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNextHop)), nextHop));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPathCost)), pathCost));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLQIIn)), LQIIn));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLQIOut)), LQIOut));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAge)), age));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAllocated)), allocated));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLinkEstablished)), linkEstablished));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kExtAddress):
            ReturnErrorOnFailure(DataModel::Decode(reader, extAddress));
            break;
        case to_underlying(Fields::kRloc16):
            ReturnErrorOnFailure(DataModel::Decode(reader, rloc16));
            break;
        case to_underlying(Fields::kRouterId):
            ReturnErrorOnFailure(DataModel::Decode(reader, routerId));
            break;
        case to_underlying(Fields::kNextHop):
            ReturnErrorOnFailure(DataModel::Decode(reader, nextHop));
            break;
        case to_underlying(Fields::kPathCost):
            ReturnErrorOnFailure(DataModel::Decode(reader, pathCost));
            break;
        case to_underlying(Fields::kLQIIn):
            ReturnErrorOnFailure(DataModel::Decode(reader, LQIIn));
            break;
        case to_underlying(Fields::kLQIOut):
            ReturnErrorOnFailure(DataModel::Decode(reader, LQIOut));
            break;
        case to_underlying(Fields::kAge):
            ReturnErrorOnFailure(DataModel::Decode(reader, age));
            break;
        case to_underlying(Fields::kAllocated):
            ReturnErrorOnFailure(DataModel::Decode(reader, allocated));
            break;
        case to_underlying(Fields::kLinkEstablished):
            ReturnErrorOnFailure(DataModel::Decode(reader, linkEstablished));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace RouteTable
namespace SecurityPolicy {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRotationTime)), rotationTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFlags)), flags));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kRotationTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, rotationTime));
            break;
        case to_underlying(Fields::kFlags):
            ReturnErrorOnFailure(DataModel::Decode(reader, flags));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace SecurityPolicy
} // namespace Structs

namespace Commands {
namespace ResetCounts {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ResetCounts.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::Channel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, channel));
        break;
    case Attributes::RoutingRole::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, routingRole));
        break;
    case Attributes::NetworkName::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, networkName));
        break;
    case Attributes::PanId::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, panId));
        break;
    case Attributes::ExtendedPanId::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, extendedPanId));
        break;
    case Attributes::MeshLocalPrefix::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, meshLocalPrefix));
        break;
    case Attributes::OverrunCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, overrunCount));
        break;
    case Attributes::NeighborTableList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, neighborTableList));
        break;
    case Attributes::RouteTableList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, routeTableList));
        break;
    case Attributes::PartitionId::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, partitionId));
        break;
    case Attributes::Weighting::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, weighting));
        break;
    case Attributes::DataVersion::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dataVersion));
        break;
    case Attributes::StableDataVersion::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, stableDataVersion));
        break;
    case Attributes::LeaderRouterId::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, leaderRouterId));
        break;
    case Attributes::DetachedRoleCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, detachedRoleCount));
        break;
    case Attributes::ChildRoleCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, childRoleCount));
        break;
    case Attributes::RouterRoleCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, routerRoleCount));
        break;
    case Attributes::LeaderRoleCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, leaderRoleCount));
        break;
    case Attributes::AttachAttemptCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attachAttemptCount));
        break;
    case Attributes::PartitionIdChangeCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, partitionIdChangeCount));
        break;
    case Attributes::BetterPartitionAttachAttemptCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, betterPartitionAttachAttemptCount));
        break;
    case Attributes::ParentChangeCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, parentChangeCount));
        break;
    case Attributes::TxTotalCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txTotalCount));
        break;
    case Attributes::TxUnicastCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txUnicastCount));
        break;
    case Attributes::TxBroadcastCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txBroadcastCount));
        break;
    case Attributes::TxAckRequestedCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txAckRequestedCount));
        break;
    case Attributes::TxAckedCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txAckedCount));
        break;
    case Attributes::TxNoAckRequestedCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txNoAckRequestedCount));
        break;
    case Attributes::TxDataCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txDataCount));
        break;
    case Attributes::TxDataPollCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txDataPollCount));
        break;
    case Attributes::TxBeaconCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txBeaconCount));
        break;
    case Attributes::TxBeaconRequestCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txBeaconRequestCount));
        break;
    case Attributes::TxOtherCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txOtherCount));
        break;
    case Attributes::TxRetryCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txRetryCount));
        break;
    case Attributes::TxDirectMaxRetryExpiryCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txDirectMaxRetryExpiryCount));
        break;
    case Attributes::TxIndirectMaxRetryExpiryCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txIndirectMaxRetryExpiryCount));
        break;
    case Attributes::TxErrCcaCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txErrCcaCount));
        break;
    case Attributes::TxErrAbortCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txErrAbortCount));
        break;
    case Attributes::TxErrBusyChannelCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txErrBusyChannelCount));
        break;
    case Attributes::RxTotalCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxTotalCount));
        break;
    case Attributes::RxUnicastCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxUnicastCount));
        break;
    case Attributes::RxBroadcastCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxBroadcastCount));
        break;
    case Attributes::RxDataCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxDataCount));
        break;
    case Attributes::RxDataPollCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxDataPollCount));
        break;
    case Attributes::RxBeaconCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxBeaconCount));
        break;
    case Attributes::RxBeaconRequestCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxBeaconRequestCount));
        break;
    case Attributes::RxOtherCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxOtherCount));
        break;
    case Attributes::RxAddressFilteredCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxAddressFilteredCount));
        break;
    case Attributes::RxDestAddrFilteredCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxDestAddrFilteredCount));
        break;
    case Attributes::RxDuplicatedCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxDuplicatedCount));
        break;
    case Attributes::RxErrNoFrameCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxErrNoFrameCount));
        break;
    case Attributes::RxErrUnknownNeighborCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxErrUnknownNeighborCount));
        break;
    case Attributes::RxErrInvalidSrcAddrCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxErrInvalidSrcAddrCount));
        break;
    case Attributes::RxErrSecCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxErrSecCount));
        break;
    case Attributes::RxErrFcsCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxErrFcsCount));
        break;
    case Attributes::RxErrOtherCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rxErrOtherCount));
        break;
    case Attributes::ActiveTimestamp::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeTimestamp));
        break;
    case Attributes::PendingTimestamp::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, pendingTimestamp));
        break;
    case Attributes::Delay::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, delay));
        break;
    case Attributes::SecurityPolicy::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, securityPolicy));
        break;
    case Attributes::ChannelPage0Mask::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, channelPage0Mask));
        break;
    case Attributes::OperationalDatasetComponents::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, operationalDatasetComponents));
        break;
    case Attributes::ActiveNetworkFaultsList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeNetworkFaultsList));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace ConnectionStatus {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kConnectionStatus)), connectionStatus));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kConnectionStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, connectionStatus));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ConnectionStatus.
namespace NetworkFaultChange {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCurrent)), current));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPrevious)), previous));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCurrent):
            ReturnErrorOnFailure(DataModel::Decode(reader, current));
            break;
        case to_underlying(Fields::kPrevious):
            ReturnErrorOnFailure(DataModel::Decode(reader, previous));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace NetworkFaultChange.
} // namespace Events

} // namespace ThreadNetworkDiagnostics
namespace WiFiNetworkDiagnostics {

namespace Commands {
namespace ResetCounts {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ResetCounts.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::Bssid::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, bssid));
        break;
    case Attributes::SecurityType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, securityType));
        break;
    case Attributes::WiFiVersion::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, wiFiVersion));
        break;
    case Attributes::ChannelNumber::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, channelNumber));
        break;
    case Attributes::Rssi::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rssi));
        break;
    case Attributes::BeaconLostCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, beaconLostCount));
        break;
    case Attributes::BeaconRxCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, beaconRxCount));
        break;
    case Attributes::PacketMulticastRxCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, packetMulticastRxCount));
        break;
    case Attributes::PacketMulticastTxCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, packetMulticastTxCount));
        break;
    case Attributes::PacketUnicastRxCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, packetUnicastRxCount));
        break;
    case Attributes::PacketUnicastTxCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, packetUnicastTxCount));
        break;
    case Attributes::CurrentMaxRate::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentMaxRate));
        break;
    case Attributes::OverrunCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, overrunCount));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace Disconnection {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kReasonCode)), reasonCode));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kReasonCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, reasonCode));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Disconnection.
namespace AssociationFailure {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAssociationFailure)), associationFailure));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kAssociationFailure):
            ReturnErrorOnFailure(DataModel::Decode(reader, associationFailure));
            break;
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AssociationFailure.
namespace ConnectionStatus {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kConnectionStatus)), connectionStatus));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kConnectionStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, connectionStatus));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ConnectionStatus.
} // namespace Events

} // namespace WiFiNetworkDiagnostics
namespace EthernetNetworkDiagnostics {

namespace Commands {
namespace ResetCounts {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ResetCounts.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::PHYRate::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, PHYRate));
        break;
    case Attributes::FullDuplex::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, fullDuplex));
        break;
    case Attributes::PacketRxCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, packetRxCount));
        break;
    case Attributes::PacketTxCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, packetTxCount));
        break;
    case Attributes::TxErrCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, txErrCount));
        break;
    case Attributes::CollisionCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, collisionCount));
        break;
    case Attributes::OverrunCount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, overrunCount));
        break;
    case Attributes::CarrierDetect::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, carrierDetect));
        break;
    case Attributes::TimeSinceReset::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, timeSinceReset));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace EthernetNetworkDiagnostics
namespace TimeSynchronization {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace TimeSynchronization
namespace BridgedDeviceBasic {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::VendorName::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, vendorName));
        break;
    case Attributes::VendorID::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, vendorID));
        break;
    case Attributes::ProductName::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, productName));
        break;
    case Attributes::NodeLabel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nodeLabel));
        break;
    case Attributes::HardwareVersion::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, hardwareVersion));
        break;
    case Attributes::HardwareVersionString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, hardwareVersionString));
        break;
    case Attributes::SoftwareVersion::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersion));
        break;
    case Attributes::SoftwareVersionString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersionString));
        break;
    case Attributes::ManufacturingDate::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, manufacturingDate));
        break;
    case Attributes::PartNumber::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, partNumber));
        break;
    case Attributes::ProductURL::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, productURL));
        break;
    case Attributes::ProductLabel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, productLabel));
        break;
    case Attributes::SerialNumber::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, serialNumber));
        break;
    case Attributes::Reachable::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, reachable));
        break;
    case Attributes::UniqueID::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, uniqueID));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace StartUp {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSoftwareVersion)), softwareVersion));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kSoftwareVersion):
            ReturnErrorOnFailure(DataModel::Decode(reader, softwareVersion));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StartUp.
namespace ShutDown {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ShutDown.
namespace Leave {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Leave.
namespace ReachableChanged {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kReachableNewValue)), reachableNewValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kReachableNewValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, reachableNewValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ReachableChanged.
} // namespace Events

} // namespace BridgedDeviceBasic
namespace Switch {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::NumberOfPositions::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfPositions));
        break;
    case Attributes::CurrentPosition::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentPosition));
        break;
    case Attributes::MultiPressMax::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, multiPressMax));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace SwitchLatched {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNewPosition)), newPosition));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNewPosition):
            ReturnErrorOnFailure(DataModel::Decode(reader, newPosition));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SwitchLatched.
namespace InitialPress {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNewPosition)), newPosition));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNewPosition):
            ReturnErrorOnFailure(DataModel::Decode(reader, newPosition));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace InitialPress.
namespace LongPress {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNewPosition)), newPosition));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNewPosition):
            ReturnErrorOnFailure(DataModel::Decode(reader, newPosition));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace LongPress.
namespace ShortRelease {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPreviousPosition)), previousPosition));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kPreviousPosition):
            ReturnErrorOnFailure(DataModel::Decode(reader, previousPosition));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ShortRelease.
namespace LongRelease {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPreviousPosition)), previousPosition));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kPreviousPosition):
            ReturnErrorOnFailure(DataModel::Decode(reader, previousPosition));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace LongRelease.
namespace MultiPressOngoing {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNewPosition)), newPosition));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCurrentNumberOfPressesCounted)),
                                           currentNumberOfPressesCounted));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNewPosition):
            ReturnErrorOnFailure(DataModel::Decode(reader, newPosition));
            break;
        case to_underlying(Fields::kCurrentNumberOfPressesCounted):
            ReturnErrorOnFailure(DataModel::Decode(reader, currentNumberOfPressesCounted));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MultiPressOngoing.
namespace MultiPressComplete {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNewPosition)), newPosition));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTotalNumberOfPressesCounted)),
                                           totalNumberOfPressesCounted));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNewPosition):
            ReturnErrorOnFailure(DataModel::Decode(reader, newPosition));
            break;
        case to_underlying(Fields::kTotalNumberOfPressesCounted):
            ReturnErrorOnFailure(DataModel::Decode(reader, totalNumberOfPressesCounted));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MultiPressComplete.
} // namespace Events

} // namespace Switch
namespace AdministratorCommissioning {

namespace Commands {
namespace OpenCommissioningWindow {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCommissioningTimeout)), commissioningTimeout));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPAKEVerifier)), PAKEVerifier));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDiscriminator)), discriminator));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIterations)), iterations));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSalt)), salt));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCommissioningTimeout):
            ReturnErrorOnFailure(DataModel::Decode(reader, commissioningTimeout));
            break;
        case to_underlying(Fields::kPAKEVerifier):
            ReturnErrorOnFailure(DataModel::Decode(reader, PAKEVerifier));
            break;
        case to_underlying(Fields::kDiscriminator):
            ReturnErrorOnFailure(DataModel::Decode(reader, discriminator));
            break;
        case to_underlying(Fields::kIterations):
            ReturnErrorOnFailure(DataModel::Decode(reader, iterations));
            break;
        case to_underlying(Fields::kSalt):
            ReturnErrorOnFailure(DataModel::Decode(reader, salt));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace OpenCommissioningWindow.
namespace OpenBasicCommissioningWindow {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCommissioningTimeout)), commissioningTimeout));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCommissioningTimeout):
            ReturnErrorOnFailure(DataModel::Decode(reader, commissioningTimeout));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace OpenBasicCommissioningWindow.
namespace RevokeCommissioning {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RevokeCommissioning.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::WindowStatus::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, windowStatus));
        break;
    case Attributes::AdminFabricIndex::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, adminFabricIndex));
        break;
    case Attributes::AdminVendorId::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, adminVendorId));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace AdministratorCommissioning
namespace OperationalCredentials {
namespace Structs {
namespace FabricDescriptor {
CHIP_ERROR Type::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    return DoEncode(writer, tag, NullOptional);
}

CHIP_ERROR Type::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex accessingFabricIndex) const
{
    return DoEncode(writer, tag, MakeOptional(accessingFabricIndex));
}

CHIP_ERROR Type::DoEncode(TLV::TLVWriter & writer, TLV::Tag tag, const Optional<FabricIndex> & accessingFabricIndex) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRootPublicKey)), rootPublicKey));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kVendorId)), vendorId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricId)), fabricId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNodeId)), nodeId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLabel)), label));
    if (accessingFabricIndex.HasValue())
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    }
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kRootPublicKey):
            ReturnErrorOnFailure(DataModel::Decode(reader, rootPublicKey));
            break;
        case to_underlying(Fields::kVendorId):
            ReturnErrorOnFailure(DataModel::Decode(reader, vendorId));
            break;
        case to_underlying(Fields::kFabricId):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricId));
            break;
        case to_underlying(Fields::kNodeId):
            ReturnErrorOnFailure(DataModel::Decode(reader, nodeId));
            break;
        case to_underlying(Fields::kLabel):
            ReturnErrorOnFailure(DataModel::Decode(reader, label));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace FabricDescriptor
namespace NOCStruct {
CHIP_ERROR Type::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    return DoEncode(writer, tag, NullOptional);
}

CHIP_ERROR Type::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex accessingFabricIndex) const
{
    return DoEncode(writer, tag, MakeOptional(accessingFabricIndex));
}

CHIP_ERROR Type::DoEncode(TLV::TLVWriter & writer, TLV::Tag tag, const Optional<FabricIndex> & accessingFabricIndex) const
{
    bool includeSensitive = !accessingFabricIndex.HasValue() || (accessingFabricIndex.Value() == fabricIndex);
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    if (includeSensitive)
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNoc)), noc));
    }
    if (includeSensitive)
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIcac)), icac));
    }
    if (accessingFabricIndex.HasValue())
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    }
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNoc):
            ReturnErrorOnFailure(DataModel::Decode(reader, noc));
            break;
        case to_underlying(Fields::kIcac):
            ReturnErrorOnFailure(DataModel::Decode(reader, icac));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace NOCStruct
} // namespace Structs

namespace Commands {
namespace AttestationRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAttestationNonce)), attestationNonce));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kAttestationNonce):
            ReturnErrorOnFailure(DataModel::Decode(reader, attestationNonce));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AttestationRequest.
namespace AttestationResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAttestationElements)), attestationElements));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSignature)), signature));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kAttestationElements):
            ReturnErrorOnFailure(DataModel::Decode(reader, attestationElements));
            break;
        case to_underlying(Fields::kSignature):
            ReturnErrorOnFailure(DataModel::Decode(reader, signature));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AttestationResponse.
namespace CertificateChainRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCertificateType)), certificateType));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCertificateType):
            ReturnErrorOnFailure(DataModel::Decode(reader, certificateType));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace CertificateChainRequest.
namespace CertificateChainResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCertificate)), certificate));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCertificate):
            ReturnErrorOnFailure(DataModel::Decode(reader, certificate));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace CertificateChainResponse.
namespace CSRRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCSRNonce)), CSRNonce));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIsForUpdateNOC)), isForUpdateNOC));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCSRNonce):
            ReturnErrorOnFailure(DataModel::Decode(reader, CSRNonce));
            break;
        case to_underlying(Fields::kIsForUpdateNOC):
            ReturnErrorOnFailure(DataModel::Decode(reader, isForUpdateNOC));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace CSRRequest.
namespace CSRResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNOCSRElements)), NOCSRElements));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAttestationSignature)), attestationSignature));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNOCSRElements):
            ReturnErrorOnFailure(DataModel::Decode(reader, NOCSRElements));
            break;
        case to_underlying(Fields::kAttestationSignature):
            ReturnErrorOnFailure(DataModel::Decode(reader, attestationSignature));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace CSRResponse.
namespace AddNOC {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNOCValue)), NOCValue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kICACValue)), ICACValue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIPKValue)), IPKValue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCaseAdminSubject)), caseAdminSubject));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAdminVendorId)), adminVendorId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNOCValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, NOCValue));
            break;
        case to_underlying(Fields::kICACValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, ICACValue));
            break;
        case to_underlying(Fields::kIPKValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, IPKValue));
            break;
        case to_underlying(Fields::kCaseAdminSubject):
            ReturnErrorOnFailure(DataModel::Decode(reader, caseAdminSubject));
            break;
        case to_underlying(Fields::kAdminVendorId):
            ReturnErrorOnFailure(DataModel::Decode(reader, adminVendorId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AddNOC.
namespace UpdateNOC {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNOCValue)), NOCValue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kICACValue)), ICACValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNOCValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, NOCValue));
            break;
        case to_underlying(Fields::kICACValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, ICACValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace UpdateNOC.
namespace NOCResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatusCode)), statusCode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDebugText)), debugText));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatusCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, statusCode));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        case to_underlying(Fields::kDebugText):
            ReturnErrorOnFailure(DataModel::Decode(reader, debugText));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace NOCResponse.
namespace UpdateFabricLabel {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLabel)), label));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kLabel):
            ReturnErrorOnFailure(DataModel::Decode(reader, label));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace UpdateFabricLabel.
namespace RemoveFabric {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RemoveFabric.
namespace AddTrustedRootCertificate {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRootCertificate)), rootCertificate));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kRootCertificate):
            ReturnErrorOnFailure(DataModel::Decode(reader, rootCertificate));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AddTrustedRootCertificate.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::NOCs::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, NOCs));
        break;
    case Attributes::Fabrics::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, fabrics));
        break;
    case Attributes::SupportedFabrics::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, supportedFabrics));
        break;
    case Attributes::CommissionedFabrics::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, commissionedFabrics));
        break;
    case Attributes::TrustedRootCertificates::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, trustedRootCertificates));
        break;
    case Attributes::CurrentFabricIndex::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentFabricIndex));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace OperationalCredentials
namespace GroupKeyManagement {
namespace Structs {
namespace GroupInfoMapStruct {
CHIP_ERROR Type::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    return DoEncode(writer, tag, NullOptional);
}

CHIP_ERROR Type::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex accessingFabricIndex) const
{
    return DoEncode(writer, tag, MakeOptional(accessingFabricIndex));
}

CHIP_ERROR Type::DoEncode(TLV::TLVWriter & writer, TLV::Tag tag, const Optional<FabricIndex> & accessingFabricIndex) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndpoints)), endpoints));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupName)), groupName));
    if (accessingFabricIndex.HasValue())
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    }
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kEndpoints):
            ReturnErrorOnFailure(DataModel::Decode(reader, endpoints));
            break;
        case to_underlying(Fields::kGroupName):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupName));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace GroupInfoMapStruct
namespace GroupKeyMapStruct {
CHIP_ERROR Type::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    return DoEncode(writer, tag, NullOptional);
}

CHIP_ERROR Type::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex accessingFabricIndex) const
{
    return DoEncode(writer, tag, MakeOptional(accessingFabricIndex));
}

CHIP_ERROR Type::DoEncode(TLV::TLVWriter & writer, TLV::Tag tag, const Optional<FabricIndex> & accessingFabricIndex) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupId)), groupId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupKeySetID)), groupKeySetID));
    if (accessingFabricIndex.HasValue())
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    }
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupId):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupId));
            break;
        case to_underlying(Fields::kGroupKeySetID):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupKeySetID));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace GroupKeyMapStruct
namespace GroupKeySetStruct {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupKeySetID)), groupKeySetID));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupKeySecurityPolicy)), groupKeySecurityPolicy));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEpochKey0)), epochKey0));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEpochStartTime0)), epochStartTime0));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEpochKey1)), epochKey1));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEpochStartTime1)), epochStartTime1));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEpochKey2)), epochKey2));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEpochStartTime2)), epochStartTime2));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupKeySetID):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupKeySetID));
            break;
        case to_underlying(Fields::kGroupKeySecurityPolicy):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupKeySecurityPolicy));
            break;
        case to_underlying(Fields::kEpochKey0):
            ReturnErrorOnFailure(DataModel::Decode(reader, epochKey0));
            break;
        case to_underlying(Fields::kEpochStartTime0):
            ReturnErrorOnFailure(DataModel::Decode(reader, epochStartTime0));
            break;
        case to_underlying(Fields::kEpochKey1):
            ReturnErrorOnFailure(DataModel::Decode(reader, epochKey1));
            break;
        case to_underlying(Fields::kEpochStartTime1):
            ReturnErrorOnFailure(DataModel::Decode(reader, epochStartTime1));
            break;
        case to_underlying(Fields::kEpochKey2):
            ReturnErrorOnFailure(DataModel::Decode(reader, epochKey2));
            break;
        case to_underlying(Fields::kEpochStartTime2):
            ReturnErrorOnFailure(DataModel::Decode(reader, epochStartTime2));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace GroupKeySetStruct
} // namespace Structs

namespace Commands {
namespace KeySetWrite {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupKeySet)), groupKeySet));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupKeySet):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupKeySet));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace KeySetWrite.
namespace KeySetRead {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupKeySetID)), groupKeySetID));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupKeySetID):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupKeySetID));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace KeySetRead.
namespace KeySetReadResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupKeySet)), groupKeySet));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupKeySet):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupKeySet));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace KeySetReadResponse.
namespace KeySetRemove {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupKeySetID)), groupKeySetID));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupKeySetID):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupKeySetID));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace KeySetRemove.
namespace KeySetReadAllIndices {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupKeySetIDs)), groupKeySetIDs));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupKeySetIDs):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupKeySetIDs));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace KeySetReadAllIndices.
namespace KeySetReadAllIndicesResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kGroupKeySetIDs)), groupKeySetIDs));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kGroupKeySetIDs):
            ReturnErrorOnFailure(DataModel::Decode(reader, groupKeySetIDs));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace KeySetReadAllIndicesResponse.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::GroupKeyMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, groupKeyMap));
        break;
    case Attributes::GroupTable::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, groupTable));
        break;
    case Attributes::MaxGroupsPerFabric::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxGroupsPerFabric));
        break;
    case Attributes::MaxGroupKeysPerFabric::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxGroupKeysPerFabric));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace GroupKeyManagement
namespace FixedLabel {
namespace Structs {
} // namespace Structs

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::LabelList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, labelList));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace FixedLabel
namespace UserLabel {
namespace Structs {
} // namespace Structs

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::LabelList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, labelList));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace UserLabel
namespace ProxyConfiguration {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace ProxyConfiguration
namespace ProxyDiscovery {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace ProxyDiscovery
namespace ProxyValid {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace ProxyValid
namespace BooleanState {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::StateValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, stateValue));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace StateChange {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStateValue)), stateValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStateValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, stateValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StateChange.
} // namespace Events

} // namespace BooleanState
namespace ModeSelect {
namespace Structs {
namespace SemanticTag {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMfgCode)), mfgCode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kValue)), value));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMfgCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, mfgCode));
            break;
        case to_underlying(Fields::kValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, value));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace SemanticTag
namespace ModeOptionStruct {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLabel)), label));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMode)), mode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSemanticTags)), semanticTags));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kLabel):
            ReturnErrorOnFailure(DataModel::Decode(reader, label));
            break;
        case to_underlying(Fields::kMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, mode));
            break;
        case to_underlying(Fields::kSemanticTags):
            ReturnErrorOnFailure(DataModel::Decode(reader, semanticTags));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ModeOptionStruct
} // namespace Structs

namespace Commands {
namespace ChangeToMode {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNewMode)), newMode));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNewMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, newMode));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ChangeToMode.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::Description::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, description));
        break;
    case Attributes::StandardNamespace::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, standardNamespace));
        break;
    case Attributes::SupportedModes::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, supportedModes));
        break;
    case Attributes::CurrentMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentMode));
        break;
    case Attributes::StartUpMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, startUpMode));
        break;
    case Attributes::OnMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, onMode));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace ModeSelect
namespace DoorLock {
namespace Structs {
namespace DlCredential {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredentialType)), credentialType));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredentialIndex)), credentialIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCredentialType):
            ReturnErrorOnFailure(DataModel::Decode(reader, credentialType));
            break;
        case to_underlying(Fields::kCredentialIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, credentialIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace DlCredential
} // namespace Structs

namespace Commands {
namespace LockDoor {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPinCode)), pinCode));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kPinCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, pinCode));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace LockDoor.
namespace UnlockDoor {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPinCode)), pinCode));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kPinCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, pinCode));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace UnlockDoor.
namespace UnlockWithTimeout {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTimeout)), timeout));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPinCode)), pinCode));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kTimeout):
            ReturnErrorOnFailure(DataModel::Decode(reader, timeout));
            break;
        case to_underlying(Fields::kPinCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, pinCode));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace UnlockWithTimeout.
namespace SetWeekDaySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kWeekDayIndex)), weekDayIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDaysMask)), daysMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStartHour)), startHour));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStartMinute)), startMinute));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndHour)), endHour));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndMinute)), endMinute));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kWeekDayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, weekDayIndex));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kDaysMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, daysMask));
            break;
        case to_underlying(Fields::kStartHour):
            ReturnErrorOnFailure(DataModel::Decode(reader, startHour));
            break;
        case to_underlying(Fields::kStartMinute):
            ReturnErrorOnFailure(DataModel::Decode(reader, startMinute));
            break;
        case to_underlying(Fields::kEndHour):
            ReturnErrorOnFailure(DataModel::Decode(reader, endHour));
            break;
        case to_underlying(Fields::kEndMinute):
            ReturnErrorOnFailure(DataModel::Decode(reader, endMinute));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SetWeekDaySchedule.
namespace GetWeekDaySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kWeekDayIndex)), weekDayIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kWeekDayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, weekDayIndex));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetWeekDaySchedule.
namespace GetWeekDayScheduleResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kWeekDayIndex)), weekDayIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDaysMask)), daysMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStartHour)), startHour));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStartMinute)), startMinute));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndHour)), endHour));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndMinute)), endMinute));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kWeekDayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, weekDayIndex));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kDaysMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, daysMask));
            break;
        case to_underlying(Fields::kStartHour):
            ReturnErrorOnFailure(DataModel::Decode(reader, startHour));
            break;
        case to_underlying(Fields::kStartMinute):
            ReturnErrorOnFailure(DataModel::Decode(reader, startMinute));
            break;
        case to_underlying(Fields::kEndHour):
            ReturnErrorOnFailure(DataModel::Decode(reader, endHour));
            break;
        case to_underlying(Fields::kEndMinute):
            ReturnErrorOnFailure(DataModel::Decode(reader, endMinute));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetWeekDayScheduleResponse.
namespace ClearWeekDaySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kWeekDayIndex)), weekDayIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kWeekDayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, weekDayIndex));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ClearWeekDaySchedule.
namespace SetYearDaySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kYearDayIndex)), yearDayIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLocalStartTime)), localStartTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLocalEndTime)), localEndTime));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kYearDayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, yearDayIndex));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kLocalStartTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, localStartTime));
            break;
        case to_underlying(Fields::kLocalEndTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, localEndTime));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SetYearDaySchedule.
namespace GetYearDaySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kYearDayIndex)), yearDayIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kYearDayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, yearDayIndex));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetYearDaySchedule.
namespace GetYearDayScheduleResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kYearDayIndex)), yearDayIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLocalStartTime)), localStartTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLocalEndTime)), localEndTime));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kYearDayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, yearDayIndex));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kLocalStartTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, localStartTime));
            break;
        case to_underlying(Fields::kLocalEndTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, localEndTime));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetYearDayScheduleResponse.
namespace ClearYearDaySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kYearDayIndex)), yearDayIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kYearDayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, yearDayIndex));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ClearYearDaySchedule.
namespace SetHolidaySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kHolidayIndex)), holidayIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLocalStartTime)), localStartTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLocalEndTime)), localEndTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOperatingMode)), operatingMode));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kHolidayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, holidayIndex));
            break;
        case to_underlying(Fields::kLocalStartTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, localStartTime));
            break;
        case to_underlying(Fields::kLocalEndTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, localEndTime));
            break;
        case to_underlying(Fields::kOperatingMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, operatingMode));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SetHolidaySchedule.
namespace GetHolidaySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kHolidayIndex)), holidayIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kHolidayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, holidayIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetHolidaySchedule.
namespace GetHolidayScheduleResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kHolidayIndex)), holidayIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLocalStartTime)), localStartTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLocalEndTime)), localEndTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOperatingMode)), operatingMode));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kHolidayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, holidayIndex));
            break;
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kLocalStartTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, localStartTime));
            break;
        case to_underlying(Fields::kLocalEndTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, localEndTime));
            break;
        case to_underlying(Fields::kOperatingMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, operatingMode));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetHolidayScheduleResponse.
namespace ClearHolidaySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kHolidayIndex)), holidayIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kHolidayIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, holidayIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ClearHolidaySchedule.
namespace SetUser {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOperationType)), operationType));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserName)), userName));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserUniqueId)), userUniqueId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserStatus)), userStatus));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserType)), userType));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredentialRule)), credentialRule));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kOperationType):
            ReturnErrorOnFailure(DataModel::Decode(reader, operationType));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kUserName):
            ReturnErrorOnFailure(DataModel::Decode(reader, userName));
            break;
        case to_underlying(Fields::kUserUniqueId):
            ReturnErrorOnFailure(DataModel::Decode(reader, userUniqueId));
            break;
        case to_underlying(Fields::kUserStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, userStatus));
            break;
        case to_underlying(Fields::kUserType):
            ReturnErrorOnFailure(DataModel::Decode(reader, userType));
            break;
        case to_underlying(Fields::kCredentialRule):
            ReturnErrorOnFailure(DataModel::Decode(reader, credentialRule));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SetUser.
namespace GetUser {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetUser.
namespace GetUserResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserName)), userName));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserUniqueId)), userUniqueId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserStatus)), userStatus));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserType)), userType));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredentialRule)), credentialRule));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredentials)), credentials));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCreatorFabricIndex)), creatorFabricIndex));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLastModifiedFabricIndex)), lastModifiedFabricIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNextUserIndex)), nextUserIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kUserName):
            ReturnErrorOnFailure(DataModel::Decode(reader, userName));
            break;
        case to_underlying(Fields::kUserUniqueId):
            ReturnErrorOnFailure(DataModel::Decode(reader, userUniqueId));
            break;
        case to_underlying(Fields::kUserStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, userStatus));
            break;
        case to_underlying(Fields::kUserType):
            ReturnErrorOnFailure(DataModel::Decode(reader, userType));
            break;
        case to_underlying(Fields::kCredentialRule):
            ReturnErrorOnFailure(DataModel::Decode(reader, credentialRule));
            break;
        case to_underlying(Fields::kCredentials):
            ReturnErrorOnFailure(DataModel::Decode(reader, credentials));
            break;
        case to_underlying(Fields::kCreatorFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, creatorFabricIndex));
            break;
        case to_underlying(Fields::kLastModifiedFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, lastModifiedFabricIndex));
            break;
        case to_underlying(Fields::kNextUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, nextUserIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetUserResponse.
namespace ClearUser {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ClearUser.
namespace SetCredential {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOperationType)), operationType));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredential)), credential));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredentialData)), credentialData));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserStatus)), userStatus));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserType)), userType));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kOperationType):
            ReturnErrorOnFailure(DataModel::Decode(reader, operationType));
            break;
        case to_underlying(Fields::kCredential):
            ReturnErrorOnFailure(DataModel::Decode(reader, credential));
            break;
        case to_underlying(Fields::kCredentialData):
            ReturnErrorOnFailure(DataModel::Decode(reader, credentialData));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kUserStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, userStatus));
            break;
        case to_underlying(Fields::kUserType):
            ReturnErrorOnFailure(DataModel::Decode(reader, userType));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SetCredential.
namespace SetCredentialResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNextCredentialIndex)), nextCredentialIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kNextCredentialIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, nextCredentialIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SetCredentialResponse.
namespace GetCredentialStatus {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredential)), credential));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCredential):
            ReturnErrorOnFailure(DataModel::Decode(reader, credential));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetCredentialStatus.
namespace GetCredentialStatusResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredentialExists)), credentialExists));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCreatorFabricIndex)), creatorFabricIndex));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLastModifiedFabricIndex)), lastModifiedFabricIndex));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNextCredentialIndex)), nextCredentialIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCredentialExists):
            ReturnErrorOnFailure(DataModel::Decode(reader, credentialExists));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kCreatorFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, creatorFabricIndex));
            break;
        case to_underlying(Fields::kLastModifiedFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, lastModifiedFabricIndex));
            break;
        case to_underlying(Fields::kNextCredentialIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, nextCredentialIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetCredentialStatusResponse.
namespace ClearCredential {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredential)), credential));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCredential):
            ReturnErrorOnFailure(DataModel::Decode(reader, credential));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ClearCredential.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::LockState::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lockState));
        break;
    case Attributes::LockType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lockType));
        break;
    case Attributes::ActuatorEnabled::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, actuatorEnabled));
        break;
    case Attributes::DoorState::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, doorState));
        break;
    case Attributes::DoorOpenEvents::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, doorOpenEvents));
        break;
    case Attributes::DoorClosedEvents::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, doorClosedEvents));
        break;
    case Attributes::OpenPeriod::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, openPeriod));
        break;
    case Attributes::NumberOfTotalUsersSupported::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfTotalUsersSupported));
        break;
    case Attributes::NumberOfPINUsersSupported::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfPINUsersSupported));
        break;
    case Attributes::NumberOfRFIDUsersSupported::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfRFIDUsersSupported));
        break;
    case Attributes::NumberOfWeekDaySchedulesSupportedPerUser::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfWeekDaySchedulesSupportedPerUser));
        break;
    case Attributes::NumberOfYearDaySchedulesSupportedPerUser::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfYearDaySchedulesSupportedPerUser));
        break;
    case Attributes::NumberOfHolidaySchedulesSupported::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfHolidaySchedulesSupported));
        break;
    case Attributes::MaxPINCodeLength::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxPINCodeLength));
        break;
    case Attributes::MinPINCodeLength::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minPINCodeLength));
        break;
    case Attributes::MaxRFIDCodeLength::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxRFIDCodeLength));
        break;
    case Attributes::MinRFIDCodeLength::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minRFIDCodeLength));
        break;
    case Attributes::CredentialRulesSupport::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, credentialRulesSupport));
        break;
    case Attributes::NumberOfCredentialsSupportedPerUser::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfCredentialsSupportedPerUser));
        break;
    case Attributes::Language::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, language));
        break;
    case Attributes::LEDSettings::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, LEDSettings));
        break;
    case Attributes::AutoRelockTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, autoRelockTime));
        break;
    case Attributes::SoundVolume::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, soundVolume));
        break;
    case Attributes::OperatingMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, operatingMode));
        break;
    case Attributes::SupportedOperatingModes::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, supportedOperatingModes));
        break;
    case Attributes::DefaultConfigurationRegister::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, defaultConfigurationRegister));
        break;
    case Attributes::EnableLocalProgramming::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, enableLocalProgramming));
        break;
    case Attributes::EnableOneTouchLocking::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, enableOneTouchLocking));
        break;
    case Attributes::EnableInsideStatusLED::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, enableInsideStatusLED));
        break;
    case Attributes::EnablePrivacyModeButton::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, enablePrivacyModeButton));
        break;
    case Attributes::LocalProgrammingFeatures::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, localProgrammingFeatures));
        break;
    case Attributes::WrongCodeEntryLimit::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, wrongCodeEntryLimit));
        break;
    case Attributes::UserCodeTemporaryDisableTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, userCodeTemporaryDisableTime));
        break;
    case Attributes::SendPINOverTheAir::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, sendPINOverTheAir));
        break;
    case Attributes::RequirePINforRemoteOperation::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, requirePINforRemoteOperation));
        break;
    case Attributes::ExpiringUserTimeout::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, expiringUserTimeout));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace DoorLockAlarm {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAlarmCode)), alarmCode));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kAlarmCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, alarmCode));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace DoorLockAlarm.
namespace DoorStateChange {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDoorState)), doorState));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kDoorState):
            ReturnErrorOnFailure(DataModel::Decode(reader, doorState));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace DoorStateChange.
namespace LockOperation {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLockOperationType)), lockOperationType));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOperationSource)), operationSource));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSourceNode)), sourceNode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredentials)), credentials));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kLockOperationType):
            ReturnErrorOnFailure(DataModel::Decode(reader, lockOperationType));
            break;
        case to_underlying(Fields::kOperationSource):
            ReturnErrorOnFailure(DataModel::Decode(reader, operationSource));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        case to_underlying(Fields::kSourceNode):
            ReturnErrorOnFailure(DataModel::Decode(reader, sourceNode));
            break;
        case to_underlying(Fields::kCredentials):
            ReturnErrorOnFailure(DataModel::Decode(reader, credentials));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace LockOperation.
namespace LockOperationError {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLockOperationType)), lockOperationType));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOperationSource)), operationSource));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOperationError)), operationError));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSourceNode)), sourceNode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCredentials)), credentials));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kLockOperationType):
            ReturnErrorOnFailure(DataModel::Decode(reader, lockOperationType));
            break;
        case to_underlying(Fields::kOperationSource):
            ReturnErrorOnFailure(DataModel::Decode(reader, operationSource));
            break;
        case to_underlying(Fields::kOperationError):
            ReturnErrorOnFailure(DataModel::Decode(reader, operationError));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        case to_underlying(Fields::kSourceNode):
            ReturnErrorOnFailure(DataModel::Decode(reader, sourceNode));
            break;
        case to_underlying(Fields::kCredentials):
            ReturnErrorOnFailure(DataModel::Decode(reader, credentials));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace LockOperationError.
namespace LockUserChange {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLockDataType)), lockDataType));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDataOperationType)), dataOperationType));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOperationSource)), operationSource));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUserIndex)), userIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSourceNode)), sourceNode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDataIndex)), dataIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kLockDataType):
            ReturnErrorOnFailure(DataModel::Decode(reader, lockDataType));
            break;
        case to_underlying(Fields::kDataOperationType):
            ReturnErrorOnFailure(DataModel::Decode(reader, dataOperationType));
            break;
        case to_underlying(Fields::kOperationSource):
            ReturnErrorOnFailure(DataModel::Decode(reader, operationSource));
            break;
        case to_underlying(Fields::kUserIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, userIndex));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        case to_underlying(Fields::kSourceNode):
            ReturnErrorOnFailure(DataModel::Decode(reader, sourceNode));
            break;
        case to_underlying(Fields::kDataIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, dataIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace LockUserChange.
} // namespace Events

} // namespace DoorLock
namespace WindowCovering {

namespace Commands {
namespace UpOrOpen {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace UpOrOpen.
namespace DownOrClose {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace DownOrClose.
namespace StopMotion {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StopMotion.
namespace GoToLiftValue {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLiftValue)), liftValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kLiftValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, liftValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GoToLiftValue.
namespace GoToLiftPercentage {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLiftPercent100thsValue)), liftPercent100thsValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kLiftPercent100thsValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, liftPercent100thsValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GoToLiftPercentage.
namespace GoToTiltValue {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTiltValue)), tiltValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kTiltValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, tiltValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GoToTiltValue.
namespace GoToTiltPercentage {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTiltPercent100thsValue)), tiltPercent100thsValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kTiltPercent100thsValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, tiltPercent100thsValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GoToTiltPercentage.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::Type::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, type));
        break;
    case Attributes::PhysicalClosedLimitLift::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, physicalClosedLimitLift));
        break;
    case Attributes::PhysicalClosedLimitTilt::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, physicalClosedLimitTilt));
        break;
    case Attributes::CurrentPositionLift::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentPositionLift));
        break;
    case Attributes::CurrentPositionTilt::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentPositionTilt));
        break;
    case Attributes::NumberOfActuationsLift::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfActuationsLift));
        break;
    case Attributes::NumberOfActuationsTilt::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfActuationsTilt));
        break;
    case Attributes::ConfigStatus::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, configStatus));
        break;
    case Attributes::CurrentPositionLiftPercentage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentPositionLiftPercentage));
        break;
    case Attributes::CurrentPositionTiltPercentage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentPositionTiltPercentage));
        break;
    case Attributes::OperationalStatus::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, operationalStatus));
        break;
    case Attributes::TargetPositionLiftPercent100ths::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, targetPositionLiftPercent100ths));
        break;
    case Attributes::TargetPositionTiltPercent100ths::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, targetPositionTiltPercent100ths));
        break;
    case Attributes::EndProductType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, endProductType));
        break;
    case Attributes::CurrentPositionLiftPercent100ths::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentPositionLiftPercent100ths));
        break;
    case Attributes::CurrentPositionTiltPercent100ths::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentPositionTiltPercent100ths));
        break;
    case Attributes::InstalledOpenLimitLift::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, installedOpenLimitLift));
        break;
    case Attributes::InstalledClosedLimitLift::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, installedClosedLimitLift));
        break;
    case Attributes::InstalledOpenLimitTilt::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, installedOpenLimitTilt));
        break;
    case Attributes::InstalledClosedLimitTilt::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, installedClosedLimitTilt));
        break;
    case Attributes::Mode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, mode));
        break;
    case Attributes::SafetyStatus::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, safetyStatus));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace WindowCovering
namespace BarrierControl {

namespace Commands {
namespace BarrierControlGoToPercent {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPercentOpen)), percentOpen));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kPercentOpen):
            ReturnErrorOnFailure(DataModel::Decode(reader, percentOpen));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace BarrierControlGoToPercent.
namespace BarrierControlStop {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace BarrierControlStop.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::BarrierMovingState::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, barrierMovingState));
        break;
    case Attributes::BarrierSafetyStatus::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, barrierSafetyStatus));
        break;
    case Attributes::BarrierCapabilities::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, barrierCapabilities));
        break;
    case Attributes::BarrierOpenEvents::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, barrierOpenEvents));
        break;
    case Attributes::BarrierCloseEvents::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, barrierCloseEvents));
        break;
    case Attributes::BarrierCommandOpenEvents::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, barrierCommandOpenEvents));
        break;
    case Attributes::BarrierCommandCloseEvents::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, barrierCommandCloseEvents));
        break;
    case Attributes::BarrierOpenPeriod::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, barrierOpenPeriod));
        break;
    case Attributes::BarrierClosePeriod::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, barrierClosePeriod));
        break;
    case Attributes::BarrierPosition::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, barrierPosition));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace BarrierControl
namespace PumpConfigurationAndControl {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::MaxPressure::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxPressure));
        break;
    case Attributes::MaxSpeed::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxSpeed));
        break;
    case Attributes::MaxFlow::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxFlow));
        break;
    case Attributes::MinConstPressure::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minConstPressure));
        break;
    case Attributes::MaxConstPressure::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxConstPressure));
        break;
    case Attributes::MinCompPressure::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minCompPressure));
        break;
    case Attributes::MaxCompPressure::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxCompPressure));
        break;
    case Attributes::MinConstSpeed::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minConstSpeed));
        break;
    case Attributes::MaxConstSpeed::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxConstSpeed));
        break;
    case Attributes::MinConstFlow::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minConstFlow));
        break;
    case Attributes::MaxConstFlow::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxConstFlow));
        break;
    case Attributes::MinConstTemp::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minConstTemp));
        break;
    case Attributes::MaxConstTemp::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxConstTemp));
        break;
    case Attributes::PumpStatus::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, pumpStatus));
        break;
    case Attributes::EffectiveOperationMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, effectiveOperationMode));
        break;
    case Attributes::EffectiveControlMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, effectiveControlMode));
        break;
    case Attributes::Capacity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, capacity));
        break;
    case Attributes::Speed::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, speed));
        break;
    case Attributes::LifetimeRunningHours::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lifetimeRunningHours));
        break;
    case Attributes::Power::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, power));
        break;
    case Attributes::LifetimeEnergyConsumed::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lifetimeEnergyConsumed));
        break;
    case Attributes::OperationMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, operationMode));
        break;
    case Attributes::ControlMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, controlMode));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace SupplyVoltageLow {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SupplyVoltageLow.
namespace SupplyVoltageHigh {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SupplyVoltageHigh.
namespace PowerMissingPhase {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace PowerMissingPhase.
namespace SystemPressureLow {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SystemPressureLow.
namespace SystemPressureHigh {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SystemPressureHigh.
namespace DryRunning {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace DryRunning.
namespace MotorTemperatureHigh {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MotorTemperatureHigh.
namespace PumpMotorFatalFailure {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace PumpMotorFatalFailure.
namespace ElectronicTemperatureHigh {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ElectronicTemperatureHigh.
namespace PumpBlocked {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace PumpBlocked.
namespace SensorFailure {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SensorFailure.
namespace ElectronicNonFatalFailure {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ElectronicNonFatalFailure.
namespace ElectronicFatalFailure {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ElectronicFatalFailure.
namespace GeneralFault {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GeneralFault.
namespace Leakage {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Leakage.
namespace AirDetection {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace AirDetection.
namespace TurbineOperation {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TurbineOperation.
} // namespace Events

} // namespace PumpConfigurationAndControl
namespace Thermostat {
namespace Structs {
namespace ThermostatScheduleTransition {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kHeatSetpoint)), heatSetpoint));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCoolSetpoint)), coolSetpoint));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kHeatSetpoint):
            ReturnErrorOnFailure(DataModel::Decode(reader, heatSetpoint));
            break;
        case to_underlying(Fields::kCoolSetpoint):
            ReturnErrorOnFailure(DataModel::Decode(reader, coolSetpoint));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ThermostatScheduleTransition
} // namespace Structs

namespace Commands {
namespace SetpointRaiseLower {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMode)), mode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAmount)), amount));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, mode));
            break;
        case to_underlying(Fields::kAmount):
            ReturnErrorOnFailure(DataModel::Decode(reader, amount));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SetpointRaiseLower.
namespace GetWeeklyScheduleResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNumberOfTransitionsForSequence)),
                                           numberOfTransitionsForSequence));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDayOfWeekForSequence)), dayOfWeekForSequence));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kModeForSequence)), modeForSequence));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitions)), transitions));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNumberOfTransitionsForSequence):
            ReturnErrorOnFailure(DataModel::Decode(reader, numberOfTransitionsForSequence));
            break;
        case to_underlying(Fields::kDayOfWeekForSequence):
            ReturnErrorOnFailure(DataModel::Decode(reader, dayOfWeekForSequence));
            break;
        case to_underlying(Fields::kModeForSequence):
            ReturnErrorOnFailure(DataModel::Decode(reader, modeForSequence));
            break;
        case to_underlying(Fields::kTransitions):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitions));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetWeeklyScheduleResponse.
namespace SetWeeklySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNumberOfTransitionsForSequence)),
                                           numberOfTransitionsForSequence));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDayOfWeekForSequence)), dayOfWeekForSequence));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kModeForSequence)), modeForSequence));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitions)), transitions));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNumberOfTransitionsForSequence):
            ReturnErrorOnFailure(DataModel::Decode(reader, numberOfTransitionsForSequence));
            break;
        case to_underlying(Fields::kDayOfWeekForSequence):
            ReturnErrorOnFailure(DataModel::Decode(reader, dayOfWeekForSequence));
            break;
        case to_underlying(Fields::kModeForSequence):
            ReturnErrorOnFailure(DataModel::Decode(reader, modeForSequence));
            break;
        case to_underlying(Fields::kTransitions):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitions));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SetWeeklySchedule.
namespace GetWeeklySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDaysToReturn)), daysToReturn));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kModeToReturn)), modeToReturn));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kDaysToReturn):
            ReturnErrorOnFailure(DataModel::Decode(reader, daysToReturn));
            break;
        case to_underlying(Fields::kModeToReturn):
            ReturnErrorOnFailure(DataModel::Decode(reader, modeToReturn));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetWeeklySchedule.
namespace ClearWeeklySchedule {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ClearWeeklySchedule.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::LocalTemperature::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, localTemperature));
        break;
    case Attributes::OutdoorTemperature::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, outdoorTemperature));
        break;
    case Attributes::Occupancy::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, occupancy));
        break;
    case Attributes::AbsMinHeatSetpointLimit::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, absMinHeatSetpointLimit));
        break;
    case Attributes::AbsMaxHeatSetpointLimit::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, absMaxHeatSetpointLimit));
        break;
    case Attributes::AbsMinCoolSetpointLimit::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, absMinCoolSetpointLimit));
        break;
    case Attributes::AbsMaxCoolSetpointLimit::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, absMaxCoolSetpointLimit));
        break;
    case Attributes::PICoolingDemand::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, PICoolingDemand));
        break;
    case Attributes::PIHeatingDemand::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, PIHeatingDemand));
        break;
    case Attributes::HVACSystemTypeConfiguration::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, HVACSystemTypeConfiguration));
        break;
    case Attributes::LocalTemperatureCalibration::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, localTemperatureCalibration));
        break;
    case Attributes::OccupiedCoolingSetpoint::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, occupiedCoolingSetpoint));
        break;
    case Attributes::OccupiedHeatingSetpoint::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, occupiedHeatingSetpoint));
        break;
    case Attributes::UnoccupiedCoolingSetpoint::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, unoccupiedCoolingSetpoint));
        break;
    case Attributes::UnoccupiedHeatingSetpoint::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, unoccupiedHeatingSetpoint));
        break;
    case Attributes::MinHeatSetpointLimit::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minHeatSetpointLimit));
        break;
    case Attributes::MaxHeatSetpointLimit::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxHeatSetpointLimit));
        break;
    case Attributes::MinCoolSetpointLimit::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minCoolSetpointLimit));
        break;
    case Attributes::MaxCoolSetpointLimit::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxCoolSetpointLimit));
        break;
    case Attributes::MinSetpointDeadBand::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minSetpointDeadBand));
        break;
    case Attributes::RemoteSensing::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, remoteSensing));
        break;
    case Attributes::ControlSequenceOfOperation::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, controlSequenceOfOperation));
        break;
    case Attributes::SystemMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, systemMode));
        break;
    case Attributes::ThermostatRunningMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, thermostatRunningMode));
        break;
    case Attributes::StartOfWeek::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, startOfWeek));
        break;
    case Attributes::NumberOfWeeklyTransitions::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfWeeklyTransitions));
        break;
    case Attributes::NumberOfDailyTransitions::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfDailyTransitions));
        break;
    case Attributes::TemperatureSetpointHold::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, temperatureSetpointHold));
        break;
    case Attributes::TemperatureSetpointHoldDuration::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, temperatureSetpointHoldDuration));
        break;
    case Attributes::ThermostatProgrammingOperationMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, thermostatProgrammingOperationMode));
        break;
    case Attributes::ThermostatRunningState::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, thermostatRunningState));
        break;
    case Attributes::SetpointChangeSource::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, setpointChangeSource));
        break;
    case Attributes::SetpointChangeAmount::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, setpointChangeAmount));
        break;
    case Attributes::SetpointChangeSourceTimestamp::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, setpointChangeSourceTimestamp));
        break;
    case Attributes::OccupiedSetback::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, occupiedSetback));
        break;
    case Attributes::OccupiedSetbackMin::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, occupiedSetbackMin));
        break;
    case Attributes::OccupiedSetbackMax::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, occupiedSetbackMax));
        break;
    case Attributes::UnoccupiedSetback::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, unoccupiedSetback));
        break;
    case Attributes::UnoccupiedSetbackMin::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, unoccupiedSetbackMin));
        break;
    case Attributes::UnoccupiedSetbackMax::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, unoccupiedSetbackMax));
        break;
    case Attributes::EmergencyHeatDelta::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, emergencyHeatDelta));
        break;
    case Attributes::ACType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ACType));
        break;
    case Attributes::ACCapacity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ACCapacity));
        break;
    case Attributes::ACRefrigerantType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ACRefrigerantType));
        break;
    case Attributes::ACCompressorType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ACCompressorType));
        break;
    case Attributes::ACErrorCode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ACErrorCode));
        break;
    case Attributes::ACLouverPosition::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ACLouverPosition));
        break;
    case Attributes::ACCoilTemperature::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ACCoilTemperature));
        break;
    case Attributes::ACCapacityformat::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ACCapacityformat));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace Thermostat
namespace FanControl {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::FanMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, fanMode));
        break;
    case Attributes::FanModeSequence::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, fanModeSequence));
        break;
    case Attributes::PercentSetting::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, percentSetting));
        break;
    case Attributes::PercentCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, percentCurrent));
        break;
    case Attributes::SpeedMax::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, speedMax));
        break;
    case Attributes::SpeedSetting::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, speedSetting));
        break;
    case Attributes::SpeedCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, speedCurrent));
        break;
    case Attributes::RockSupport::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rockSupport));
        break;
    case Attributes::RockSetting::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rockSetting));
        break;
    case Attributes::WindSupport::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, windSupport));
        break;
    case Attributes::WindSetting::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, windSetting));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace FanControl
namespace ThermostatUserInterfaceConfiguration {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::TemperatureDisplayMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, temperatureDisplayMode));
        break;
    case Attributes::KeypadLockout::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, keypadLockout));
        break;
    case Attributes::ScheduleProgrammingVisibility::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, scheduleProgrammingVisibility));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace ThermostatUserInterfaceConfiguration
namespace ColorControl {

namespace Commands {
namespace MoveToHue {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kHue)), hue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDirection)), direction));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kHue):
            ReturnErrorOnFailure(DataModel::Decode(reader, hue));
            break;
        case to_underlying(Fields::kDirection):
            ReturnErrorOnFailure(DataModel::Decode(reader, direction));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveToHue.
namespace MoveHue {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMoveMode)), moveMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRate)), rate));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMoveMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, moveMode));
            break;
        case to_underlying(Fields::kRate):
            ReturnErrorOnFailure(DataModel::Decode(reader, rate));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveHue.
namespace StepHue {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepMode)), stepMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepSize)), stepSize));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStepMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepMode));
            break;
        case to_underlying(Fields::kStepSize):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepSize));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StepHue.
namespace MoveToSaturation {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSaturation)), saturation));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kSaturation):
            ReturnErrorOnFailure(DataModel::Decode(reader, saturation));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveToSaturation.
namespace MoveSaturation {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMoveMode)), moveMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRate)), rate));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMoveMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, moveMode));
            break;
        case to_underlying(Fields::kRate):
            ReturnErrorOnFailure(DataModel::Decode(reader, rate));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveSaturation.
namespace StepSaturation {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepMode)), stepMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepSize)), stepSize));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStepMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepMode));
            break;
        case to_underlying(Fields::kStepSize):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepSize));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StepSaturation.
namespace MoveToHueAndSaturation {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kHue)), hue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSaturation)), saturation));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kHue):
            ReturnErrorOnFailure(DataModel::Decode(reader, hue));
            break;
        case to_underlying(Fields::kSaturation):
            ReturnErrorOnFailure(DataModel::Decode(reader, saturation));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveToHueAndSaturation.
namespace MoveToColor {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kColorX)), colorX));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kColorY)), colorY));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kColorX):
            ReturnErrorOnFailure(DataModel::Decode(reader, colorX));
            break;
        case to_underlying(Fields::kColorY):
            ReturnErrorOnFailure(DataModel::Decode(reader, colorY));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveToColor.
namespace MoveColor {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRateX)), rateX));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRateY)), rateY));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kRateX):
            ReturnErrorOnFailure(DataModel::Decode(reader, rateX));
            break;
        case to_underlying(Fields::kRateY):
            ReturnErrorOnFailure(DataModel::Decode(reader, rateY));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveColor.
namespace StepColor {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepX)), stepX));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepY)), stepY));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStepX):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepX));
            break;
        case to_underlying(Fields::kStepY):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepY));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StepColor.
namespace MoveToColorTemperature {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kColorTemperature)), colorTemperature));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kColorTemperature):
            ReturnErrorOnFailure(DataModel::Decode(reader, colorTemperature));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveToColorTemperature.
namespace EnhancedMoveToHue {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEnhancedHue)), enhancedHue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDirection)), direction));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kEnhancedHue):
            ReturnErrorOnFailure(DataModel::Decode(reader, enhancedHue));
            break;
        case to_underlying(Fields::kDirection):
            ReturnErrorOnFailure(DataModel::Decode(reader, direction));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace EnhancedMoveToHue.
namespace EnhancedMoveHue {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMoveMode)), moveMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRate)), rate));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMoveMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, moveMode));
            break;
        case to_underlying(Fields::kRate):
            ReturnErrorOnFailure(DataModel::Decode(reader, rate));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace EnhancedMoveHue.
namespace EnhancedStepHue {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepMode)), stepMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepSize)), stepSize));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStepMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepMode));
            break;
        case to_underlying(Fields::kStepSize):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepSize));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace EnhancedStepHue.
namespace EnhancedMoveToHueAndSaturation {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEnhancedHue)), enhancedHue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSaturation)), saturation));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kEnhancedHue):
            ReturnErrorOnFailure(DataModel::Decode(reader, enhancedHue));
            break;
        case to_underlying(Fields::kSaturation):
            ReturnErrorOnFailure(DataModel::Decode(reader, saturation));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace EnhancedMoveToHueAndSaturation.
namespace ColorLoopSet {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUpdateFlags)), updateFlags));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAction)), action));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDirection)), direction));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTime)), time));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStartHue)), startHue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kUpdateFlags):
            ReturnErrorOnFailure(DataModel::Decode(reader, updateFlags));
            break;
        case to_underlying(Fields::kAction):
            ReturnErrorOnFailure(DataModel::Decode(reader, action));
            break;
        case to_underlying(Fields::kDirection):
            ReturnErrorOnFailure(DataModel::Decode(reader, direction));
            break;
        case to_underlying(Fields::kTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, time));
            break;
        case to_underlying(Fields::kStartHue):
            ReturnErrorOnFailure(DataModel::Decode(reader, startHue));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ColorLoopSet.
namespace StopMoveStep {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StopMoveStep.
namespace MoveColorTemperature {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMoveMode)), moveMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kRate)), rate));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kColorTemperatureMinimumMireds)),
                                           colorTemperatureMinimumMireds));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kColorTemperatureMaximumMireds)),
                                           colorTemperatureMaximumMireds));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMoveMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, moveMode));
            break;
        case to_underlying(Fields::kRate):
            ReturnErrorOnFailure(DataModel::Decode(reader, rate));
            break;
        case to_underlying(Fields::kColorTemperatureMinimumMireds):
            ReturnErrorOnFailure(DataModel::Decode(reader, colorTemperatureMinimumMireds));
            break;
        case to_underlying(Fields::kColorTemperatureMaximumMireds):
            ReturnErrorOnFailure(DataModel::Decode(reader, colorTemperatureMaximumMireds));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace MoveColorTemperature.
namespace StepColorTemperature {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepMode)), stepMode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStepSize)), stepSize));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTransitionTime)), transitionTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kColorTemperatureMinimumMireds)),
                                           colorTemperatureMinimumMireds));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kColorTemperatureMaximumMireds)),
                                           colorTemperatureMaximumMireds));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsMask)), optionsMask));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionsOverride)), optionsOverride));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStepMode):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepMode));
            break;
        case to_underlying(Fields::kStepSize):
            ReturnErrorOnFailure(DataModel::Decode(reader, stepSize));
            break;
        case to_underlying(Fields::kTransitionTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, transitionTime));
            break;
        case to_underlying(Fields::kColorTemperatureMinimumMireds):
            ReturnErrorOnFailure(DataModel::Decode(reader, colorTemperatureMinimumMireds));
            break;
        case to_underlying(Fields::kColorTemperatureMaximumMireds):
            ReturnErrorOnFailure(DataModel::Decode(reader, colorTemperatureMaximumMireds));
            break;
        case to_underlying(Fields::kOptionsMask):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsMask));
            break;
        case to_underlying(Fields::kOptionsOverride):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionsOverride));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StepColorTemperature.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::CurrentHue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentHue));
        break;
    case Attributes::CurrentSaturation::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentSaturation));
        break;
    case Attributes::RemainingTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, remainingTime));
        break;
    case Attributes::CurrentX::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentX));
        break;
    case Attributes::CurrentY::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentY));
        break;
    case Attributes::DriftCompensation::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, driftCompensation));
        break;
    case Attributes::CompensationText::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, compensationText));
        break;
    case Attributes::ColorTemperature::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorTemperature));
        break;
    case Attributes::ColorMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorMode));
        break;
    case Attributes::Options::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, options));
        break;
    case Attributes::NumberOfPrimaries::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, numberOfPrimaries));
        break;
    case Attributes::Primary1X::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary1X));
        break;
    case Attributes::Primary1Y::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary1Y));
        break;
    case Attributes::Primary1Intensity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary1Intensity));
        break;
    case Attributes::Primary2X::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary2X));
        break;
    case Attributes::Primary2Y::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary2Y));
        break;
    case Attributes::Primary2Intensity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary2Intensity));
        break;
    case Attributes::Primary3X::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary3X));
        break;
    case Attributes::Primary3Y::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary3Y));
        break;
    case Attributes::Primary3Intensity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary3Intensity));
        break;
    case Attributes::Primary4X::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary4X));
        break;
    case Attributes::Primary4Y::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary4Y));
        break;
    case Attributes::Primary4Intensity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary4Intensity));
        break;
    case Attributes::Primary5X::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary5X));
        break;
    case Attributes::Primary5Y::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary5Y));
        break;
    case Attributes::Primary5Intensity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary5Intensity));
        break;
    case Attributes::Primary6X::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary6X));
        break;
    case Attributes::Primary6Y::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary6Y));
        break;
    case Attributes::Primary6Intensity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, primary6Intensity));
        break;
    case Attributes::WhitePointX::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, whitePointX));
        break;
    case Attributes::WhitePointY::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, whitePointY));
        break;
    case Attributes::ColorPointRX::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorPointRX));
        break;
    case Attributes::ColorPointRY::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorPointRY));
        break;
    case Attributes::ColorPointRIntensity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorPointRIntensity));
        break;
    case Attributes::ColorPointGX::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorPointGX));
        break;
    case Attributes::ColorPointGY::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorPointGY));
        break;
    case Attributes::ColorPointGIntensity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorPointGIntensity));
        break;
    case Attributes::ColorPointBX::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorPointBX));
        break;
    case Attributes::ColorPointBY::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorPointBY));
        break;
    case Attributes::ColorPointBIntensity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorPointBIntensity));
        break;
    case Attributes::EnhancedCurrentHue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, enhancedCurrentHue));
        break;
    case Attributes::EnhancedColorMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, enhancedColorMode));
        break;
    case Attributes::ColorLoopActive::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorLoopActive));
        break;
    case Attributes::ColorLoopDirection::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorLoopDirection));
        break;
    case Attributes::ColorLoopTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorLoopTime));
        break;
    case Attributes::ColorLoopStartEnhancedHue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorLoopStartEnhancedHue));
        break;
    case Attributes::ColorLoopStoredEnhancedHue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorLoopStoredEnhancedHue));
        break;
    case Attributes::ColorCapabilities::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorCapabilities));
        break;
    case Attributes::ColorTempPhysicalMinMireds::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorTempPhysicalMinMireds));
        break;
    case Attributes::ColorTempPhysicalMaxMireds::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, colorTempPhysicalMaxMireds));
        break;
    case Attributes::CoupleColorTempToLevelMinMireds::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, coupleColorTempToLevelMinMireds));
        break;
    case Attributes::StartUpColorTemperatureMireds::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, startUpColorTemperatureMireds));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace ColorControl
namespace BallastConfiguration {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::PhysicalMinLevel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, physicalMinLevel));
        break;
    case Attributes::PhysicalMaxLevel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, physicalMaxLevel));
        break;
    case Attributes::BallastStatus::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ballastStatus));
        break;
    case Attributes::MinLevel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minLevel));
        break;
    case Attributes::MaxLevel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxLevel));
        break;
    case Attributes::IntrinsicBalanceFactor::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, intrinsicBalanceFactor));
        break;
    case Attributes::BallastFactorAdjustment::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ballastFactorAdjustment));
        break;
    case Attributes::LampQuantity::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lampQuantity));
        break;
    case Attributes::LampType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lampType));
        break;
    case Attributes::LampManufacturer::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lampManufacturer));
        break;
    case Attributes::LampRatedHours::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lampRatedHours));
        break;
    case Attributes::LampBurnHours::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lampBurnHours));
        break;
    case Attributes::LampAlarmMode::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lampAlarmMode));
        break;
    case Attributes::LampBurnHoursTripPoint::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lampBurnHoursTripPoint));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace BallastConfiguration
namespace IlluminanceMeasurement {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::MeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measuredValue));
        break;
    case Attributes::MinMeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minMeasuredValue));
        break;
    case Attributes::MaxMeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxMeasuredValue));
        break;
    case Attributes::Tolerance::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, tolerance));
        break;
    case Attributes::LightSensorType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lightSensorType));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace IlluminanceMeasurement
namespace TemperatureMeasurement {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::MeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measuredValue));
        break;
    case Attributes::MinMeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minMeasuredValue));
        break;
    case Attributes::MaxMeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxMeasuredValue));
        break;
    case Attributes::Tolerance::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, tolerance));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace TemperatureMeasurement
namespace PressureMeasurement {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::MeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measuredValue));
        break;
    case Attributes::MinMeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minMeasuredValue));
        break;
    case Attributes::MaxMeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxMeasuredValue));
        break;
    case Attributes::Tolerance::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, tolerance));
        break;
    case Attributes::ScaledValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, scaledValue));
        break;
    case Attributes::MinScaledValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minScaledValue));
        break;
    case Attributes::MaxScaledValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxScaledValue));
        break;
    case Attributes::ScaledTolerance::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, scaledTolerance));
        break;
    case Attributes::Scale::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, scale));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace PressureMeasurement
namespace FlowMeasurement {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::MeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measuredValue));
        break;
    case Attributes::MinMeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minMeasuredValue));
        break;
    case Attributes::MaxMeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxMeasuredValue));
        break;
    case Attributes::Tolerance::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, tolerance));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace FlowMeasurement
namespace RelativeHumidityMeasurement {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::MeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measuredValue));
        break;
    case Attributes::MinMeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, minMeasuredValue));
        break;
    case Attributes::MaxMeasuredValue::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, maxMeasuredValue));
        break;
    case Attributes::Tolerance::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, tolerance));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace RelativeHumidityMeasurement
namespace OccupancySensing {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::Occupancy::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, occupancy));
        break;
    case Attributes::OccupancySensorType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, occupancySensorType));
        break;
    case Attributes::OccupancySensorTypeBitmap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, occupancySensorTypeBitmap));
        break;
    case Attributes::PirOccupiedToUnoccupiedDelay::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, pirOccupiedToUnoccupiedDelay));
        break;
    case Attributes::PirUnoccupiedToOccupiedDelay::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, pirUnoccupiedToOccupiedDelay));
        break;
    case Attributes::PirUnoccupiedToOccupiedThreshold::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, pirUnoccupiedToOccupiedThreshold));
        break;
    case Attributes::UltrasonicOccupiedToUnoccupiedDelay::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ultrasonicOccupiedToUnoccupiedDelay));
        break;
    case Attributes::UltrasonicUnoccupiedToOccupiedDelay::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ultrasonicUnoccupiedToOccupiedDelay));
        break;
    case Attributes::UltrasonicUnoccupiedToOccupiedThreshold::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, ultrasonicUnoccupiedToOccupiedThreshold));
        break;
    case Attributes::PhysicalContactOccupiedToUnoccupiedDelay::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, physicalContactOccupiedToUnoccupiedDelay));
        break;
    case Attributes::PhysicalContactUnoccupiedToOccupiedDelay::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, physicalContactUnoccupiedToOccupiedDelay));
        break;
    case Attributes::PhysicalContactUnoccupiedToOccupiedThreshold::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, physicalContactUnoccupiedToOccupiedThreshold));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace OccupancySensing
namespace WakeOnLan {

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::MACAddress::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, MACAddress));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace WakeOnLan
namespace Channel {
namespace Structs {
namespace ChannelInfo {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMajorNumber)), majorNumber));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMinorNumber)), minorNumber));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCallSign)), callSign));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAffiliateCallSign)), affiliateCallSign));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMajorNumber):
            ReturnErrorOnFailure(DataModel::Decode(reader, majorNumber));
            break;
        case to_underlying(Fields::kMinorNumber):
            ReturnErrorOnFailure(DataModel::Decode(reader, minorNumber));
            break;
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        case to_underlying(Fields::kCallSign):
            ReturnErrorOnFailure(DataModel::Decode(reader, callSign));
            break;
        case to_underlying(Fields::kAffiliateCallSign):
            ReturnErrorOnFailure(DataModel::Decode(reader, affiliateCallSign));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ChannelInfo
namespace LineupInfo {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOperatorName)), operatorName));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLineupName)), lineupName));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPostalCode)), postalCode));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLineupInfoType)), lineupInfoType));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kOperatorName):
            ReturnErrorOnFailure(DataModel::Decode(reader, operatorName));
            break;
        case to_underlying(Fields::kLineupName):
            ReturnErrorOnFailure(DataModel::Decode(reader, lineupName));
            break;
        case to_underlying(Fields::kPostalCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, postalCode));
            break;
        case to_underlying(Fields::kLineupInfoType):
            ReturnErrorOnFailure(DataModel::Decode(reader, lineupInfoType));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace LineupInfo
} // namespace Structs

namespace Commands {
namespace ChangeChannel {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMatch)), match));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMatch):
            ReturnErrorOnFailure(DataModel::Decode(reader, match));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ChangeChannel.
namespace ChangeChannelResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kData)), data));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kData):
            ReturnErrorOnFailure(DataModel::Decode(reader, data));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ChangeChannelResponse.
namespace ChangeChannelByNumber {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMajorNumber)), majorNumber));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMinorNumber)), minorNumber));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMajorNumber):
            ReturnErrorOnFailure(DataModel::Decode(reader, majorNumber));
            break;
        case to_underlying(Fields::kMinorNumber):
            ReturnErrorOnFailure(DataModel::Decode(reader, minorNumber));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ChangeChannelByNumber.
namespace SkipChannel {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCount)), count));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCount):
            ReturnErrorOnFailure(DataModel::Decode(reader, count));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SkipChannel.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::ChannelList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, channelList));
        break;
    case Attributes::Lineup::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lineup));
        break;
    case Attributes::CurrentChannel::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentChannel));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace Channel
namespace TargetNavigator {
namespace Structs {
namespace TargetInfo {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIdentifier)), identifier));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kIdentifier):
            ReturnErrorOnFailure(DataModel::Decode(reader, identifier));
            break;
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace TargetInfo
} // namespace Structs

namespace Commands {
namespace NavigateTarget {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTarget)), target));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kData)), data));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kTarget):
            ReturnErrorOnFailure(DataModel::Decode(reader, target));
            break;
        case to_underlying(Fields::kData):
            ReturnErrorOnFailure(DataModel::Decode(reader, data));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace NavigateTarget.
namespace NavigateTargetResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kData)), data));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kData):
            ReturnErrorOnFailure(DataModel::Decode(reader, data));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace NavigateTargetResponse.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::TargetList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, targetList));
        break;
    case Attributes::CurrentTarget::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentTarget));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace TargetNavigator
namespace MediaPlayback {
namespace Structs {
namespace PlaybackPosition {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kUpdatedAt)), updatedAt));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPosition)), position));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kUpdatedAt):
            ReturnErrorOnFailure(DataModel::Decode(reader, updatedAt));
            break;
        case to_underlying(Fields::kPosition):
            ReturnErrorOnFailure(DataModel::Decode(reader, position));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace PlaybackPosition
} // namespace Structs

namespace Commands {
namespace Play {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Play.
namespace Pause {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Pause.
namespace StopPlayback {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StopPlayback.
namespace StartOver {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StartOver.
namespace Previous {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Previous.
namespace Next {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Next.
namespace Rewind {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Rewind.
namespace FastForward {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace FastForward.
namespace SkipForward {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDeltaPositionMilliseconds)), deltaPositionMilliseconds));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kDeltaPositionMilliseconds):
            ReturnErrorOnFailure(DataModel::Decode(reader, deltaPositionMilliseconds));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SkipForward.
namespace SkipBackward {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDeltaPositionMilliseconds)), deltaPositionMilliseconds));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kDeltaPositionMilliseconds):
            ReturnErrorOnFailure(DataModel::Decode(reader, deltaPositionMilliseconds));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SkipBackward.
namespace PlaybackResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kData)), data));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kData):
            ReturnErrorOnFailure(DataModel::Decode(reader, data));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace PlaybackResponse.
namespace Seek {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kPosition)), position));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kPosition):
            ReturnErrorOnFailure(DataModel::Decode(reader, position));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Seek.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::CurrentState::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentState));
        break;
    case Attributes::StartTime::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, startTime));
        break;
    case Attributes::Duration::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, duration));
        break;
    case Attributes::SampledPosition::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, sampledPosition));
        break;
    case Attributes::PlaybackSpeed::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, playbackSpeed));
        break;
    case Attributes::SeekRangeEnd::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, seekRangeEnd));
        break;
    case Attributes::SeekRangeStart::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, seekRangeStart));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace MediaPlayback
namespace MediaInput {
namespace Structs {
namespace InputInfo {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIndex)), index));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kInputType)), inputType));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDescription)), description));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, index));
            break;
        case to_underlying(Fields::kInputType):
            ReturnErrorOnFailure(DataModel::Decode(reader, inputType));
            break;
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        case to_underlying(Fields::kDescription):
            ReturnErrorOnFailure(DataModel::Decode(reader, description));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace InputInfo
} // namespace Structs

namespace Commands {
namespace SelectInput {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIndex)), index));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, index));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SelectInput.
namespace ShowInputStatus {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace ShowInputStatus.
namespace HideInputStatus {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace HideInputStatus.
namespace RenameInput {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIndex)), index));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, index));
            break;
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RenameInput.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::InputList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, inputList));
        break;
    case Attributes::CurrentInput::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentInput));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace MediaInput
namespace LowPower {

namespace Commands {
namespace Sleep {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Sleep.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace LowPower
namespace KeypadInput {

namespace Commands {
namespace SendKey {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kKeyCode)), keyCode));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kKeyCode):
            ReturnErrorOnFailure(DataModel::Decode(reader, keyCode));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SendKey.
namespace SendKeyResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SendKeyResponse.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace KeypadInput
namespace ContentLauncher {
namespace Structs {
namespace Dimension {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kWidth)), width));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kHeight)), height));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMetric)), metric));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kWidth):
            ReturnErrorOnFailure(DataModel::Decode(reader, width));
            break;
        case to_underlying(Fields::kHeight):
            ReturnErrorOnFailure(DataModel::Decode(reader, height));
            break;
        case to_underlying(Fields::kMetric):
            ReturnErrorOnFailure(DataModel::Decode(reader, metric));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace Dimension
namespace AdditionalInfo {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kValue)), value));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        case to_underlying(Fields::kValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, value));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace AdditionalInfo
namespace Parameter {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kType)), type));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kValue)), value));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kExternalIDList)), externalIDList));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kType):
            ReturnErrorOnFailure(DataModel::Decode(reader, type));
            break;
        case to_underlying(Fields::kValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, value));
            break;
        case to_underlying(Fields::kExternalIDList):
            ReturnErrorOnFailure(DataModel::Decode(reader, externalIDList));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace Parameter
namespace ContentSearch {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kParameterList)), parameterList));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kParameterList):
            ReturnErrorOnFailure(DataModel::Decode(reader, parameterList));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ContentSearch
namespace StyleInformation {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kImageUrl)), imageUrl));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kColor)), color));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSize)), size));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kImageUrl):
            ReturnErrorOnFailure(DataModel::Decode(reader, imageUrl));
            break;
        case to_underlying(Fields::kColor):
            ReturnErrorOnFailure(DataModel::Decode(reader, color));
            break;
        case to_underlying(Fields::kSize):
            ReturnErrorOnFailure(DataModel::Decode(reader, size));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace StyleInformation
namespace BrandingInformation {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kProviderName)), providerName));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBackground)), background));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kLogo)), logo));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kProgressBar)), progressBar));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSplash)), splash));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kWaterMark)), waterMark));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kProviderName):
            ReturnErrorOnFailure(DataModel::Decode(reader, providerName));
            break;
        case to_underlying(Fields::kBackground):
            ReturnErrorOnFailure(DataModel::Decode(reader, background));
            break;
        case to_underlying(Fields::kLogo):
            ReturnErrorOnFailure(DataModel::Decode(reader, logo));
            break;
        case to_underlying(Fields::kProgressBar):
            ReturnErrorOnFailure(DataModel::Decode(reader, progressBar));
            break;
        case to_underlying(Fields::kSplash):
            ReturnErrorOnFailure(DataModel::Decode(reader, splash));
            break;
        case to_underlying(Fields::kWaterMark):
            ReturnErrorOnFailure(DataModel::Decode(reader, waterMark));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace BrandingInformation
} // namespace Structs

namespace Commands {
namespace LaunchContent {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSearch)), search));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAutoPlay)), autoPlay));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kData)), data));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kSearch):
            ReturnErrorOnFailure(DataModel::Decode(reader, search));
            break;
        case to_underlying(Fields::kAutoPlay):
            ReturnErrorOnFailure(DataModel::Decode(reader, autoPlay));
            break;
        case to_underlying(Fields::kData):
            ReturnErrorOnFailure(DataModel::Decode(reader, data));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace LaunchContent.
namespace LaunchURL {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kContentURL)), contentURL));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kDisplayString)), displayString));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kBrandingInformation)), brandingInformation));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kContentURL):
            ReturnErrorOnFailure(DataModel::Decode(reader, contentURL));
            break;
        case to_underlying(Fields::kDisplayString):
            ReturnErrorOnFailure(DataModel::Decode(reader, displayString));
            break;
        case to_underlying(Fields::kBrandingInformation):
            ReturnErrorOnFailure(DataModel::Decode(reader, brandingInformation));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace LaunchURL.
namespace LaunchResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kData)), data));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kData):
            ReturnErrorOnFailure(DataModel::Decode(reader, data));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace LaunchResponse.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::AcceptHeader::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptHeader));
        break;
    case Attributes::SupportedStreamingProtocols::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, supportedStreamingProtocols));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace ContentLauncher
namespace AudioOutput {
namespace Structs {
namespace OutputInfo {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIndex)), index));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOutputType)), outputType));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, index));
            break;
        case to_underlying(Fields::kOutputType):
            ReturnErrorOnFailure(DataModel::Decode(reader, outputType));
            break;
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace OutputInfo
} // namespace Structs

namespace Commands {
namespace SelectOutput {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIndex)), index));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, index));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SelectOutput.
namespace RenameOutput {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIndex)), index));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kName)), name));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, index));
            break;
        case to_underlying(Fields::kName):
            ReturnErrorOnFailure(DataModel::Decode(reader, name));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace RenameOutput.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::OutputList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, outputList));
        break;
    case Attributes::CurrentOutput::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentOutput));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace AudioOutput
namespace ApplicationLauncher {
namespace Structs {
namespace Application {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCatalogVendorId)), catalogVendorId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kApplicationId)), applicationId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCatalogVendorId):
            ReturnErrorOnFailure(DataModel::Decode(reader, catalogVendorId));
            break;
        case to_underlying(Fields::kApplicationId):
            ReturnErrorOnFailure(DataModel::Decode(reader, applicationId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace Application
namespace ApplicationEP {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kApplication)), application));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kEndpoint)), endpoint));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kApplication):
            ReturnErrorOnFailure(DataModel::Decode(reader, application));
            break;
        case to_underlying(Fields::kEndpoint):
            ReturnErrorOnFailure(DataModel::Decode(reader, endpoint));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ApplicationEP
} // namespace Structs

namespace Commands {
namespace LaunchApp {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kApplication)), application));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kData)), data));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kApplication):
            ReturnErrorOnFailure(DataModel::Decode(reader, application));
            break;
        case to_underlying(Fields::kData):
            ReturnErrorOnFailure(DataModel::Decode(reader, data));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace LaunchApp.
namespace StopApp {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kApplication)), application));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kApplication):
            ReturnErrorOnFailure(DataModel::Decode(reader, application));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace StopApp.
namespace HideApp {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kApplication)), application));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kApplication):
            ReturnErrorOnFailure(DataModel::Decode(reader, application));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace HideApp.
namespace LauncherResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kData)), data));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kData):
            ReturnErrorOnFailure(DataModel::Decode(reader, data));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace LauncherResponse.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::CatalogList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, catalogList));
        break;
    case Attributes::CurrentApp::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentApp));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace ApplicationLauncher
namespace ApplicationBasic {
namespace Structs {
namespace ApplicationBasicApplication {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kCatalogVendorId)), catalogVendorId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kApplicationId)), applicationId));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kCatalogVendorId):
            ReturnErrorOnFailure(DataModel::Decode(reader, catalogVendorId));
            break;
        case to_underlying(Fields::kApplicationId):
            ReturnErrorOnFailure(DataModel::Decode(reader, applicationId));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace ApplicationBasicApplication
} // namespace Structs

namespace Commands {
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::VendorName::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, vendorName));
        break;
    case Attributes::VendorID::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, vendorID));
        break;
    case Attributes::ApplicationName::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, applicationName));
        break;
    case Attributes::ProductID::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, productID));
        break;
    case Attributes::Application::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, application));
        break;
    case Attributes::Status::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, status));
        break;
    case Attributes::ApplicationVersion::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, applicationVersion));
        break;
    case Attributes::AllowedVendorList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, allowedVendorList));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace ApplicationBasic
namespace AccountLogin {

namespace Commands {
namespace GetSetupPIN {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTempAccountIdentifier)), tempAccountIdentifier));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kTempAccountIdentifier):
            ReturnErrorOnFailure(DataModel::Decode(reader, tempAccountIdentifier));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetSetupPIN.
namespace GetSetupPINResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSetupPIN)), setupPIN));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kSetupPIN):
            ReturnErrorOnFailure(DataModel::Decode(reader, setupPIN));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetSetupPINResponse.
namespace Login {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kTempAccountIdentifier)), tempAccountIdentifier));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kSetupPIN)), setupPIN));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kTempAccountIdentifier):
            ReturnErrorOnFailure(DataModel::Decode(reader, tempAccountIdentifier));
            break;
        case to_underlying(Fields::kSetupPIN):
            ReturnErrorOnFailure(DataModel::Decode(reader, setupPIN));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Login.
namespace Logout {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Logout.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace AccountLogin
namespace ElectricalMeasurement {

namespace Commands {
namespace GetProfileInfoResponseCommand {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kProfileCount)), profileCount));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kProfileIntervalPeriod)), profileIntervalPeriod));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMaxNumberOfIntervals)), maxNumberOfIntervals));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kListOfAttributes)), listOfAttributes));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kProfileCount):
            ReturnErrorOnFailure(DataModel::Decode(reader, profileCount));
            break;
        case to_underlying(Fields::kProfileIntervalPeriod):
            ReturnErrorOnFailure(DataModel::Decode(reader, profileIntervalPeriod));
            break;
        case to_underlying(Fields::kMaxNumberOfIntervals):
            ReturnErrorOnFailure(DataModel::Decode(reader, maxNumberOfIntervals));
            break;
        case to_underlying(Fields::kListOfAttributes):
            ReturnErrorOnFailure(DataModel::Decode(reader, listOfAttributes));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetProfileInfoResponseCommand.
namespace GetProfileInfoCommand {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetProfileInfoCommand.
namespace GetMeasurementProfileResponseCommand {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStartTime)), startTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStatus)), status));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kProfileIntervalPeriod)), profileIntervalPeriod));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNumberOfIntervalsDelivered)), numberOfIntervalsDelivered));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAttributeId)), attributeId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kIntervals)), intervals));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kStartTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, startTime));
            break;
        case to_underlying(Fields::kStatus):
            ReturnErrorOnFailure(DataModel::Decode(reader, status));
            break;
        case to_underlying(Fields::kProfileIntervalPeriod):
            ReturnErrorOnFailure(DataModel::Decode(reader, profileIntervalPeriod));
            break;
        case to_underlying(Fields::kNumberOfIntervalsDelivered):
            ReturnErrorOnFailure(DataModel::Decode(reader, numberOfIntervalsDelivered));
            break;
        case to_underlying(Fields::kAttributeId):
            ReturnErrorOnFailure(DataModel::Decode(reader, attributeId));
            break;
        case to_underlying(Fields::kIntervals):
            ReturnErrorOnFailure(DataModel::Decode(reader, intervals));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetMeasurementProfileResponseCommand.
namespace GetMeasurementProfileCommand {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kAttributeId)), attributeId));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kStartTime)), startTime));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNumberOfIntervals)), numberOfIntervals));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kAttributeId):
            ReturnErrorOnFailure(DataModel::Decode(reader, attributeId));
            break;
        case to_underlying(Fields::kStartTime):
            ReturnErrorOnFailure(DataModel::Decode(reader, startTime));
            break;
        case to_underlying(Fields::kNumberOfIntervals):
            ReturnErrorOnFailure(DataModel::Decode(reader, numberOfIntervals));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace GetMeasurementProfileCommand.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::MeasurementType::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measurementType));
        break;
    case Attributes::DcVoltage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcVoltage));
        break;
    case Attributes::DcVoltageMin::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcVoltageMin));
        break;
    case Attributes::DcVoltageMax::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcVoltageMax));
        break;
    case Attributes::DcCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcCurrent));
        break;
    case Attributes::DcCurrentMin::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcCurrentMin));
        break;
    case Attributes::DcCurrentMax::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcCurrentMax));
        break;
    case Attributes::DcPower::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcPower));
        break;
    case Attributes::DcPowerMin::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcPowerMin));
        break;
    case Attributes::DcPowerMax::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcPowerMax));
        break;
    case Attributes::DcVoltageMultiplier::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcVoltageMultiplier));
        break;
    case Attributes::DcVoltageDivisor::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcVoltageDivisor));
        break;
    case Attributes::DcCurrentMultiplier::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcCurrentMultiplier));
        break;
    case Attributes::DcCurrentDivisor::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcCurrentDivisor));
        break;
    case Attributes::DcPowerMultiplier::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcPowerMultiplier));
        break;
    case Attributes::DcPowerDivisor::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, dcPowerDivisor));
        break;
    case Attributes::AcFrequency::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acFrequency));
        break;
    case Attributes::AcFrequencyMin::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acFrequencyMin));
        break;
    case Attributes::AcFrequencyMax::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acFrequencyMax));
        break;
    case Attributes::NeutralCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, neutralCurrent));
        break;
    case Attributes::TotalActivePower::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, totalActivePower));
        break;
    case Attributes::TotalReactivePower::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, totalReactivePower));
        break;
    case Attributes::TotalApparentPower::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, totalApparentPower));
        break;
    case Attributes::Measured1stHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measured1stHarmonicCurrent));
        break;
    case Attributes::Measured3rdHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measured3rdHarmonicCurrent));
        break;
    case Attributes::Measured5thHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measured5thHarmonicCurrent));
        break;
    case Attributes::Measured7thHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measured7thHarmonicCurrent));
        break;
    case Attributes::Measured9thHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measured9thHarmonicCurrent));
        break;
    case Attributes::Measured11thHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measured11thHarmonicCurrent));
        break;
    case Attributes::MeasuredPhase1stHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measuredPhase1stHarmonicCurrent));
        break;
    case Attributes::MeasuredPhase3rdHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measuredPhase3rdHarmonicCurrent));
        break;
    case Attributes::MeasuredPhase5thHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measuredPhase5thHarmonicCurrent));
        break;
    case Attributes::MeasuredPhase7thHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measuredPhase7thHarmonicCurrent));
        break;
    case Attributes::MeasuredPhase9thHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measuredPhase9thHarmonicCurrent));
        break;
    case Attributes::MeasuredPhase11thHarmonicCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, measuredPhase11thHarmonicCurrent));
        break;
    case Attributes::AcFrequencyMultiplier::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acFrequencyMultiplier));
        break;
    case Attributes::AcFrequencyDivisor::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acFrequencyDivisor));
        break;
    case Attributes::PowerMultiplier::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, powerMultiplier));
        break;
    case Attributes::PowerDivisor::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, powerDivisor));
        break;
    case Attributes::HarmonicCurrentMultiplier::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, harmonicCurrentMultiplier));
        break;
    case Attributes::PhaseHarmonicCurrentMultiplier::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, phaseHarmonicCurrentMultiplier));
        break;
    case Attributes::InstantaneousVoltage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, instantaneousVoltage));
        break;
    case Attributes::InstantaneousLineCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, instantaneousLineCurrent));
        break;
    case Attributes::InstantaneousActiveCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, instantaneousActiveCurrent));
        break;
    case Attributes::InstantaneousReactiveCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, instantaneousReactiveCurrent));
        break;
    case Attributes::InstantaneousPower::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, instantaneousPower));
        break;
    case Attributes::RmsVoltage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltage));
        break;
    case Attributes::RmsVoltageMin::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageMin));
        break;
    case Attributes::RmsVoltageMax::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageMax));
        break;
    case Attributes::RmsCurrent::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsCurrent));
        break;
    case Attributes::RmsCurrentMin::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsCurrentMin));
        break;
    case Attributes::RmsCurrentMax::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsCurrentMax));
        break;
    case Attributes::ActivePower::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activePower));
        break;
    case Attributes::ActivePowerMin::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activePowerMin));
        break;
    case Attributes::ActivePowerMax::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activePowerMax));
        break;
    case Attributes::ReactivePower::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, reactivePower));
        break;
    case Attributes::ApparentPower::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, apparentPower));
        break;
    case Attributes::PowerFactor::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, powerFactor));
        break;
    case Attributes::AverageRmsVoltageMeasurementPeriod::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, averageRmsVoltageMeasurementPeriod));
        break;
    case Attributes::AverageRmsUnderVoltageCounter::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, averageRmsUnderVoltageCounter));
        break;
    case Attributes::RmsExtremeOverVoltagePeriod::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsExtremeOverVoltagePeriod));
        break;
    case Attributes::RmsExtremeUnderVoltagePeriod::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsExtremeUnderVoltagePeriod));
        break;
    case Attributes::RmsVoltageSagPeriod::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageSagPeriod));
        break;
    case Attributes::RmsVoltageSwellPeriod::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageSwellPeriod));
        break;
    case Attributes::AcVoltageMultiplier::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acVoltageMultiplier));
        break;
    case Attributes::AcVoltageDivisor::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acVoltageDivisor));
        break;
    case Attributes::AcCurrentMultiplier::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acCurrentMultiplier));
        break;
    case Attributes::AcCurrentDivisor::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acCurrentDivisor));
        break;
    case Attributes::AcPowerMultiplier::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acPowerMultiplier));
        break;
    case Attributes::AcPowerDivisor::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acPowerDivisor));
        break;
    case Attributes::OverloadAlarmsMask::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, overloadAlarmsMask));
        break;
    case Attributes::VoltageOverload::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, voltageOverload));
        break;
    case Attributes::CurrentOverload::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, currentOverload));
        break;
    case Attributes::AcOverloadAlarmsMask::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acOverloadAlarmsMask));
        break;
    case Attributes::AcVoltageOverload::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acVoltageOverload));
        break;
    case Attributes::AcCurrentOverload::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acCurrentOverload));
        break;
    case Attributes::AcActivePowerOverload::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acActivePowerOverload));
        break;
    case Attributes::AcReactivePowerOverload::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acReactivePowerOverload));
        break;
    case Attributes::AverageRmsOverVoltage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, averageRmsOverVoltage));
        break;
    case Attributes::AverageRmsUnderVoltage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, averageRmsUnderVoltage));
        break;
    case Attributes::RmsExtremeOverVoltage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsExtremeOverVoltage));
        break;
    case Attributes::RmsExtremeUnderVoltage::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsExtremeUnderVoltage));
        break;
    case Attributes::RmsVoltageSag::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageSag));
        break;
    case Attributes::RmsVoltageSwell::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageSwell));
        break;
    case Attributes::LineCurrentPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lineCurrentPhaseB));
        break;
    case Attributes::ActiveCurrentPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeCurrentPhaseB));
        break;
    case Attributes::ReactiveCurrentPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, reactiveCurrentPhaseB));
        break;
    case Attributes::RmsVoltagePhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltagePhaseB));
        break;
    case Attributes::RmsVoltageMinPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageMinPhaseB));
        break;
    case Attributes::RmsVoltageMaxPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageMaxPhaseB));
        break;
    case Attributes::RmsCurrentPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsCurrentPhaseB));
        break;
    case Attributes::RmsCurrentMinPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsCurrentMinPhaseB));
        break;
    case Attributes::RmsCurrentMaxPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsCurrentMaxPhaseB));
        break;
    case Attributes::ActivePowerPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activePowerPhaseB));
        break;
    case Attributes::ActivePowerMinPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activePowerMinPhaseB));
        break;
    case Attributes::ActivePowerMaxPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activePowerMaxPhaseB));
        break;
    case Attributes::ReactivePowerPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, reactivePowerPhaseB));
        break;
    case Attributes::ApparentPowerPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, apparentPowerPhaseB));
        break;
    case Attributes::PowerFactorPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, powerFactorPhaseB));
        break;
    case Attributes::AverageRmsVoltageMeasurementPeriodPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, averageRmsVoltageMeasurementPeriodPhaseB));
        break;
    case Attributes::AverageRmsOverVoltageCounterPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, averageRmsOverVoltageCounterPhaseB));
        break;
    case Attributes::AverageRmsUnderVoltageCounterPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, averageRmsUnderVoltageCounterPhaseB));
        break;
    case Attributes::RmsExtremeOverVoltagePeriodPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsExtremeOverVoltagePeriodPhaseB));
        break;
    case Attributes::RmsExtremeUnderVoltagePeriodPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsExtremeUnderVoltagePeriodPhaseB));
        break;
    case Attributes::RmsVoltageSagPeriodPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageSagPeriodPhaseB));
        break;
    case Attributes::RmsVoltageSwellPeriodPhaseB::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageSwellPeriodPhaseB));
        break;
    case Attributes::LineCurrentPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, lineCurrentPhaseC));
        break;
    case Attributes::ActiveCurrentPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activeCurrentPhaseC));
        break;
    case Attributes::ReactiveCurrentPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, reactiveCurrentPhaseC));
        break;
    case Attributes::RmsVoltagePhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltagePhaseC));
        break;
    case Attributes::RmsVoltageMinPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageMinPhaseC));
        break;
    case Attributes::RmsVoltageMaxPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageMaxPhaseC));
        break;
    case Attributes::RmsCurrentPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsCurrentPhaseC));
        break;
    case Attributes::RmsCurrentMinPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsCurrentMinPhaseC));
        break;
    case Attributes::RmsCurrentMaxPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsCurrentMaxPhaseC));
        break;
    case Attributes::ActivePowerPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activePowerPhaseC));
        break;
    case Attributes::ActivePowerMinPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activePowerMinPhaseC));
        break;
    case Attributes::ActivePowerMaxPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, activePowerMaxPhaseC));
        break;
    case Attributes::ReactivePowerPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, reactivePowerPhaseC));
        break;
    case Attributes::ApparentPowerPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, apparentPowerPhaseC));
        break;
    case Attributes::PowerFactorPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, powerFactorPhaseC));
        break;
    case Attributes::AverageRmsVoltageMeasurementPeriodPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, averageRmsVoltageMeasurementPeriodPhaseC));
        break;
    case Attributes::AverageRmsOverVoltageCounterPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, averageRmsOverVoltageCounterPhaseC));
        break;
    case Attributes::AverageRmsUnderVoltageCounterPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, averageRmsUnderVoltageCounterPhaseC));
        break;
    case Attributes::RmsExtremeOverVoltagePeriodPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsExtremeOverVoltagePeriodPhaseC));
        break;
    case Attributes::RmsExtremeUnderVoltagePeriodPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsExtremeUnderVoltagePeriodPhaseC));
        break;
    case Attributes::RmsVoltageSagPeriodPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageSagPeriodPhaseC));
        break;
    case Attributes::RmsVoltageSwellPeriodPhaseC::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rmsVoltageSwellPeriodPhaseC));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
} // namespace Events

} // namespace ElectricalMeasurement
namespace TestCluster {
namespace Structs {
namespace SimpleStruct {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kA)), a));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kB)), b));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kC)), c));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kD)), d));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kE)), e));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kF)), f));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kG)), g));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kH)), h));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kA):
            ReturnErrorOnFailure(DataModel::Decode(reader, a));
            break;
        case to_underlying(Fields::kB):
            ReturnErrorOnFailure(DataModel::Decode(reader, b));
            break;
        case to_underlying(Fields::kC):
            ReturnErrorOnFailure(DataModel::Decode(reader, c));
            break;
        case to_underlying(Fields::kD):
            ReturnErrorOnFailure(DataModel::Decode(reader, d));
            break;
        case to_underlying(Fields::kE):
            ReturnErrorOnFailure(DataModel::Decode(reader, e));
            break;
        case to_underlying(Fields::kF):
            ReturnErrorOnFailure(DataModel::Decode(reader, f));
            break;
        case to_underlying(Fields::kG):
            ReturnErrorOnFailure(DataModel::Decode(reader, g));
            break;
        case to_underlying(Fields::kH):
            ReturnErrorOnFailure(DataModel::Decode(reader, h));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace SimpleStruct
namespace TestFabricScoped {
CHIP_ERROR Type::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    return DoEncode(writer, tag, NullOptional);
}

CHIP_ERROR Type::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex accessingFabricIndex) const
{
    return DoEncode(writer, tag, MakeOptional(accessingFabricIndex));
}

CHIP_ERROR Type::DoEncode(TLV::TLVWriter & writer, TLV::Tag tag, const Optional<FabricIndex> & accessingFabricIndex) const
{
    bool includeSensitive = !accessingFabricIndex.HasValue() || (accessingFabricIndex.Value() == fabricIndex);
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    if (includeSensitive)
    {
        ReturnErrorOnFailure(
            DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricSensitiveInt8u)), fabricSensitiveInt8u));
    }
    if (includeSensitive)
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalFabricSensitiveInt8u)),
                                               optionalFabricSensitiveInt8u));
    }
    if (includeSensitive)
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableFabricSensitiveInt8u)),
                                               nullableFabricSensitiveInt8u));
    }
    if (includeSensitive)
    {
        ReturnErrorOnFailure(DataModel::Encode(writer,
                                               TLV::ContextTag(to_underlying(Fields::kNullableOptionalFabricSensitiveInt8u)),
                                               nullableOptionalFabricSensitiveInt8u));
    }
    if (includeSensitive)
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricSensitiveCharString)),
                                               fabricSensitiveCharString));
    }
    if (includeSensitive)
    {
        ReturnErrorOnFailure(
            DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricSensitiveStruct)), fabricSensitiveStruct));
    }
    if (includeSensitive)
    {
        ReturnErrorOnFailure(
            DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricSensitiveInt8uList)), fabricSensitiveInt8uList));
    }
    if (accessingFabricIndex.HasValue())
    {
        ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    }
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kFabricSensitiveInt8u):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricSensitiveInt8u));
            break;
        case to_underlying(Fields::kOptionalFabricSensitiveInt8u):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalFabricSensitiveInt8u));
            break;
        case to_underlying(Fields::kNullableFabricSensitiveInt8u):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableFabricSensitiveInt8u));
            break;
        case to_underlying(Fields::kNullableOptionalFabricSensitiveInt8u):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalFabricSensitiveInt8u));
            break;
        case to_underlying(Fields::kFabricSensitiveCharString):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricSensitiveCharString));
            break;
        case to_underlying(Fields::kFabricSensitiveStruct):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricSensitiveStruct));
            break;
        case to_underlying(Fields::kFabricSensitiveInt8uList):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricSensitiveInt8uList));
            break;
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace TestFabricScoped
namespace NullablesAndOptionalsStruct {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableInt)), nullableInt));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalInt)), optionalInt));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalInt)), nullableOptionalInt));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableString)), nullableString));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalString)), optionalString));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalString)), nullableOptionalString));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableStruct)), nullableStruct));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalStruct)), optionalStruct));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalStruct)), nullableOptionalStruct));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableList)), nullableList));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalList)), optionalList));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalList)), nullableOptionalList));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNullableInt):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt));
            break;
        case to_underlying(Fields::kOptionalInt):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalInt));
            break;
        case to_underlying(Fields::kNullableOptionalInt):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalInt));
            break;
        case to_underlying(Fields::kNullableString):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableString));
            break;
        case to_underlying(Fields::kOptionalString):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalString));
            break;
        case to_underlying(Fields::kNullableOptionalString):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalString));
            break;
        case to_underlying(Fields::kNullableStruct):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableStruct));
            break;
        case to_underlying(Fields::kOptionalStruct):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalStruct));
            break;
        case to_underlying(Fields::kNullableOptionalStruct):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalStruct));
            break;
        case to_underlying(Fields::kNullableList):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableList));
            break;
        case to_underlying(Fields::kOptionalList):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalList));
            break;
        case to_underlying(Fields::kNullableOptionalList):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalList));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace NullablesAndOptionalsStruct
namespace NestedStruct {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kA)), a));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kB)), b));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kC)), c));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kA):
            ReturnErrorOnFailure(DataModel::Decode(reader, a));
            break;
        case to_underlying(Fields::kB):
            ReturnErrorOnFailure(DataModel::Decode(reader, b));
            break;
        case to_underlying(Fields::kC):
            ReturnErrorOnFailure(DataModel::Decode(reader, c));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace NestedStruct
namespace NestedStructList {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kA)), a));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kB)), b));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kC)), c));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kD)), d));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kE)), e));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kF)), f));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kG)), g));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kA):
            ReturnErrorOnFailure(DataModel::Decode(reader, a));
            break;
        case to_underlying(Fields::kB):
            ReturnErrorOnFailure(DataModel::Decode(reader, b));
            break;
        case to_underlying(Fields::kC):
            ReturnErrorOnFailure(DataModel::Decode(reader, c));
            break;
        case to_underlying(Fields::kD):
            ReturnErrorOnFailure(DataModel::Decode(reader, d));
            break;
        case to_underlying(Fields::kE):
            ReturnErrorOnFailure(DataModel::Decode(reader, e));
            break;
        case to_underlying(Fields::kF):
            ReturnErrorOnFailure(DataModel::Decode(reader, f));
            break;
        case to_underlying(Fields::kG):
            ReturnErrorOnFailure(DataModel::Decode(reader, g));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace NestedStructList
namespace DoubleNestedStructList {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kA)), a));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kA):
            ReturnErrorOnFailure(DataModel::Decode(reader, a));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace DoubleNestedStructList
namespace TestListStructOctet {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMember1)), member1));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kMember2)), member2));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    err = reader.EnterContainer(outer);
    ReturnErrorOnFailure(err);
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kMember1):
            ReturnErrorOnFailure(DataModel::Decode(reader, member1));
            break;
        case to_underlying(Fields::kMember2):
            ReturnErrorOnFailure(DataModel::Decode(reader, member2));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));

    return CHIP_NO_ERROR;
}

} // namespace TestListStructOctet
} // namespace Structs

namespace Commands {
namespace Test {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace Test.
namespace TestSpecificResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kReturnValue)), returnValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kReturnValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, returnValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestSpecificResponse.
namespace TestNotHandled {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestNotHandled.
namespace TestAddArgumentsResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kReturnValue)), returnValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kReturnValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, returnValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestAddArgumentsResponse.
namespace TestSpecific {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestSpecific.
namespace TestSimpleArgumentResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kReturnValue)), returnValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kReturnValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, returnValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestSimpleArgumentResponse.
namespace TestUnknownCommand {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestUnknownCommand.
namespace TestStructArrayArgumentResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg2)), arg2));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg3)), arg3));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg4)), arg4));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg5)), arg5));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg6)), arg6));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        case to_underlying(Fields::kArg2):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg2));
            break;
        case to_underlying(Fields::kArg3):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg3));
            break;
        case to_underlying(Fields::kArg4):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg4));
            break;
        case to_underlying(Fields::kArg5):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg5));
            break;
        case to_underlying(Fields::kArg6):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg6));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestStructArrayArgumentResponse.
namespace TestAddArguments {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg2)), arg2));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        case to_underlying(Fields::kArg2):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg2));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestAddArguments.
namespace TestListInt8UReverseResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestListInt8UReverseResponse.
namespace TestSimpleArgumentRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestSimpleArgumentRequest.
namespace TestEnumsResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg2)), arg2));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        case to_underlying(Fields::kArg2):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg2));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestEnumsResponse.
namespace TestStructArrayArgumentRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg2)), arg2));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg3)), arg3));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg4)), arg4));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg5)), arg5));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg6)), arg6));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        case to_underlying(Fields::kArg2):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg2));
            break;
        case to_underlying(Fields::kArg3):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg3));
            break;
        case to_underlying(Fields::kArg4):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg4));
            break;
        case to_underlying(Fields::kArg5):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg5));
            break;
        case to_underlying(Fields::kArg6):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg6));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestStructArrayArgumentRequest.
namespace TestNullableOptionalResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kWasPresent)), wasPresent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kWasNull)), wasNull));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kValue)), value));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOriginalValue)), originalValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kWasPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, wasPresent));
            break;
        case to_underlying(Fields::kWasNull):
            ReturnErrorOnFailure(DataModel::Decode(reader, wasNull));
            break;
        case to_underlying(Fields::kValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, value));
            break;
        case to_underlying(Fields::kOriginalValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, originalValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestNullableOptionalResponse.
namespace TestStructArgumentRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestStructArgumentRequest.
namespace TestComplexNullableOptionalResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableIntWasNull)), nullableIntWasNull));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableIntValue)), nullableIntValue));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalIntWasPresent)), optionalIntWasPresent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalIntValue)), optionalIntValue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalIntWasPresent)),
                                           nullableOptionalIntWasPresent));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalIntWasNull)), nullableOptionalIntWasNull));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalIntValue)), nullableOptionalIntValue));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableStringWasNull)), nullableStringWasNull));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableStringValue)), nullableStringValue));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalStringWasPresent)), optionalStringWasPresent));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalStringValue)), optionalStringValue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalStringWasPresent)),
                                           nullableOptionalStringWasPresent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalStringWasNull)),
                                           nullableOptionalStringWasNull));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalStringValue)),
                                           nullableOptionalStringValue));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableStructWasNull)), nullableStructWasNull));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableStructValue)), nullableStructValue));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalStructWasPresent)), optionalStructWasPresent));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalStructValue)), optionalStructValue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalStructWasPresent)),
                                           nullableOptionalStructWasPresent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalStructWasNull)),
                                           nullableOptionalStructWasNull));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalStructValue)),
                                           nullableOptionalStructValue));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableListWasNull)), nullableListWasNull));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableListValue)), nullableListValue));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalListWasPresent)), optionalListWasPresent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalListValue)), optionalListValue));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalListWasPresent)),
                                           nullableOptionalListWasPresent));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalListWasNull)),
                                           nullableOptionalListWasNull));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalListValue)), nullableOptionalListValue));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNullableIntWasNull):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableIntWasNull));
            break;
        case to_underlying(Fields::kNullableIntValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableIntValue));
            break;
        case to_underlying(Fields::kOptionalIntWasPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalIntWasPresent));
            break;
        case to_underlying(Fields::kOptionalIntValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalIntValue));
            break;
        case to_underlying(Fields::kNullableOptionalIntWasPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalIntWasPresent));
            break;
        case to_underlying(Fields::kNullableOptionalIntWasNull):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalIntWasNull));
            break;
        case to_underlying(Fields::kNullableOptionalIntValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalIntValue));
            break;
        case to_underlying(Fields::kNullableStringWasNull):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableStringWasNull));
            break;
        case to_underlying(Fields::kNullableStringValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableStringValue));
            break;
        case to_underlying(Fields::kOptionalStringWasPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalStringWasPresent));
            break;
        case to_underlying(Fields::kOptionalStringValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalStringValue));
            break;
        case to_underlying(Fields::kNullableOptionalStringWasPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalStringWasPresent));
            break;
        case to_underlying(Fields::kNullableOptionalStringWasNull):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalStringWasNull));
            break;
        case to_underlying(Fields::kNullableOptionalStringValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalStringValue));
            break;
        case to_underlying(Fields::kNullableStructWasNull):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableStructWasNull));
            break;
        case to_underlying(Fields::kNullableStructValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableStructValue));
            break;
        case to_underlying(Fields::kOptionalStructWasPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalStructWasPresent));
            break;
        case to_underlying(Fields::kOptionalStructValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalStructValue));
            break;
        case to_underlying(Fields::kNullableOptionalStructWasPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalStructWasPresent));
            break;
        case to_underlying(Fields::kNullableOptionalStructWasNull):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalStructWasNull));
            break;
        case to_underlying(Fields::kNullableOptionalStructValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalStructValue));
            break;
        case to_underlying(Fields::kNullableListWasNull):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableListWasNull));
            break;
        case to_underlying(Fields::kNullableListValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableListValue));
            break;
        case to_underlying(Fields::kOptionalListWasPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalListWasPresent));
            break;
        case to_underlying(Fields::kOptionalListValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalListValue));
            break;
        case to_underlying(Fields::kNullableOptionalListWasPresent):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalListWasPresent));
            break;
        case to_underlying(Fields::kNullableOptionalListWasNull):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalListWasNull));
            break;
        case to_underlying(Fields::kNullableOptionalListValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalListValue));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestComplexNullableOptionalResponse.
namespace TestNestedStructArgumentRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestNestedStructArgumentRequest.
namespace BooleanResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kValue)), value));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, value));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace BooleanResponse.
namespace TestListStructArgumentRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestListStructArgumentRequest.
namespace SimpleStructResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SimpleStructResponse.
namespace TestListInt8UArgumentRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestListInt8UArgumentRequest.
namespace TestEmitTestEventResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kValue)), value));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, value));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestEmitTestEventResponse.
namespace TestNestedStructListArgumentRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestNestedStructListArgumentRequest.
namespace TestEmitTestFabricScopedEventResponse {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kValue)), value));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kValue):
            ReturnErrorOnFailure(DataModel::Decode(reader, value));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestEmitTestFabricScopedEventResponse.
namespace TestListNestedStructListArgumentRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestListNestedStructListArgumentRequest.
namespace TestListInt8UReverseRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestListInt8UReverseRequest.
namespace TestEnumsRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg2)), arg2));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        case to_underlying(Fields::kArg2):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg2));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestEnumsRequest.
namespace TestNullableOptionalRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestNullableOptionalRequest.
namespace TestComplexNullableOptionalRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableInt)), nullableInt));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalInt)), optionalInt));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalInt)), nullableOptionalInt));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableString)), nullableString));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalString)), optionalString));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalString)), nullableOptionalString));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableStruct)), nullableStruct));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalStruct)), optionalStruct));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalStruct)), nullableOptionalStruct));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableList)), nullableList));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kOptionalList)), optionalList));
    ReturnErrorOnFailure(
        DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kNullableOptionalList)), nullableOptionalList));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kNullableInt):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt));
            break;
        case to_underlying(Fields::kOptionalInt):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalInt));
            break;
        case to_underlying(Fields::kNullableOptionalInt):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalInt));
            break;
        case to_underlying(Fields::kNullableString):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableString));
            break;
        case to_underlying(Fields::kOptionalString):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalString));
            break;
        case to_underlying(Fields::kNullableOptionalString):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalString));
            break;
        case to_underlying(Fields::kNullableStruct):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableStruct));
            break;
        case to_underlying(Fields::kOptionalStruct):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalStruct));
            break;
        case to_underlying(Fields::kNullableOptionalStruct):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalStruct));
            break;
        case to_underlying(Fields::kNullableList):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableList));
            break;
        case to_underlying(Fields::kOptionalList):
            ReturnErrorOnFailure(DataModel::Decode(reader, optionalList));
            break;
        case to_underlying(Fields::kNullableOptionalList):
            ReturnErrorOnFailure(DataModel::Decode(reader, nullableOptionalList));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestComplexNullableOptionalRequest.
namespace SimpleStructEchoRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace SimpleStructEchoRequest.
namespace TimedInvokeRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TimedInvokeRequest.
namespace TestSimpleOptionalArgumentRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestSimpleOptionalArgumentRequest.
namespace TestEmitTestEventRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg2)), arg2));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg3)), arg3));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        case to_underlying(Fields::kArg2):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg2));
            break;
        case to_underlying(Fields::kArg3):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg3));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestEmitTestEventRequest.
namespace TestEmitTestFabricScopedEventRequest {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestEmitTestFabricScopedEventRequest.
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path)
{
    switch (path.mAttributeId)
    {
    case Attributes::Boolean::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, boolean));
        break;
    case Attributes::Bitmap8::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, bitmap8));
        break;
    case Attributes::Bitmap16::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, bitmap16));
        break;
    case Attributes::Bitmap32::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, bitmap32));
        break;
    case Attributes::Bitmap64::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, bitmap64));
        break;
    case Attributes::Int8u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int8u));
        break;
    case Attributes::Int16u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int16u));
        break;
    case Attributes::Int24u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int24u));
        break;
    case Attributes::Int32u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int32u));
        break;
    case Attributes::Int40u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int40u));
        break;
    case Attributes::Int48u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int48u));
        break;
    case Attributes::Int56u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int56u));
        break;
    case Attributes::Int64u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int64u));
        break;
    case Attributes::Int8s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int8s));
        break;
    case Attributes::Int16s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int16s));
        break;
    case Attributes::Int24s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int24s));
        break;
    case Attributes::Int32s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int32s));
        break;
    case Attributes::Int40s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int40s));
        break;
    case Attributes::Int48s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int48s));
        break;
    case Attributes::Int56s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int56s));
        break;
    case Attributes::Int64s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, int64s));
        break;
    case Attributes::Enum8::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, enum8));
        break;
    case Attributes::Enum16::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, enum16));
        break;
    case Attributes::FloatSingle::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, floatSingle));
        break;
    case Attributes::FloatDouble::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, floatDouble));
        break;
    case Attributes::OctetString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, octetString));
        break;
    case Attributes::ListInt8u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, listInt8u));
        break;
    case Attributes::ListOctetString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, listOctetString));
        break;
    case Attributes::ListStructOctetString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, listStructOctetString));
        break;
    case Attributes::LongOctetString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, longOctetString));
        break;
    case Attributes::CharString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, charString));
        break;
    case Attributes::LongCharString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, longCharString));
        break;
    case Attributes::EpochUs::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, epochUs));
        break;
    case Attributes::EpochS::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, epochS));
        break;
    case Attributes::VendorId::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, vendorId));
        break;
    case Attributes::ListNullablesAndOptionalsStruct::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, listNullablesAndOptionalsStruct));
        break;
    case Attributes::EnumAttr::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, enumAttr));
        break;
    case Attributes::StructAttr::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, structAttr));
        break;
    case Attributes::RangeRestrictedInt8u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rangeRestrictedInt8u));
        break;
    case Attributes::RangeRestrictedInt8s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rangeRestrictedInt8s));
        break;
    case Attributes::RangeRestrictedInt16u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rangeRestrictedInt16u));
        break;
    case Attributes::RangeRestrictedInt16s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, rangeRestrictedInt16s));
        break;
    case Attributes::ListLongOctetString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, listLongOctetString));
        break;
    case Attributes::ListFabricScoped::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, listFabricScoped));
        break;
    case Attributes::TimedWriteBoolean::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, timedWriteBoolean));
        break;
    case Attributes::GeneralErrorBoolean::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generalErrorBoolean));
        break;
    case Attributes::ClusterErrorBoolean::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterErrorBoolean));
        break;
    case Attributes::Unsupported::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, unsupported));
        break;
    case Attributes::NullableBoolean::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableBoolean));
        break;
    case Attributes::NullableBitmap8::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableBitmap8));
        break;
    case Attributes::NullableBitmap16::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableBitmap16));
        break;
    case Attributes::NullableBitmap32::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableBitmap32));
        break;
    case Attributes::NullableBitmap64::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableBitmap64));
        break;
    case Attributes::NullableInt8u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt8u));
        break;
    case Attributes::NullableInt16u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt16u));
        break;
    case Attributes::NullableInt24u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt24u));
        break;
    case Attributes::NullableInt32u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt32u));
        break;
    case Attributes::NullableInt40u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt40u));
        break;
    case Attributes::NullableInt48u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt48u));
        break;
    case Attributes::NullableInt56u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt56u));
        break;
    case Attributes::NullableInt64u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt64u));
        break;
    case Attributes::NullableInt8s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt8s));
        break;
    case Attributes::NullableInt16s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt16s));
        break;
    case Attributes::NullableInt24s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt24s));
        break;
    case Attributes::NullableInt32s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt32s));
        break;
    case Attributes::NullableInt40s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt40s));
        break;
    case Attributes::NullableInt48s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt48s));
        break;
    case Attributes::NullableInt56s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt56s));
        break;
    case Attributes::NullableInt64s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableInt64s));
        break;
    case Attributes::NullableEnum8::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableEnum8));
        break;
    case Attributes::NullableEnum16::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableEnum16));
        break;
    case Attributes::NullableFloatSingle::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableFloatSingle));
        break;
    case Attributes::NullableFloatDouble::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableFloatDouble));
        break;
    case Attributes::NullableOctetString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableOctetString));
        break;
    case Attributes::NullableCharString::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableCharString));
        break;
    case Attributes::NullableEnumAttr::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableEnumAttr));
        break;
    case Attributes::NullableStruct::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableStruct));
        break;
    case Attributes::NullableRangeRestrictedInt8u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableRangeRestrictedInt8u));
        break;
    case Attributes::NullableRangeRestrictedInt8s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableRangeRestrictedInt8s));
        break;
    case Attributes::NullableRangeRestrictedInt16u::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableRangeRestrictedInt16u));
        break;
    case Attributes::NullableRangeRestrictedInt16s::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, nullableRangeRestrictedInt16s));
        break;
    case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, generatedCommandList));
        break;
    case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, acceptedCommandList));
        break;
    case Attributes::AttributeList::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, attributeList));
        break;
    case Attributes::FeatureMap::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, featureMap));
        break;
    case Attributes::ClusterRevision::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, clusterRevision));
        break;
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
namespace TestEvent {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg2)), arg2));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg3)), arg3));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg4)), arg4));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg5)), arg5));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg6)), arg6));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kArg1):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg1));
            break;
        case to_underlying(Fields::kArg2):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg2));
            break;
        case to_underlying(Fields::kArg3):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg3));
            break;
        case to_underlying(Fields::kArg4):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg4));
            break;
        case to_underlying(Fields::kArg5):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg5));
            break;
        case to_underlying(Fields::kArg6):
            ReturnErrorOnFailure(DataModel::Decode(reader, arg6));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestEvent.
namespace TestFabricScopedEvent {
CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kFabricIndex)), fabricIndex));
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Fields::kFabricIndex):
            ReturnErrorOnFailure(DataModel::Decode(reader, fabricIndex));
            break;
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace TestFabricScopedEvent.
} // namespace Events

} // namespace TestCluster

} // namespace Clusters

bool CommandNeedsTimedInvoke(ClusterId aCluster, CommandId aCommand)
{
    // Maybe it would be smaller code to codegen a table and walk over it?
    // Not sure.
    switch (aCluster)
    {
    case Clusters::AdministratorCommissioning::Id: {
        switch (aCommand)
        {
        case Clusters::AdministratorCommissioning::Commands::OpenCommissioningWindow::Id:
        case Clusters::AdministratorCommissioning::Commands::OpenBasicCommissioningWindow::Id:
        case Clusters::AdministratorCommissioning::Commands::RevokeCommissioning::Id:
            return true;
        default:
            return false;
        }
    }
    case Clusters::DoorLock::Id: {
        switch (aCommand)
        {
        case Clusters::DoorLock::Commands::LockDoor::Id:
        case Clusters::DoorLock::Commands::UnlockDoor::Id:
        case Clusters::DoorLock::Commands::UnlockWithTimeout::Id:
        case Clusters::DoorLock::Commands::SetUser::Id:
        case Clusters::DoorLock::Commands::ClearUser::Id:
        case Clusters::DoorLock::Commands::SetCredential::Id:
        case Clusters::DoorLock::Commands::ClearCredential::Id:
            return true;
        default:
            return false;
        }
    }
    case Clusters::AccountLogin::Id: {
        switch (aCommand)
        {
        case Clusters::AccountLogin::Commands::GetSetupPIN::Id:
        case Clusters::AccountLogin::Commands::Login::Id:
        case Clusters::AccountLogin::Commands::Logout::Id:
            return true;
        default:
            return false;
        }
    }
    case Clusters::TestCluster::Id: {
        switch (aCommand)
        {
        case Clusters::TestCluster::Commands::TimedInvokeRequest::Id:
            return true;
        default:
            return false;
        }
    }
    default:
        break;
    }

    return false;
}

bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand)
{
    // Maybe it would be smaller code to codegen a table and walk over it?
    // Not sure.
    switch (aCluster)
    {
    case Clusters::Identify::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::Groups::Id: {
        switch (aCommand)
        {
        case Clusters::Groups::Commands::AddGroup::Id:
            return true;
        case Clusters::Groups::Commands::ViewGroup::Id:
            return true;
        case Clusters::Groups::Commands::GetGroupMembership::Id:
            return true;
        case Clusters::Groups::Commands::RemoveGroup::Id:
            return true;
        case Clusters::Groups::Commands::RemoveAllGroups::Id:
            return true;
        case Clusters::Groups::Commands::AddGroupIfIdentifying::Id:
            return true;
        default:
            return false;
        }
    }
    case Clusters::Scenes::Id: {
        switch (aCommand)
        {
        case Clusters::Scenes::Commands::AddScene::Id:
            return true;
        case Clusters::Scenes::Commands::ViewScene::Id:
            return true;
        case Clusters::Scenes::Commands::RemoveScene::Id:
            return true;
        case Clusters::Scenes::Commands::RemoveAllScenes::Id:
            return true;
        case Clusters::Scenes::Commands::StoreScene::Id:
            return true;
        case Clusters::Scenes::Commands::RecallScene::Id:
            return true;
        case Clusters::Scenes::Commands::GetSceneMembership::Id:
            return true;
        case Clusters::Scenes::Commands::EnhancedAddScene::Id:
            return true;
        case Clusters::Scenes::Commands::EnhancedViewScene::Id:
            return true;
        case Clusters::Scenes::Commands::CopyScene::Id:
            return true;
        default:
            return false;
        }
    }
    case Clusters::OnOff::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::LevelControl::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::BridgedActions::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::Basic::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::OtaSoftwareUpdateProvider::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::OtaSoftwareUpdateRequestor::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::GeneralCommissioning::Id: {
        switch (aCommand)
        {
        case Clusters::GeneralCommissioning::Commands::CommissioningComplete::Id:
            return true;
        default:
            return false;
        }
    }
    case Clusters::NetworkCommissioning::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::DiagnosticLogs::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::GeneralDiagnostics::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::SoftwareDiagnostics::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::ThreadNetworkDiagnostics::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::WiFiNetworkDiagnostics::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::EthernetNetworkDiagnostics::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::AdministratorCommissioning::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::OperationalCredentials::Id: {
        switch (aCommand)
        {
        case Clusters::OperationalCredentials::Commands::UpdateNOC::Id:
            return true;
        case Clusters::OperationalCredentials::Commands::UpdateFabricLabel::Id:
            return true;
        default:
            return false;
        }
    }
    case Clusters::GroupKeyManagement::Id: {
        switch (aCommand)
        {
        case Clusters::GroupKeyManagement::Commands::KeySetWrite::Id:
            return true;
        case Clusters::GroupKeyManagement::Commands::KeySetRead::Id:
            return true;
        case Clusters::GroupKeyManagement::Commands::KeySetRemove::Id:
            return true;
        case Clusters::GroupKeyManagement::Commands::KeySetReadAllIndices::Id:
            return true;
        default:
            return false;
        }
    }
    case Clusters::ModeSelect::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::DoorLock::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::WindowCovering::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::BarrierControl::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::Thermostat::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::ColorControl::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::Channel::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::TargetNavigator::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::MediaPlayback::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::MediaInput::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::LowPower::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::KeypadInput::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::ContentLauncher::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::AudioOutput::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::ApplicationLauncher::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::AccountLogin::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::ElectricalMeasurement::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    case Clusters::TestCluster::Id: {
        switch (aCommand)
        {
        default:
            return false;
        }
    }
    }
    return false;
}

} // namespace app
} // namespace chip
