/*
 *
 *    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 <commands/clusters/ComplexArgument.h>

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Scenes::Structs::AttributeValuePair::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("AttributeValuePair.attributeValue", "attributeValue",
                                                                  value.isMember("attributeValue")));

    char labelWithMember[kMaxLabelLength];
    if (value.isMember("attributeID"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "attributeID");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.attributeID, value["attributeID"]));
    }
    valueCopy.removeMember("attributeID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "attributeValue");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.attributeValue, value["attributeValue"]));
    valueCopy.removeMember("attributeValue");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::Scenes::Structs::AttributeValuePair::Type & request)
{
    ComplexArgumentParser::Finalize(request.attributeID);
    ComplexArgumentParser::Finalize(request.attributeValue);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Scenes::Structs::ExtensionFieldSet::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ExtensionFieldSet.clusterID", "clusterID", value.isMember("clusterID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ExtensionFieldSet.attributeValueList", "attributeValueList",
                                                                  value.isMember("attributeValueList")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "clusterID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.clusterID, value["clusterID"]));
    valueCopy.removeMember("clusterID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "attributeValueList");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.attributeValueList, value["attributeValueList"]));
    valueCopy.removeMember("attributeValueList");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::Scenes::Structs::ExtensionFieldSet::Type & request)
{
    ComplexArgumentParser::Finalize(request.clusterID);
    ComplexArgumentParser::Finalize(request.attributeValueList);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("DeviceTypeStruct.deviceType", "deviceType", value.isMember("deviceType")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("DeviceTypeStruct.revision", "revision", value.isMember("revision")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "deviceType");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.deviceType, value["deviceType"]));
    valueCopy.removeMember("deviceType");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "revision");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.revision, value["revision"]));
    valueCopy.removeMember("revision");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.deviceType);
    ComplexArgumentParser::Finalize(request.revision);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Binding::Structs::TargetStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    char labelWithMember[kMaxLabelLength];
    if (value.isMember("node"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "node");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.node, value["node"]));
    }
    valueCopy.removeMember("node");

    if (value.isMember("group"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "group");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.group, value["group"]));
    }
    valueCopy.removeMember("group");

    if (value.isMember("endpoint"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpoint");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpoint, value["endpoint"]));
    }
    valueCopy.removeMember("endpoint");

    if (value.isMember("cluster"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "cluster");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.cluster, value["cluster"]));
    }
    valueCopy.removeMember("cluster");

    if (value.isMember("fabricIndex"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"]));
    }
    valueCopy.removeMember("fabricIndex");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::Binding::Structs::TargetStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.node);
    ComplexArgumentParser::Finalize(request.group);
    ComplexArgumentParser::Finalize(request.endpoint);
    ComplexArgumentParser::Finalize(request.cluster);
    ComplexArgumentParser::Finalize(request.fabricIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::AccessControl::Structs::Target::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("Target.cluster", "cluster", value.isMember("cluster")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("Target.endpoint", "endpoint", value.isMember("endpoint")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("Target.deviceType", "deviceType", value.isMember("deviceType")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "cluster");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.cluster, value["cluster"]));
    valueCopy.removeMember("cluster");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpoint");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpoint, value["endpoint"]));
    valueCopy.removeMember("endpoint");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "deviceType");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.deviceType, value["deviceType"]));
    valueCopy.removeMember("deviceType");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::AccessControl::Structs::Target::Type & request)
{
    ComplexArgumentParser::Finalize(request.cluster);
    ComplexArgumentParser::Finalize(request.endpoint);
    ComplexArgumentParser::Finalize(request.deviceType);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::AccessControl::Structs::AccessControlEntryStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("AccessControlEntryStruct.privilege", "privilege", value.isMember("privilege")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("AccessControlEntryStruct.authMode", "authMode", value.isMember("authMode")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("AccessControlEntryStruct.subjects", "subjects", value.isMember("subjects")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("AccessControlEntryStruct.targets", "targets", value.isMember("targets")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "privilege");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.privilege, value["privilege"]));
    valueCopy.removeMember("privilege");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "authMode");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.authMode, value["authMode"]));
    valueCopy.removeMember("authMode");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "subjects");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.subjects, value["subjects"]));
    valueCopy.removeMember("subjects");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "targets");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.targets, value["targets"]));
    valueCopy.removeMember("targets");

    if (value.isMember("fabricIndex"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"]));
    }
    valueCopy.removeMember("fabricIndex");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::AccessControl::Structs::AccessControlEntryStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.privilege);
    ComplexArgumentParser::Finalize(request.authMode);
    ComplexArgumentParser::Finalize(request.subjects);
    ComplexArgumentParser::Finalize(request.targets);
    ComplexArgumentParser::Finalize(request.fabricIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::AccessControl::Structs::AccessControlExtensionStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("AccessControlExtensionStruct.data", "data", value.isMember("data")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "data");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.data, value["data"]));
    valueCopy.removeMember("data");

    if (value.isMember("fabricIndex"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"]));
    }
    valueCopy.removeMember("fabricIndex");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::AccessControl::Structs::AccessControlExtensionStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.data);
    ComplexArgumentParser::Finalize(request.fabricIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Actions::Structs::ActionStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ActionStruct.actionID", "actionID", value.isMember("actionID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ActionStruct.name", "name", value.isMember("name")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ActionStruct.type", "type", value.isMember("type")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ActionStruct.endpointListID", "endpointListID",
                                                                  value.isMember("endpointListID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ActionStruct.supportedCommands", "supportedCommands",
                                                                  value.isMember("supportedCommands")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ActionStruct.state", "state", value.isMember("state")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "actionID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.actionID, value["actionID"]));
    valueCopy.removeMember("actionID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"]));
    valueCopy.removeMember("name");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "type");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.type, value["type"]));
    valueCopy.removeMember("type");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpointListID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpointListID, value["endpointListID"]));
    valueCopy.removeMember("endpointListID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "supportedCommands");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.supportedCommands, value["supportedCommands"]));
    valueCopy.removeMember("supportedCommands");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "state");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.state, value["state"]));
    valueCopy.removeMember("state");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::Actions::Structs::ActionStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.actionID);
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.type);
    ComplexArgumentParser::Finalize(request.endpointListID);
    ComplexArgumentParser::Finalize(request.supportedCommands);
    ComplexArgumentParser::Finalize(request.state);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Actions::Structs::EndpointListStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("EndpointListStruct.endpointListID", "endpointListID",
                                                                  value.isMember("endpointListID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("EndpointListStruct.name", "name", value.isMember("name")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("EndpointListStruct.type", "type", value.isMember("type")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("EndpointListStruct.endpoints", "endpoints", value.isMember("endpoints")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpointListID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpointListID, value["endpointListID"]));
    valueCopy.removeMember("endpointListID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"]));
    valueCopy.removeMember("name");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "type");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.type, value["type"]));
    valueCopy.removeMember("type");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpoints");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpoints, value["endpoints"]));
    valueCopy.removeMember("endpoints");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::Actions::Structs::EndpointListStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.endpointListID);
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.type);
    ComplexArgumentParser::Finalize(request.endpoints);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::BasicInformation::Structs::CapabilityMinimaStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist(
        "CapabilityMinimaStruct.caseSessionsPerFabric", "caseSessionsPerFabric", value.isMember("caseSessionsPerFabric")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist(
        "CapabilityMinimaStruct.subscriptionsPerFabric", "subscriptionsPerFabric", value.isMember("subscriptionsPerFabric")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "caseSessionsPerFabric");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.caseSessionsPerFabric, value["caseSessionsPerFabric"]));
    valueCopy.removeMember("caseSessionsPerFabric");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "subscriptionsPerFabric");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.subscriptionsPerFabric, value["subscriptionsPerFabric"]));
    valueCopy.removeMember("subscriptionsPerFabric");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::BasicInformation::Structs::CapabilityMinimaStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.caseSessionsPerFabric);
    ComplexArgumentParser::Finalize(request.subscriptionsPerFabric);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::BasicInformation::Structs::ProductAppearanceStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ProductAppearanceStruct.finish", "finish", value.isMember("finish")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ProductAppearanceStruct.primaryColor", "primaryColor",
                                                                  value.isMember("primaryColor")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "finish");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.finish, value["finish"]));
    valueCopy.removeMember("finish");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "primaryColor");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.primaryColor, value["primaryColor"]));
    valueCopy.removeMember("primaryColor");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::BasicInformation::Structs::ProductAppearanceStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.finish);
    ComplexArgumentParser::Finalize(request.primaryColor);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::OtaSoftwareUpdateRequestor::Structs::ProviderLocation::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ProviderLocation.providerNodeID", "providerNodeID",
                                                                  value.isMember("providerNodeID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ProviderLocation.endpoint", "endpoint", value.isMember("endpoint")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "providerNodeID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.providerNodeID, value["providerNodeID"]));
    valueCopy.removeMember("providerNodeID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpoint");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpoint, value["endpoint"]));
    valueCopy.removeMember("endpoint");

    if (value.isMember("fabricIndex"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"]));
    }
    valueCopy.removeMember("fabricIndex");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::OtaSoftwareUpdateRequestor::Structs::ProviderLocation::Type & request)
{
    ComplexArgumentParser::Finalize(request.providerNodeID);
    ComplexArgumentParser::Finalize(request.endpoint);
    ComplexArgumentParser::Finalize(request.fabricIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::PowerSource::Structs::BatChargeFaultChangeType::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("BatChargeFaultChangeType.current", "current", value.isMember("current")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("BatChargeFaultChangeType.previous", "previous", value.isMember("previous")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "current");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.current, value["current"]));
    valueCopy.removeMember("current");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "previous");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.previous, value["previous"]));
    valueCopy.removeMember("previous");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::PowerSource::Structs::BatChargeFaultChangeType::Type & request)
{
    ComplexArgumentParser::Finalize(request.current);
    ComplexArgumentParser::Finalize(request.previous);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::PowerSource::Structs::BatFaultChangeType::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("BatFaultChangeType.current", "current", value.isMember("current")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("BatFaultChangeType.previous", "previous", value.isMember("previous")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "current");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.current, value["current"]));
    valueCopy.removeMember("current");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "previous");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.previous, value["previous"]));
    valueCopy.removeMember("previous");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::PowerSource::Structs::BatFaultChangeType::Type & request)
{
    ComplexArgumentParser::Finalize(request.current);
    ComplexArgumentParser::Finalize(request.previous);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::PowerSource::Structs::WiredFaultChangeType::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("WiredFaultChangeType.current", "current", value.isMember("current")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("WiredFaultChangeType.previous", "previous", value.isMember("previous")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "current");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.current, value["current"]));
    valueCopy.removeMember("current");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "previous");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.previous, value["previous"]));
    valueCopy.removeMember("previous");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::PowerSource::Structs::WiredFaultChangeType::Type & request)
{
    ComplexArgumentParser::Finalize(request.current);
    ComplexArgumentParser::Finalize(request.previous);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::GeneralCommissioning::Structs::BasicCommissioningInfo::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("BasicCommissioningInfo.failSafeExpiryLengthSeconds",
                                                                  "failSafeExpiryLengthSeconds",
                                                                  value.isMember("failSafeExpiryLengthSeconds")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("BasicCommissioningInfo.maxCumulativeFailsafeSeconds",
                                                                  "maxCumulativeFailsafeSeconds",
                                                                  value.isMember("maxCumulativeFailsafeSeconds")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "failSafeExpiryLengthSeconds");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.failSafeExpiryLengthSeconds, value["failSafeExpiryLengthSeconds"]));
    valueCopy.removeMember("failSafeExpiryLengthSeconds");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "maxCumulativeFailsafeSeconds");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.maxCumulativeFailsafeSeconds, value["maxCumulativeFailsafeSeconds"]));
    valueCopy.removeMember("maxCumulativeFailsafeSeconds");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::GeneralCommissioning::Structs::BasicCommissioningInfo::Type & request)
{
    ComplexArgumentParser::Finalize(request.failSafeExpiryLengthSeconds);
    ComplexArgumentParser::Finalize(request.maxCumulativeFailsafeSeconds);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::NetworkCommissioning::Structs::NetworkInfo::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("NetworkInfo.networkID", "networkID", value.isMember("networkID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("NetworkInfo.connected", "connected", value.isMember("connected")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "networkID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.networkID, value["networkID"]));
    valueCopy.removeMember("networkID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "connected");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.connected, value["connected"]));
    valueCopy.removeMember("connected");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::NetworkCommissioning::Structs::NetworkInfo::Type & request)
{
    ComplexArgumentParser::Finalize(request.networkID);
    ComplexArgumentParser::Finalize(request.connected);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::NetworkCommissioning::Structs::ThreadInterfaceScanResult::Type & request,
                             Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResult.panId", "panId", value.isMember("panId")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResult.extendedPanId", "extendedPanId",
                                                                  value.isMember("extendedPanId")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResult.networkName", "networkName",
                                                                  value.isMember("networkName")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResult.channel", "channel", value.isMember("channel")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResult.version", "version", value.isMember("version")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResult.extendedAddress", "extendedAddress",
                                                                  value.isMember("extendedAddress")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResult.rssi", "rssi", value.isMember("rssi")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResult.lqi", "lqi", value.isMember("lqi")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "panId");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.panId, value["panId"]));
    valueCopy.removeMember("panId");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "extendedPanId");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.extendedPanId, value["extendedPanId"]));
    valueCopy.removeMember("extendedPanId");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "networkName");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.networkName, value["networkName"]));
    valueCopy.removeMember("networkName");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "channel");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.channel, value["channel"]));
    valueCopy.removeMember("channel");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "version");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.version, value["version"]));
    valueCopy.removeMember("version");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "extendedAddress");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.extendedAddress, value["extendedAddress"]));
    valueCopy.removeMember("extendedAddress");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "rssi");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.rssi, value["rssi"]));
    valueCopy.removeMember("rssi");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "lqi");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.lqi, value["lqi"]));
    valueCopy.removeMember("lqi");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::NetworkCommissioning::Structs::ThreadInterfaceScanResult::Type & request)
{
    ComplexArgumentParser::Finalize(request.panId);
    ComplexArgumentParser::Finalize(request.extendedPanId);
    ComplexArgumentParser::Finalize(request.networkName);
    ComplexArgumentParser::Finalize(request.channel);
    ComplexArgumentParser::Finalize(request.version);
    ComplexArgumentParser::Finalize(request.extendedAddress);
    ComplexArgumentParser::Finalize(request.rssi);
    ComplexArgumentParser::Finalize(request.lqi);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::NetworkCommissioning::Structs::WiFiInterfaceScanResult::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("WiFiInterfaceScanResult.security", "security", value.isMember("security")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("WiFiInterfaceScanResult.ssid", "ssid", value.isMember("ssid")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("WiFiInterfaceScanResult.bssid", "bssid", value.isMember("bssid")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("WiFiInterfaceScanResult.channel", "channel", value.isMember("channel")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("WiFiInterfaceScanResult.wiFiBand", "wiFiBand", value.isMember("wiFiBand")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("WiFiInterfaceScanResult.rssi", "rssi", value.isMember("rssi")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "security");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.security, value["security"]));
    valueCopy.removeMember("security");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "ssid");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.ssid, value["ssid"]));
    valueCopy.removeMember("ssid");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "bssid");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.bssid, value["bssid"]));
    valueCopy.removeMember("bssid");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "channel");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.channel, value["channel"]));
    valueCopy.removeMember("channel");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "wiFiBand");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.wiFiBand, value["wiFiBand"]));
    valueCopy.removeMember("wiFiBand");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "rssi");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.rssi, value["rssi"]));
    valueCopy.removeMember("rssi");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::NetworkCommissioning::Structs::WiFiInterfaceScanResult::Type & request)
{
    ComplexArgumentParser::Finalize(request.security);
    ComplexArgumentParser::Finalize(request.ssid);
    ComplexArgumentParser::Finalize(request.bssid);
    ComplexArgumentParser::Finalize(request.channel);
    ComplexArgumentParser::Finalize(request.wiFiBand);
    ComplexArgumentParser::Finalize(request.rssi);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::GeneralDiagnostics::Structs::NetworkInterface::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NetworkInterface.name", "name", value.isMember("name")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NetworkInterface.isOperational", "isOperational",
                                                                  value.isMember("isOperational")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NetworkInterface.offPremiseServicesReachableIPv4",
                                                                  "offPremiseServicesReachableIPv4",
                                                                  value.isMember("offPremiseServicesReachableIPv4")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NetworkInterface.offPremiseServicesReachableIPv6",
                                                                  "offPremiseServicesReachableIPv6",
                                                                  value.isMember("offPremiseServicesReachableIPv6")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NetworkInterface.hardwareAddress", "hardwareAddress",
                                                                  value.isMember("hardwareAddress")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NetworkInterface.IPv4Addresses", "IPv4Addresses",
                                                                  value.isMember("IPv4Addresses")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NetworkInterface.IPv6Addresses", "IPv6Addresses",
                                                                  value.isMember("IPv6Addresses")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NetworkInterface.type", "type", value.isMember("type")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"]));
    valueCopy.removeMember("name");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "isOperational");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.isOperational, value["isOperational"]));
    valueCopy.removeMember("isOperational");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "offPremiseServicesReachableIPv4");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.offPremiseServicesReachableIPv4,
                                                      value["offPremiseServicesReachableIPv4"]));
    valueCopy.removeMember("offPremiseServicesReachableIPv4");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "offPremiseServicesReachableIPv6");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.offPremiseServicesReachableIPv6,
                                                      value["offPremiseServicesReachableIPv6"]));
    valueCopy.removeMember("offPremiseServicesReachableIPv6");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "hardwareAddress");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.hardwareAddress, value["hardwareAddress"]));
    valueCopy.removeMember("hardwareAddress");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "IPv4Addresses");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.IPv4Addresses, value["IPv4Addresses"]));
    valueCopy.removeMember("IPv4Addresses");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "IPv6Addresses");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.IPv6Addresses, value["IPv6Addresses"]));
    valueCopy.removeMember("IPv6Addresses");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "type");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.type, value["type"]));
    valueCopy.removeMember("type");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::GeneralDiagnostics::Structs::NetworkInterface::Type & request)
{
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.isOperational);
    ComplexArgumentParser::Finalize(request.offPremiseServicesReachableIPv4);
    ComplexArgumentParser::Finalize(request.offPremiseServicesReachableIPv6);
    ComplexArgumentParser::Finalize(request.hardwareAddress);
    ComplexArgumentParser::Finalize(request.IPv4Addresses);
    ComplexArgumentParser::Finalize(request.IPv6Addresses);
    ComplexArgumentParser::Finalize(request.type);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::SoftwareDiagnostics::Structs::ThreadMetricsStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThreadMetricsStruct.id", "id", value.isMember("id")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "id");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.id, value["id"]));
    valueCopy.removeMember("id");

    if (value.isMember("name"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"]));
    }
    valueCopy.removeMember("name");

    if (value.isMember("stackFreeCurrent"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "stackFreeCurrent");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.stackFreeCurrent, value["stackFreeCurrent"]));
    }
    valueCopy.removeMember("stackFreeCurrent");

    if (value.isMember("stackFreeMinimum"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "stackFreeMinimum");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.stackFreeMinimum, value["stackFreeMinimum"]));
    }
    valueCopy.removeMember("stackFreeMinimum");

    if (value.isMember("stackSize"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "stackSize");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.stackSize, value["stackSize"]));
    }
    valueCopy.removeMember("stackSize");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::SoftwareDiagnostics::Structs::ThreadMetricsStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.id);
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.stackFreeCurrent);
    ComplexArgumentParser::Finalize(request.stackFreeMinimum);
    ComplexArgumentParser::Finalize(request.stackSize);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ThreadNetworkDiagnostics::Structs::NeighborTable::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("NeighborTable.extAddress", "extAddress", value.isMember("extAddress")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTable.age", "age", value.isMember("age")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTable.rloc16", "rloc16", value.isMember("rloc16")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTable.linkFrameCounter", "linkFrameCounter",
                                                                  value.isMember("linkFrameCounter")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTable.mleFrameCounter", "mleFrameCounter",
                                                                  value.isMember("mleFrameCounter")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTable.lqi", "lqi", value.isMember("lqi")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("NeighborTable.averageRssi", "averageRssi", value.isMember("averageRssi")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("NeighborTable.lastRssi", "lastRssi", value.isMember("lastRssi")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTable.frameErrorRate", "frameErrorRate",
                                                                  value.isMember("frameErrorRate")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTable.messageErrorRate", "messageErrorRate",
                                                                  value.isMember("messageErrorRate")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("NeighborTable.rxOnWhenIdle", "rxOnWhenIdle", value.isMember("rxOnWhenIdle")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTable.fullThreadDevice", "fullThreadDevice",
                                                                  value.isMember("fullThreadDevice")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTable.fullNetworkData", "fullNetworkData",
                                                                  value.isMember("fullNetworkData")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTable.isChild", "isChild", value.isMember("isChild")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "extAddress");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.extAddress, value["extAddress"]));
    valueCopy.removeMember("extAddress");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "age");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.age, value["age"]));
    valueCopy.removeMember("age");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "rloc16");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.rloc16, value["rloc16"]));
    valueCopy.removeMember("rloc16");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "linkFrameCounter");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.linkFrameCounter, value["linkFrameCounter"]));
    valueCopy.removeMember("linkFrameCounter");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "mleFrameCounter");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.mleFrameCounter, value["mleFrameCounter"]));
    valueCopy.removeMember("mleFrameCounter");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "lqi");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.lqi, value["lqi"]));
    valueCopy.removeMember("lqi");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "averageRssi");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.averageRssi, value["averageRssi"]));
    valueCopy.removeMember("averageRssi");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "lastRssi");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.lastRssi, value["lastRssi"]));
    valueCopy.removeMember("lastRssi");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "frameErrorRate");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.frameErrorRate, value["frameErrorRate"]));
    valueCopy.removeMember("frameErrorRate");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "messageErrorRate");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.messageErrorRate, value["messageErrorRate"]));
    valueCopy.removeMember("messageErrorRate");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "rxOnWhenIdle");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.rxOnWhenIdle, value["rxOnWhenIdle"]));
    valueCopy.removeMember("rxOnWhenIdle");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fullThreadDevice");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fullThreadDevice, value["fullThreadDevice"]));
    valueCopy.removeMember("fullThreadDevice");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fullNetworkData");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fullNetworkData, value["fullNetworkData"]));
    valueCopy.removeMember("fullNetworkData");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "isChild");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.isChild, value["isChild"]));
    valueCopy.removeMember("isChild");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ThreadNetworkDiagnostics::Structs::NeighborTable::Type & request)
{
    ComplexArgumentParser::Finalize(request.extAddress);
    ComplexArgumentParser::Finalize(request.age);
    ComplexArgumentParser::Finalize(request.rloc16);
    ComplexArgumentParser::Finalize(request.linkFrameCounter);
    ComplexArgumentParser::Finalize(request.mleFrameCounter);
    ComplexArgumentParser::Finalize(request.lqi);
    ComplexArgumentParser::Finalize(request.averageRssi);
    ComplexArgumentParser::Finalize(request.lastRssi);
    ComplexArgumentParser::Finalize(request.frameErrorRate);
    ComplexArgumentParser::Finalize(request.messageErrorRate);
    ComplexArgumentParser::Finalize(request.rxOnWhenIdle);
    ComplexArgumentParser::Finalize(request.fullThreadDevice);
    ComplexArgumentParser::Finalize(request.fullNetworkData);
    ComplexArgumentParser::Finalize(request.isChild);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::ThreadNetworkDiagnostics::Structs::OperationalDatasetComponents::Type & request,
                             Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist(
        "OperationalDatasetComponents.activeTimestampPresent", "activeTimestampPresent", value.isMember("activeTimestampPresent")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("OperationalDatasetComponents.pendingTimestampPresent",
                                                                  "pendingTimestampPresent",
                                                                  value.isMember("pendingTimestampPresent")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("OperationalDatasetComponents.masterKeyPresent",
                                                                  "masterKeyPresent", value.isMember("masterKeyPresent")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("OperationalDatasetComponents.networkNamePresent",
                                                                  "networkNamePresent", value.isMember("networkNamePresent")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("OperationalDatasetComponents.extendedPanIdPresent",
                                                                  "extendedPanIdPresent", value.isMember("extendedPanIdPresent")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist(
        "OperationalDatasetComponents.meshLocalPrefixPresent", "meshLocalPrefixPresent", value.isMember("meshLocalPrefixPresent")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("OperationalDatasetComponents.delayPresent", "delayPresent",
                                                                  value.isMember("delayPresent")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("OperationalDatasetComponents.panIdPresent", "panIdPresent",
                                                                  value.isMember("panIdPresent")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("OperationalDatasetComponents.channelPresent", "channelPresent",
                                                                  value.isMember("channelPresent")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("OperationalDatasetComponents.pskcPresent", "pskcPresent",
                                                                  value.isMember("pskcPresent")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist(
        "OperationalDatasetComponents.securityPolicyPresent", "securityPolicyPresent", value.isMember("securityPolicyPresent")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("OperationalDatasetComponents.channelMaskPresent",
                                                                  "channelMaskPresent", value.isMember("channelMaskPresent")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "activeTimestampPresent");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.activeTimestampPresent, value["activeTimestampPresent"]));
    valueCopy.removeMember("activeTimestampPresent");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "pendingTimestampPresent");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.pendingTimestampPresent, value["pendingTimestampPresent"]));
    valueCopy.removeMember("pendingTimestampPresent");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "masterKeyPresent");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.masterKeyPresent, value["masterKeyPresent"]));
    valueCopy.removeMember("masterKeyPresent");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "networkNamePresent");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.networkNamePresent, value["networkNamePresent"]));
    valueCopy.removeMember("networkNamePresent");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "extendedPanIdPresent");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.extendedPanIdPresent, value["extendedPanIdPresent"]));
    valueCopy.removeMember("extendedPanIdPresent");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "meshLocalPrefixPresent");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.meshLocalPrefixPresent, value["meshLocalPrefixPresent"]));
    valueCopy.removeMember("meshLocalPrefixPresent");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "delayPresent");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.delayPresent, value["delayPresent"]));
    valueCopy.removeMember("delayPresent");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "panIdPresent");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.panIdPresent, value["panIdPresent"]));
    valueCopy.removeMember("panIdPresent");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "channelPresent");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.channelPresent, value["channelPresent"]));
    valueCopy.removeMember("channelPresent");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "pskcPresent");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.pskcPresent, value["pskcPresent"]));
    valueCopy.removeMember("pskcPresent");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "securityPolicyPresent");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.securityPolicyPresent, value["securityPolicyPresent"]));
    valueCopy.removeMember("securityPolicyPresent");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "channelMaskPresent");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.channelMaskPresent, value["channelMaskPresent"]));
    valueCopy.removeMember("channelMaskPresent");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::ThreadNetworkDiagnostics::Structs::OperationalDatasetComponents::Type & request)
{
    ComplexArgumentParser::Finalize(request.activeTimestampPresent);
    ComplexArgumentParser::Finalize(request.pendingTimestampPresent);
    ComplexArgumentParser::Finalize(request.masterKeyPresent);
    ComplexArgumentParser::Finalize(request.networkNamePresent);
    ComplexArgumentParser::Finalize(request.extendedPanIdPresent);
    ComplexArgumentParser::Finalize(request.meshLocalPrefixPresent);
    ComplexArgumentParser::Finalize(request.delayPresent);
    ComplexArgumentParser::Finalize(request.panIdPresent);
    ComplexArgumentParser::Finalize(request.channelPresent);
    ComplexArgumentParser::Finalize(request.pskcPresent);
    ComplexArgumentParser::Finalize(request.securityPolicyPresent);
    ComplexArgumentParser::Finalize(request.channelMaskPresent);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ThreadNetworkDiagnostics::Structs::RouteTable::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("RouteTable.extAddress", "extAddress", value.isMember("extAddress")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTable.rloc16", "rloc16", value.isMember("rloc16")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTable.routerId", "routerId", value.isMember("routerId")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTable.nextHop", "nextHop", value.isMember("nextHop")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTable.pathCost", "pathCost", value.isMember("pathCost")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTable.LQIIn", "LQIIn", value.isMember("LQIIn")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTable.LQIOut", "LQIOut", value.isMember("LQIOut")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTable.age", "age", value.isMember("age")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("RouteTable.allocated", "allocated", value.isMember("allocated")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTable.linkEstablished", "linkEstablished",
                                                                  value.isMember("linkEstablished")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "extAddress");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.extAddress, value["extAddress"]));
    valueCopy.removeMember("extAddress");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "rloc16");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.rloc16, value["rloc16"]));
    valueCopy.removeMember("rloc16");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "routerId");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.routerId, value["routerId"]));
    valueCopy.removeMember("routerId");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nextHop");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.nextHop, value["nextHop"]));
    valueCopy.removeMember("nextHop");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "pathCost");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.pathCost, value["pathCost"]));
    valueCopy.removeMember("pathCost");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "LQIIn");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.LQIIn, value["LQIIn"]));
    valueCopy.removeMember("LQIIn");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "LQIOut");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.LQIOut, value["LQIOut"]));
    valueCopy.removeMember("LQIOut");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "age");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.age, value["age"]));
    valueCopy.removeMember("age");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "allocated");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.allocated, value["allocated"]));
    valueCopy.removeMember("allocated");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "linkEstablished");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.linkEstablished, value["linkEstablished"]));
    valueCopy.removeMember("linkEstablished");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ThreadNetworkDiagnostics::Structs::RouteTable::Type & request)
{
    ComplexArgumentParser::Finalize(request.extAddress);
    ComplexArgumentParser::Finalize(request.rloc16);
    ComplexArgumentParser::Finalize(request.routerId);
    ComplexArgumentParser::Finalize(request.nextHop);
    ComplexArgumentParser::Finalize(request.pathCost);
    ComplexArgumentParser::Finalize(request.LQIIn);
    ComplexArgumentParser::Finalize(request.LQIOut);
    ComplexArgumentParser::Finalize(request.age);
    ComplexArgumentParser::Finalize(request.allocated);
    ComplexArgumentParser::Finalize(request.linkEstablished);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ThreadNetworkDiagnostics::Structs::SecurityPolicy::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("SecurityPolicy.rotationTime", "rotationTime", value.isMember("rotationTime")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SecurityPolicy.flags", "flags", value.isMember("flags")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "rotationTime");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.rotationTime, value["rotationTime"]));
    valueCopy.removeMember("rotationTime");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "flags");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.flags, value["flags"]));
    valueCopy.removeMember("flags");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ThreadNetworkDiagnostics::Structs::SecurityPolicy::Type & request)
{
    ComplexArgumentParser::Finalize(request.rotationTime);
    ComplexArgumentParser::Finalize(request.flags);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("DSTOffsetStruct.offset", "offset", value.isMember("offset")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("DSTOffsetStruct.validStarting", "validStarting",
                                                                  value.isMember("validStarting")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("DSTOffsetStruct.validUntil", "validUntil", value.isMember("validUntil")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "offset");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.offset, value["offset"]));
    valueCopy.removeMember("offset");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "validStarting");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.validStarting, value["validStarting"]));
    valueCopy.removeMember("validStarting");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "validUntil");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.validUntil, value["validUntil"]));
    valueCopy.removeMember("validUntil");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.offset);
    ComplexArgumentParser::Finalize(request.validStarting);
    ComplexArgumentParser::Finalize(request.validUntil);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::TimeSynchronization::Structs::FabricScopedTrustedTimeSourceStruct::Type & request,
                             Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("FabricScopedTrustedTimeSourceStruct.nodeID", "nodeID", value.isMember("nodeID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("FabricScopedTrustedTimeSourceStruct.endpoint", "endpoint",
                                                                  value.isMember("endpoint")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nodeID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.nodeID, value["nodeID"]));
    valueCopy.removeMember("nodeID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpoint");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpoint, value["endpoint"]));
    valueCopy.removeMember("endpoint");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::TimeSynchronization::Structs::FabricScopedTrustedTimeSourceStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.nodeID);
    ComplexArgumentParser::Finalize(request.endpoint);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TimeZoneStruct.offset", "offset", value.isMember("offset")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TimeZoneStruct.validAt", "validAt", value.isMember("validAt")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "offset");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.offset, value["offset"]));
    valueCopy.removeMember("offset");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "validAt");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.validAt, value["validAt"]));
    valueCopy.removeMember("validAt");

    if (value.isMember("name"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"]));
    }
    valueCopy.removeMember("name");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.offset);
    ComplexArgumentParser::Finalize(request.validAt);
    ComplexArgumentParser::Finalize(request.name);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::TimeSynchronization::Structs::TrustedTimeSourceStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TrustedTimeSourceStruct.fabricIndex", "fabricIndex",
                                                                  value.isMember("fabricIndex")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("TrustedTimeSourceStruct.nodeID", "nodeID", value.isMember("nodeID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("TrustedTimeSourceStruct.endpoint", "endpoint", value.isMember("endpoint")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"]));
    valueCopy.removeMember("fabricIndex");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nodeID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.nodeID, value["nodeID"]));
    valueCopy.removeMember("nodeID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpoint");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpoint, value["endpoint"]));
    valueCopy.removeMember("endpoint");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::TimeSynchronization::Structs::TrustedTimeSourceStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.fabricIndex);
    ComplexArgumentParser::Finalize(request.nodeID);
    ComplexArgumentParser::Finalize(request.endpoint);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::BridgedDeviceBasicInformation::Structs::ProductAppearanceStruct::Type & request,
                             Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ProductAppearanceStruct.finish", "finish", value.isMember("finish")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ProductAppearanceStruct.primaryColor", "primaryColor",
                                                                  value.isMember("primaryColor")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "finish");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.finish, value["finish"]));
    valueCopy.removeMember("finish");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "primaryColor");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.primaryColor, value["primaryColor"]));
    valueCopy.removeMember("primaryColor");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::BridgedDeviceBasicInformation::Structs::ProductAppearanceStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.finish);
    ComplexArgumentParser::Finalize(request.primaryColor);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::OperationalCredentials::Structs::FabricDescriptorStruct::Type & request,
                             Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("FabricDescriptorStruct.rootPublicKey", "rootPublicKey",
                                                                  value.isMember("rootPublicKey")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("FabricDescriptorStruct.vendorID", "vendorID", value.isMember("vendorID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("FabricDescriptorStruct.fabricID", "fabricID", value.isMember("fabricID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("FabricDescriptorStruct.nodeID", "nodeID", value.isMember("nodeID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("FabricDescriptorStruct.label", "label", value.isMember("label")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "rootPublicKey");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.rootPublicKey, value["rootPublicKey"]));
    valueCopy.removeMember("rootPublicKey");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "vendorID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.vendorID, value["vendorID"]));
    valueCopy.removeMember("vendorID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricID, value["fabricID"]));
    valueCopy.removeMember("fabricID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nodeID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.nodeID, value["nodeID"]));
    valueCopy.removeMember("nodeID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "label");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.label, value["label"]));
    valueCopy.removeMember("label");

    if (value.isMember("fabricIndex"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"]));
    }
    valueCopy.removeMember("fabricIndex");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::OperationalCredentials::Structs::FabricDescriptorStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.rootPublicKey);
    ComplexArgumentParser::Finalize(request.vendorID);
    ComplexArgumentParser::Finalize(request.fabricID);
    ComplexArgumentParser::Finalize(request.nodeID);
    ComplexArgumentParser::Finalize(request.label);
    ComplexArgumentParser::Finalize(request.fabricIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::OperationalCredentials::Structs::NOCStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NOCStruct.noc", "noc", value.isMember("noc")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NOCStruct.icac", "icac", value.isMember("icac")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "noc");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.noc, value["noc"]));
    valueCopy.removeMember("noc");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "icac");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.icac, value["icac"]));
    valueCopy.removeMember("icac");

    if (value.isMember("fabricIndex"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"]));
    }
    valueCopy.removeMember("fabricIndex");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::OperationalCredentials::Structs::NOCStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.noc);
    ComplexArgumentParser::Finalize(request.icac);
    ComplexArgumentParser::Finalize(request.fabricIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::GroupKeyManagement::Structs::GroupInfoMapStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("GroupInfoMapStruct.groupId", "groupId", value.isMember("groupId")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("GroupInfoMapStruct.endpoints", "endpoints", value.isMember("endpoints")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "groupId");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.groupId, value["groupId"]));
    valueCopy.removeMember("groupId");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpoints");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpoints, value["endpoints"]));
    valueCopy.removeMember("endpoints");

    if (value.isMember("groupName"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "groupName");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.groupName, value["groupName"]));
    }
    valueCopy.removeMember("groupName");

    if (value.isMember("fabricIndex"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"]));
    }
    valueCopy.removeMember("fabricIndex");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::GroupKeyManagement::Structs::GroupInfoMapStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.groupId);
    ComplexArgumentParser::Finalize(request.endpoints);
    ComplexArgumentParser::Finalize(request.groupName);
    ComplexArgumentParser::Finalize(request.fabricIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::GroupKeyManagement::Structs::GroupKeyMapStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("GroupKeyMapStruct.groupId", "groupId", value.isMember("groupId")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("GroupKeyMapStruct.groupKeySetID", "groupKeySetID",
                                                                  value.isMember("groupKeySetID")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "groupId");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.groupId, value["groupId"]));
    valueCopy.removeMember("groupId");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "groupKeySetID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.groupKeySetID, value["groupKeySetID"]));
    valueCopy.removeMember("groupKeySetID");

    if (value.isMember("fabricIndex"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"]));
    }
    valueCopy.removeMember("fabricIndex");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::GroupKeyManagement::Structs::GroupKeyMapStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.groupId);
    ComplexArgumentParser::Finalize(request.groupKeySetID);
    ComplexArgumentParser::Finalize(request.fabricIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::GroupKeyManagement::Structs::GroupKeySetStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("GroupKeySetStruct.groupKeySetID", "groupKeySetID",
                                                                  value.isMember("groupKeySetID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist(
        "GroupKeySetStruct.groupKeySecurityPolicy", "groupKeySecurityPolicy", value.isMember("groupKeySecurityPolicy")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("GroupKeySetStruct.epochKey0", "epochKey0", value.isMember("epochKey0")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("GroupKeySetStruct.epochStartTime0", "epochStartTime0",
                                                                  value.isMember("epochStartTime0")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("GroupKeySetStruct.epochKey1", "epochKey1", value.isMember("epochKey1")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("GroupKeySetStruct.epochStartTime1", "epochStartTime1",
                                                                  value.isMember("epochStartTime1")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("GroupKeySetStruct.epochKey2", "epochKey2", value.isMember("epochKey2")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("GroupKeySetStruct.epochStartTime2", "epochStartTime2",
                                                                  value.isMember("epochStartTime2")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "groupKeySetID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.groupKeySetID, value["groupKeySetID"]));
    valueCopy.removeMember("groupKeySetID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "groupKeySecurityPolicy");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.groupKeySecurityPolicy, value["groupKeySecurityPolicy"]));
    valueCopy.removeMember("groupKeySecurityPolicy");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "epochKey0");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.epochKey0, value["epochKey0"]));
    valueCopy.removeMember("epochKey0");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "epochStartTime0");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.epochStartTime0, value["epochStartTime0"]));
    valueCopy.removeMember("epochStartTime0");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "epochKey1");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.epochKey1, value["epochKey1"]));
    valueCopy.removeMember("epochKey1");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "epochStartTime1");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.epochStartTime1, value["epochStartTime1"]));
    valueCopy.removeMember("epochStartTime1");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "epochKey2");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.epochKey2, value["epochKey2"]));
    valueCopy.removeMember("epochKey2");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "epochStartTime2");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.epochStartTime2, value["epochStartTime2"]));
    valueCopy.removeMember("epochStartTime2");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::GroupKeyManagement::Structs::GroupKeySetStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.groupKeySetID);
    ComplexArgumentParser::Finalize(request.groupKeySecurityPolicy);
    ComplexArgumentParser::Finalize(request.epochKey0);
    ComplexArgumentParser::Finalize(request.epochStartTime0);
    ComplexArgumentParser::Finalize(request.epochKey1);
    ComplexArgumentParser::Finalize(request.epochStartTime1);
    ComplexArgumentParser::Finalize(request.epochKey2);
    ComplexArgumentParser::Finalize(request.epochStartTime2);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::FixedLabel::Structs::LabelStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LabelStruct.label", "label", value.isMember("label")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LabelStruct.value", "value", value.isMember("value")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "label");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.label, value["label"]));
    valueCopy.removeMember("label");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "value");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.value, value["value"]));
    valueCopy.removeMember("value");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::FixedLabel::Structs::LabelStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.label);
    ComplexArgumentParser::Finalize(request.value);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::UserLabel::Structs::LabelStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LabelStruct.label", "label", value.isMember("label")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LabelStruct.value", "value", value.isMember("value")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "label");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.label, value["label"]));
    valueCopy.removeMember("label");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "value");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.value, value["value"]));
    valueCopy.removeMember("value");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::UserLabel::Structs::LabelStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.label);
    ComplexArgumentParser::Finalize(request.value);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::IcdManagement::Structs::MonitoringRegistrationStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MonitoringRegistrationStruct.checkInNodeID", "checkInNodeID",
                                                                  value.isMember("checkInNodeID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MonitoringRegistrationStruct.monitoredSubject",
                                                                  "monitoredSubject", value.isMember("monitoredSubject")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("MonitoringRegistrationStruct.key", "key", value.isMember("key")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "checkInNodeID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.checkInNodeID, value["checkInNodeID"]));
    valueCopy.removeMember("checkInNodeID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "monitoredSubject");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.monitoredSubject, value["monitoredSubject"]));
    valueCopy.removeMember("monitoredSubject");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "key");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.key, value["key"]));
    valueCopy.removeMember("key");

    if (value.isMember("fabricIndex"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"]));
    }
    valueCopy.removeMember("fabricIndex");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::IcdManagement::Structs::MonitoringRegistrationStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.checkInNodeID);
    ComplexArgumentParser::Finalize(request.monitoredSubject);
    ComplexArgumentParser::Finalize(request.key);
    ComplexArgumentParser::Finalize(request.fabricIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ModeSelect::Structs::SemanticTagStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("SemanticTagStruct.mfgCode", "mfgCode", value.isMember("mfgCode")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SemanticTagStruct.value", "value", value.isMember("value")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "mfgCode");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.mfgCode, value["mfgCode"]));
    valueCopy.removeMember("mfgCode");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "value");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.value, value["value"]));
    valueCopy.removeMember("value");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ModeSelect::Structs::SemanticTagStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.mfgCode);
    ComplexArgumentParser::Finalize(request.value);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ModeSelect::Structs::ModeOptionStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ModeOptionStruct.label", "label", value.isMember("label")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ModeOptionStruct.mode", "mode", value.isMember("mode")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ModeOptionStruct.semanticTags", "semanticTags", value.isMember("semanticTags")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "label");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.label, value["label"]));
    valueCopy.removeMember("label");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "mode");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.mode, value["mode"]));
    valueCopy.removeMember("mode");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "semanticTags");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.semanticTags, value["semanticTags"]));
    valueCopy.removeMember("semanticTags");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ModeSelect::Structs::ModeOptionStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.label);
    ComplexArgumentParser::Finalize(request.mode);
    ComplexArgumentParser::Finalize(request.semanticTags);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::TemperatureControl::Structs::TemperatureLevelStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("TemperatureLevelStruct.label", "label", value.isMember("label")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TemperatureLevelStruct.temperatureLevel", "temperatureLevel",
                                                                  value.isMember("temperatureLevel")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "label");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.label, value["label"]));
    valueCopy.removeMember("label");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "temperatureLevel");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.temperatureLevel, value["temperatureLevel"]));
    valueCopy.removeMember("temperatureLevel");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::TemperatureControl::Structs::TemperatureLevelStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.label);
    ComplexArgumentParser::Finalize(request.temperatureLevel);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::DoorLock::Structs::CredentialStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("CredentialStruct.credentialType", "credentialType",
                                                                  value.isMember("credentialType")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("CredentialStruct.credentialIndex", "credentialIndex",
                                                                  value.isMember("credentialIndex")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "credentialType");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.credentialType, value["credentialType"]));
    valueCopy.removeMember("credentialType");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "credentialIndex");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.credentialIndex, value["credentialIndex"]));
    valueCopy.removeMember("credentialIndex");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::DoorLock::Structs::CredentialStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.credentialType);
    ComplexArgumentParser::Finalize(request.credentialIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Thermostat::Structs::ThermostatScheduleTransition::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThermostatScheduleTransition.transitionTime", "transitionTime",
                                                                  value.isMember("transitionTime")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThermostatScheduleTransition.heatSetpoint", "heatSetpoint",
                                                                  value.isMember("heatSetpoint")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThermostatScheduleTransition.coolSetpoint", "coolSetpoint",
                                                                  value.isMember("coolSetpoint")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "transitionTime");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.transitionTime, value["transitionTime"]));
    valueCopy.removeMember("transitionTime");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "heatSetpoint");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.heatSetpoint, value["heatSetpoint"]));
    valueCopy.removeMember("heatSetpoint");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "coolSetpoint");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.coolSetpoint, value["coolSetpoint"]));
    valueCopy.removeMember("coolSetpoint");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::Thermostat::Structs::ThermostatScheduleTransition::Type & request)
{
    ComplexArgumentParser::Finalize(request.transitionTime);
    ComplexArgumentParser::Finalize(request.heatSetpoint);
    ComplexArgumentParser::Finalize(request.coolSetpoint);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Channel::Structs::ChannelInfoStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ChannelInfoStruct.majorNumber", "majorNumber", value.isMember("majorNumber")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ChannelInfoStruct.minorNumber", "minorNumber", value.isMember("minorNumber")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "majorNumber");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.majorNumber, value["majorNumber"]));
    valueCopy.removeMember("majorNumber");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "minorNumber");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.minorNumber, value["minorNumber"]));
    valueCopy.removeMember("minorNumber");

    if (value.isMember("name"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"]));
    }
    valueCopy.removeMember("name");

    if (value.isMember("callSign"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "callSign");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.callSign, value["callSign"]));
    }
    valueCopy.removeMember("callSign");

    if (value.isMember("affiliateCallSign"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "affiliateCallSign");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.affiliateCallSign, value["affiliateCallSign"]));
    }
    valueCopy.removeMember("affiliateCallSign");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::Channel::Structs::ChannelInfoStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.majorNumber);
    ComplexArgumentParser::Finalize(request.minorNumber);
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.callSign);
    ComplexArgumentParser::Finalize(request.affiliateCallSign);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Channel::Structs::LineupInfoStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("LineupInfoStruct.operatorName", "operatorName", value.isMember("operatorName")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LineupInfoStruct.lineupInfoType", "lineupInfoType",
                                                                  value.isMember("lineupInfoType")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "operatorName");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.operatorName, value["operatorName"]));
    valueCopy.removeMember("operatorName");

    if (value.isMember("lineupName"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "lineupName");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.lineupName, value["lineupName"]));
    }
    valueCopy.removeMember("lineupName");

    if (value.isMember("postalCode"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "postalCode");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.postalCode, value["postalCode"]));
    }
    valueCopy.removeMember("postalCode");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "lineupInfoType");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.lineupInfoType, value["lineupInfoType"]));
    valueCopy.removeMember("lineupInfoType");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::Channel::Structs::LineupInfoStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.operatorName);
    ComplexArgumentParser::Finalize(request.lineupName);
    ComplexArgumentParser::Finalize(request.postalCode);
    ComplexArgumentParser::Finalize(request.lineupInfoType);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::TargetNavigator::Structs::TargetInfoStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("TargetInfoStruct.identifier", "identifier", value.isMember("identifier")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TargetInfoStruct.name", "name", value.isMember("name")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "identifier");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.identifier, value["identifier"]));
    valueCopy.removeMember("identifier");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"]));
    valueCopy.removeMember("name");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::TargetNavigator::Structs::TargetInfoStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.identifier);
    ComplexArgumentParser::Finalize(request.name);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::MediaPlayback::Structs::PlaybackPositionStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("PlaybackPositionStruct.updatedAt", "updatedAt", value.isMember("updatedAt")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("PlaybackPositionStruct.position", "position", value.isMember("position")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "updatedAt");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.updatedAt, value["updatedAt"]));
    valueCopy.removeMember("updatedAt");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "position");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.position, value["position"]));
    valueCopy.removeMember("position");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::MediaPlayback::Structs::PlaybackPositionStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.updatedAt);
    ComplexArgumentParser::Finalize(request.position);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::MediaInput::Structs::InputInfoStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("InputInfoStruct.index", "index", value.isMember("index")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("InputInfoStruct.inputType", "inputType", value.isMember("inputType")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("InputInfoStruct.name", "name", value.isMember("name")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("InputInfoStruct.description", "description", value.isMember("description")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "index");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.index, value["index"]));
    valueCopy.removeMember("index");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "inputType");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.inputType, value["inputType"]));
    valueCopy.removeMember("inputType");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"]));
    valueCopy.removeMember("name");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "description");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.description, value["description"]));
    valueCopy.removeMember("description");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::MediaInput::Structs::InputInfoStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.index);
    ComplexArgumentParser::Finalize(request.inputType);
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.description);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ContentLauncher::Structs::DimensionStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("DimensionStruct.width", "width", value.isMember("width")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("DimensionStruct.height", "height", value.isMember("height")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("DimensionStruct.metric", "metric", value.isMember("metric")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "width");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.width, value["width"]));
    valueCopy.removeMember("width");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "height");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.height, value["height"]));
    valueCopy.removeMember("height");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "metric");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.metric, value["metric"]));
    valueCopy.removeMember("metric");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ContentLauncher::Structs::DimensionStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.width);
    ComplexArgumentParser::Finalize(request.height);
    ComplexArgumentParser::Finalize(request.metric);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ContentLauncher::Structs::AdditionalInfoStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("AdditionalInfoStruct.name", "name", value.isMember("name")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("AdditionalInfoStruct.value", "value", value.isMember("value")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"]));
    valueCopy.removeMember("name");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "value");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.value, value["value"]));
    valueCopy.removeMember("value");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ContentLauncher::Structs::AdditionalInfoStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.value);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ContentLauncher::Structs::ParameterStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ParameterStruct.type", "type", value.isMember("type")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ParameterStruct.value", "value", value.isMember("value")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "type");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.type, value["type"]));
    valueCopy.removeMember("type");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "value");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.value, value["value"]));
    valueCopy.removeMember("value");

    if (value.isMember("externalIDList"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "externalIDList");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.externalIDList, value["externalIDList"]));
    }
    valueCopy.removeMember("externalIDList");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ContentLauncher::Structs::ParameterStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.type);
    ComplexArgumentParser::Finalize(request.value);
    ComplexArgumentParser::Finalize(request.externalIDList);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ContentLauncher::Structs::ContentSearchStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ContentSearchStruct.parameterList", "parameterList",
                                                                  value.isMember("parameterList")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "parameterList");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.parameterList, value["parameterList"]));
    valueCopy.removeMember("parameterList");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ContentLauncher::Structs::ContentSearchStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.parameterList);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ContentLauncher::Structs::StyleInformationStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    char labelWithMember[kMaxLabelLength];
    if (value.isMember("imageURL"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "imageURL");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.imageURL, value["imageURL"]));
    }
    valueCopy.removeMember("imageURL");

    if (value.isMember("color"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "color");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.color, value["color"]));
    }
    valueCopy.removeMember("color");

    if (value.isMember("size"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "size");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.size, value["size"]));
    }
    valueCopy.removeMember("size");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ContentLauncher::Structs::StyleInformationStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.imageURL);
    ComplexArgumentParser::Finalize(request.color);
    ComplexArgumentParser::Finalize(request.size);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ContentLauncher::Structs::BrandingInformationStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("BrandingInformationStruct.providerName", "providerName",
                                                                  value.isMember("providerName")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "providerName");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.providerName, value["providerName"]));
    valueCopy.removeMember("providerName");

    if (value.isMember("background"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "background");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.background, value["background"]));
    }
    valueCopy.removeMember("background");

    if (value.isMember("logo"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "logo");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.logo, value["logo"]));
    }
    valueCopy.removeMember("logo");

    if (value.isMember("progressBar"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "progressBar");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.progressBar, value["progressBar"]));
    }
    valueCopy.removeMember("progressBar");

    if (value.isMember("splash"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "splash");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.splash, value["splash"]));
    }
    valueCopy.removeMember("splash");

    if (value.isMember("waterMark"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "waterMark");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.waterMark, value["waterMark"]));
    }
    valueCopy.removeMember("waterMark");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ContentLauncher::Structs::BrandingInformationStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.providerName);
    ComplexArgumentParser::Finalize(request.background);
    ComplexArgumentParser::Finalize(request.logo);
    ComplexArgumentParser::Finalize(request.progressBar);
    ComplexArgumentParser::Finalize(request.splash);
    ComplexArgumentParser::Finalize(request.waterMark);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::AudioOutput::Structs::OutputInfoStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("OutputInfoStruct.index", "index", value.isMember("index")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("OutputInfoStruct.outputType", "outputType", value.isMember("outputType")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("OutputInfoStruct.name", "name", value.isMember("name")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "index");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.index, value["index"]));
    valueCopy.removeMember("index");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "outputType");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.outputType, value["outputType"]));
    valueCopy.removeMember("outputType");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"]));
    valueCopy.removeMember("name");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::AudioOutput::Structs::OutputInfoStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.index);
    ComplexArgumentParser::Finalize(request.outputType);
    ComplexArgumentParser::Finalize(request.name);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ApplicationLauncher::Structs::ApplicationStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ApplicationStruct.catalogVendorID", "catalogVendorID",
                                                                  value.isMember("catalogVendorID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ApplicationStruct.applicationID", "applicationID",
                                                                  value.isMember("applicationID")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "catalogVendorID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.catalogVendorID, value["catalogVendorID"]));
    valueCopy.removeMember("catalogVendorID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "applicationID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.applicationID, value["applicationID"]));
    valueCopy.removeMember("applicationID");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ApplicationLauncher::Structs::ApplicationStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.catalogVendorID);
    ComplexArgumentParser::Finalize(request.applicationID);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ApplicationLauncher::Structs::ApplicationEPStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ApplicationEPStruct.application", "application", value.isMember("application")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "application");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.application, value["application"]));
    valueCopy.removeMember("application");

    if (value.isMember("endpoint"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpoint");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpoint, value["endpoint"]));
    }
    valueCopy.removeMember("endpoint");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ApplicationLauncher::Structs::ApplicationEPStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.application);
    ComplexArgumentParser::Finalize(request.endpoint);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ApplicationBasic::Structs::ApplicationStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ApplicationStruct.catalogVendorID", "catalogVendorID",
                                                                  value.isMember("catalogVendorID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ApplicationStruct.applicationID", "applicationID",
                                                                  value.isMember("applicationID")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "catalogVendorID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.catalogVendorID, value["catalogVendorID"]));
    valueCopy.removeMember("catalogVendorID");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "applicationID");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.applicationID, value["applicationID"]));
    valueCopy.removeMember("applicationID");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::ApplicationBasic::Structs::ApplicationStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.catalogVendorID);
    ComplexArgumentParser::Finalize(request.applicationID);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SimpleStruct.a", "a", value.isMember("a")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SimpleStruct.b", "b", value.isMember("b")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SimpleStruct.c", "c", value.isMember("c")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SimpleStruct.d", "d", value.isMember("d")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SimpleStruct.e", "e", value.isMember("e")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SimpleStruct.f", "f", value.isMember("f")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SimpleStruct.g", "g", value.isMember("g")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SimpleStruct.h", "h", value.isMember("h")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "a");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.a, value["a"]));
    valueCopy.removeMember("a");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "b");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.b, value["b"]));
    valueCopy.removeMember("b");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "c");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.c, value["c"]));
    valueCopy.removeMember("c");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "d");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.d, value["d"]));
    valueCopy.removeMember("d");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "e");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.e, value["e"]));
    valueCopy.removeMember("e");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "f");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.f, value["f"]));
    valueCopy.removeMember("f");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "g");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.g, value["g"]));
    valueCopy.removeMember("g");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "h");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.h, value["h"]));
    valueCopy.removeMember("h");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.a);
    ComplexArgumentParser::Finalize(request.b);
    ComplexArgumentParser::Finalize(request.c);
    ComplexArgumentParser::Finalize(request.d);
    ComplexArgumentParser::Finalize(request.e);
    ComplexArgumentParser::Finalize(request.f);
    ComplexArgumentParser::Finalize(request.g);
    ComplexArgumentParser::Finalize(request.h);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::UnitTesting::Structs::TestFabricScoped::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TestFabricScoped.fabricSensitiveInt8u", "fabricSensitiveInt8u",
                                                                  value.isMember("fabricSensitiveInt8u")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TestFabricScoped.nullableFabricSensitiveInt8u",
                                                                  "nullableFabricSensitiveInt8u",
                                                                  value.isMember("nullableFabricSensitiveInt8u")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist(
        "TestFabricScoped.fabricSensitiveCharString", "fabricSensitiveCharString", value.isMember("fabricSensitiveCharString")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TestFabricScoped.fabricSensitiveStruct", "fabricSensitiveStruct",
                                                                  value.isMember("fabricSensitiveStruct")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist(
        "TestFabricScoped.fabricSensitiveInt8uList", "fabricSensitiveInt8uList", value.isMember("fabricSensitiveInt8uList")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricSensitiveInt8u");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.fabricSensitiveInt8u, value["fabricSensitiveInt8u"]));
    valueCopy.removeMember("fabricSensitiveInt8u");

    if (value.isMember("optionalFabricSensitiveInt8u"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "optionalFabricSensitiveInt8u");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.optionalFabricSensitiveInt8u,
                                                          value["optionalFabricSensitiveInt8u"]));
    }
    valueCopy.removeMember("optionalFabricSensitiveInt8u");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nullableFabricSensitiveInt8u");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.nullableFabricSensitiveInt8u, value["nullableFabricSensitiveInt8u"]));
    valueCopy.removeMember("nullableFabricSensitiveInt8u");

    if (value.isMember("nullableOptionalFabricSensitiveInt8u"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nullableOptionalFabricSensitiveInt8u");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.nullableOptionalFabricSensitiveInt8u,
                                                          value["nullableOptionalFabricSensitiveInt8u"]));
    }
    valueCopy.removeMember("nullableOptionalFabricSensitiveInt8u");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricSensitiveCharString");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.fabricSensitiveCharString, value["fabricSensitiveCharString"]));
    valueCopy.removeMember("fabricSensitiveCharString");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricSensitiveStruct");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.fabricSensitiveStruct, value["fabricSensitiveStruct"]));
    valueCopy.removeMember("fabricSensitiveStruct");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricSensitiveInt8uList");
    ReturnErrorOnFailure(
        ComplexArgumentParser::Setup(labelWithMember, request.fabricSensitiveInt8uList, value["fabricSensitiveInt8uList"]));
    valueCopy.removeMember("fabricSensitiveInt8uList");

    if (value.isMember("fabricIndex"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"]));
    }
    valueCopy.removeMember("fabricIndex");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::UnitTesting::Structs::TestFabricScoped::Type & request)
{
    ComplexArgumentParser::Finalize(request.fabricSensitiveInt8u);
    ComplexArgumentParser::Finalize(request.optionalFabricSensitiveInt8u);
    ComplexArgumentParser::Finalize(request.nullableFabricSensitiveInt8u);
    ComplexArgumentParser::Finalize(request.nullableOptionalFabricSensitiveInt8u);
    ComplexArgumentParser::Finalize(request.fabricSensitiveCharString);
    ComplexArgumentParser::Finalize(request.fabricSensitiveStruct);
    ComplexArgumentParser::Finalize(request.fabricSensitiveInt8uList);
    ComplexArgumentParser::Finalize(request.fabricIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::UnitTesting::Structs::NullablesAndOptionalsStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NullablesAndOptionalsStruct.nullableInt", "nullableInt",
                                                                  value.isMember("nullableInt")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NullablesAndOptionalsStruct.nullableString", "nullableString",
                                                                  value.isMember("nullableString")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NullablesAndOptionalsStruct.nullableStruct", "nullableStruct",
                                                                  value.isMember("nullableStruct")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NullablesAndOptionalsStruct.nullableList", "nullableList",
                                                                  value.isMember("nullableList")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nullableInt");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.nullableInt, value["nullableInt"]));
    valueCopy.removeMember("nullableInt");

    if (value.isMember("optionalInt"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "optionalInt");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.optionalInt, value["optionalInt"]));
    }
    valueCopy.removeMember("optionalInt");

    if (value.isMember("nullableOptionalInt"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nullableOptionalInt");
        ReturnErrorOnFailure(
            ComplexArgumentParser::Setup(labelWithMember, request.nullableOptionalInt, value["nullableOptionalInt"]));
    }
    valueCopy.removeMember("nullableOptionalInt");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nullableString");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.nullableString, value["nullableString"]));
    valueCopy.removeMember("nullableString");

    if (value.isMember("optionalString"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "optionalString");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.optionalString, value["optionalString"]));
    }
    valueCopy.removeMember("optionalString");

    if (value.isMember("nullableOptionalString"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nullableOptionalString");
        ReturnErrorOnFailure(
            ComplexArgumentParser::Setup(labelWithMember, request.nullableOptionalString, value["nullableOptionalString"]));
    }
    valueCopy.removeMember("nullableOptionalString");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nullableStruct");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.nullableStruct, value["nullableStruct"]));
    valueCopy.removeMember("nullableStruct");

    if (value.isMember("optionalStruct"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "optionalStruct");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.optionalStruct, value["optionalStruct"]));
    }
    valueCopy.removeMember("optionalStruct");

    if (value.isMember("nullableOptionalStruct"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nullableOptionalStruct");
        ReturnErrorOnFailure(
            ComplexArgumentParser::Setup(labelWithMember, request.nullableOptionalStruct, value["nullableOptionalStruct"]));
    }
    valueCopy.removeMember("nullableOptionalStruct");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nullableList");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.nullableList, value["nullableList"]));
    valueCopy.removeMember("nullableList");

    if (value.isMember("optionalList"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "optionalList");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.optionalList, value["optionalList"]));
    }
    valueCopy.removeMember("optionalList");

    if (value.isMember("nullableOptionalList"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "nullableOptionalList");
        ReturnErrorOnFailure(
            ComplexArgumentParser::Setup(labelWithMember, request.nullableOptionalList, value["nullableOptionalList"]));
    }
    valueCopy.removeMember("nullableOptionalList");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::UnitTesting::Structs::NullablesAndOptionalsStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.nullableInt);
    ComplexArgumentParser::Finalize(request.optionalInt);
    ComplexArgumentParser::Finalize(request.nullableOptionalInt);
    ComplexArgumentParser::Finalize(request.nullableString);
    ComplexArgumentParser::Finalize(request.optionalString);
    ComplexArgumentParser::Finalize(request.nullableOptionalString);
    ComplexArgumentParser::Finalize(request.nullableStruct);
    ComplexArgumentParser::Finalize(request.optionalStruct);
    ComplexArgumentParser::Finalize(request.nullableOptionalStruct);
    ComplexArgumentParser::Finalize(request.nullableList);
    ComplexArgumentParser::Finalize(request.optionalList);
    ComplexArgumentParser::Finalize(request.nullableOptionalList);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::UnitTesting::Structs::NestedStruct::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NestedStruct.a", "a", value.isMember("a")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NestedStruct.b", "b", value.isMember("b")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NestedStruct.c", "c", value.isMember("c")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "a");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.a, value["a"]));
    valueCopy.removeMember("a");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "b");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.b, value["b"]));
    valueCopy.removeMember("b");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "c");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.c, value["c"]));
    valueCopy.removeMember("c");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::UnitTesting::Structs::NestedStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.a);
    ComplexArgumentParser::Finalize(request.b);
    ComplexArgumentParser::Finalize(request.c);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::UnitTesting::Structs::NestedStructList::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NestedStructList.a", "a", value.isMember("a")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NestedStructList.b", "b", value.isMember("b")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NestedStructList.c", "c", value.isMember("c")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NestedStructList.d", "d", value.isMember("d")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NestedStructList.e", "e", value.isMember("e")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NestedStructList.f", "f", value.isMember("f")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NestedStructList.g", "g", value.isMember("g")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "a");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.a, value["a"]));
    valueCopy.removeMember("a");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "b");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.b, value["b"]));
    valueCopy.removeMember("b");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "c");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.c, value["c"]));
    valueCopy.removeMember("c");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "d");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.d, value["d"]));
    valueCopy.removeMember("d");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "e");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.e, value["e"]));
    valueCopy.removeMember("e");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "f");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.f, value["f"]));
    valueCopy.removeMember("f");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "g");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.g, value["g"]));
    valueCopy.removeMember("g");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::UnitTesting::Structs::NestedStructList::Type & request)
{
    ComplexArgumentParser::Finalize(request.a);
    ComplexArgumentParser::Finalize(request.b);
    ComplexArgumentParser::Finalize(request.c);
    ComplexArgumentParser::Finalize(request.d);
    ComplexArgumentParser::Finalize(request.e);
    ComplexArgumentParser::Finalize(request.f);
    ComplexArgumentParser::Finalize(request.g);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::UnitTesting::Structs::DoubleNestedStructList::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("DoubleNestedStructList.a", "a", value.isMember("a")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "a");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.a, value["a"]));
    valueCopy.removeMember("a");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::UnitTesting::Structs::DoubleNestedStructList::Type & request)
{
    ComplexArgumentParser::Finalize(request.a);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::UnitTesting::Structs::TestListStructOctet::Type & request,
                                        Json::Value & value)
{
    VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT);

    // Copy to track which members we already processed.
    Json::Value valueCopy(value);

    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("TestListStructOctet.member1", "member1", value.isMember("member1")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("TestListStructOctet.member2", "member2", value.isMember("member2")));

    char labelWithMember[kMaxLabelLength];
    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "member1");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.member1, value["member1"]));
    valueCopy.removeMember("member1");

    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "member2");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.member2, value["member2"]));
    valueCopy.removeMember("member2");

    return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy);
}

void ComplexArgumentParser::Finalize(chip::app::Clusters::UnitTesting::Structs::TestListStructOctet::Type & request)
{
    ComplexArgumentParser::Finalize(request.member1);
    ComplexArgumentParser::Finalize(request.member2);
}
