/*
 *
 *    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.tempLevel", "tempLevel", value.isMember("tempLevel")));

    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, "tempLevel");
    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.tempLevel, value["tempLevel"]));
    valueCopy.removeMember("tempLevel");

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

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

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);
}
