/*
 *
 *    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::detail::Structs::ModeTagStruct::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("ModeTagStruct.value", "value", value.isMember("value")));

    char labelWithMember[kMaxLabelLength];
    if (value.isMember("mfgCode"))
    {
        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::detail::Structs::ModeTagStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.mfgCode);
    ComplexArgumentParser::Finalize(request.value);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::detail::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.modeTags", "modeTags", value.isMember("modeTags")));

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

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

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

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::detail::Structs::MeasurementAccuracyRangeStruct::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("MeasurementAccuracyRangeStruct.rangeMin", "rangeMin",
                                                                  value.isMember("rangeMin")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MeasurementAccuracyRangeStruct.rangeMax", "rangeMax",
                                                                  value.isMember("rangeMax")));

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

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

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

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::MeasurementAccuracyRangeStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.rangeMin);
    ComplexArgumentParser::Finalize(request.rangeMax);
    ComplexArgumentParser::Finalize(request.percentMax);
    ComplexArgumentParser::Finalize(request.percentMin);
    ComplexArgumentParser::Finalize(request.percentTypical);
    ComplexArgumentParser::Finalize(request.fixedMax);
    ComplexArgumentParser::Finalize(request.fixedMin);
    ComplexArgumentParser::Finalize(request.fixedTypical);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::detail::Structs::MeasurementAccuracyStruct::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("MeasurementAccuracyStruct.measurementType", "measurementType",
                                                                  value.isMember("measurementType")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("MeasurementAccuracyStruct.measured", "measured", value.isMember("measured")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MeasurementAccuracyStruct.minMeasuredValue", "minMeasuredValue",
                                                                  value.isMember("minMeasuredValue")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MeasurementAccuracyStruct.maxMeasuredValue", "maxMeasuredValue",
                                                                  value.isMember("maxMeasuredValue")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MeasurementAccuracyStruct.accuracyRanges", "accuracyRanges",
                                                                  value.isMember("accuracyRanges")));

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::MeasurementAccuracyStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.measurementType);
    ComplexArgumentParser::Finalize(request.measured);
    ComplexArgumentParser::Finalize(request.minMeasuredValue);
    ComplexArgumentParser::Finalize(request.maxMeasuredValue);
    ComplexArgumentParser::Finalize(request.accuracyRanges);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::detail::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::detail::Structs::ApplicationStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.catalogVendorID);
    ComplexArgumentParser::Finalize(request.applicationID);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::detail::Structs::ErrorStateStruct::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("ErrorStateStruct.errorStateID", "errorStateID", value.isMember("errorStateID")));

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::ErrorStateStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.errorStateID);
    ComplexArgumentParser::Finalize(request.errorStateLabel);
    ComplexArgumentParser::Finalize(request.errorStateDetails);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::detail::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::detail::Structs::LabelStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.label);
    ComplexArgumentParser::Finalize(request.value);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::detail::Structs::OperationalStateStruct::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("OperationalStateStruct.operationalStateID", "operationalStateID",
                                                                  value.isMember("operationalStateID")));

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::OperationalStateStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.operationalStateID);
    ComplexArgumentParser::Finalize(request.operationalStateLabel);
}

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::Descriptor::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.namespaceID", "namespaceID", value.isMember("namespaceID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SemanticTagStruct.tag", "tag", value.isMember("tag")));

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.mfgCode);
    ComplexArgumentParser::Finalize(request.namespaceID);
    ComplexArgumentParser::Finalize(request.tag);
    ComplexArgumentParser::Finalize(request.label);
}

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::AccessControlTargetStruct::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("AccessControlTargetStruct.cluster", "cluster", value.isMember("cluster")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("AccessControlTargetStruct.endpoint", "endpoint", value.isMember("endpoint")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("AccessControlTargetStruct.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::AccessControlTargetStruct::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::NetworkInfoStruct::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("NetworkInfoStruct.networkID", "networkID", value.isMember("networkID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("NetworkInfoStruct.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");

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

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

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

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

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::NetworkCommissioning::Structs::ThreadInterfaceScanResultStruct::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("ThreadInterfaceScanResultStruct.panId", "panId", value.isMember("panId")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResultStruct.extendedPanId", "extendedPanId",
                                                                  value.isMember("extendedPanId")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResultStruct.networkName", "networkName",
                                                                  value.isMember("networkName")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResultStruct.channel", "channel", value.isMember("channel")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResultStruct.version", "version", value.isMember("version")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResultStruct.extendedAddress",
                                                                  "extendedAddress", value.isMember("extendedAddress")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResultStruct.rssi", "rssi", value.isMember("rssi")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ThreadInterfaceScanResultStruct.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::ThreadInterfaceScanResultStruct::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::WiFiInterfaceScanResultStruct::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("WiFiInterfaceScanResultStruct.security", "security", value.isMember("security")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("WiFiInterfaceScanResultStruct.ssid", "ssid", value.isMember("ssid")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("WiFiInterfaceScanResultStruct.bssid", "bssid", value.isMember("bssid")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("WiFiInterfaceScanResultStruct.channel", "channel", value.isMember("channel")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("WiFiInterfaceScanResultStruct.wiFiBand", "wiFiBand", value.isMember("wiFiBand")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("WiFiInterfaceScanResultStruct.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::WiFiInterfaceScanResultStruct::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::NeighborTableStruct::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("NeighborTableStruct.extAddress", "extAddress", value.isMember("extAddress")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.age", "age", value.isMember("age")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.rloc16", "rloc16", value.isMember("rloc16")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.linkFrameCounter", "linkFrameCounter",
                                                                  value.isMember("linkFrameCounter")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.mleFrameCounter", "mleFrameCounter",
                                                                  value.isMember("mleFrameCounter")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.lqi", "lqi", value.isMember("lqi")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.averageRssi", "averageRssi", value.isMember("averageRssi")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.lastRssi", "lastRssi", value.isMember("lastRssi")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.frameErrorRate", "frameErrorRate",
                                                                  value.isMember("frameErrorRate")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.messageErrorRate", "messageErrorRate",
                                                                  value.isMember("messageErrorRate")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.rxOnWhenIdle", "rxOnWhenIdle",
                                                                  value.isMember("rxOnWhenIdle")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.fullThreadDevice", "fullThreadDevice",
                                                                  value.isMember("fullThreadDevice")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.fullNetworkData", "fullNetworkData",
                                                                  value.isMember("fullNetworkData")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("NeighborTableStruct.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::NeighborTableStruct::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::RouteTableStruct::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("RouteTableStruct.extAddress", "extAddress", value.isMember("extAddress")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.rloc16", "rloc16", value.isMember("rloc16")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.routerId", "routerId", value.isMember("routerId")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.nextHop", "nextHop", value.isMember("nextHop")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.pathCost", "pathCost", value.isMember("pathCost")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.LQIIn", "LQIIn", value.isMember("LQIIn")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.LQIOut", "LQIOut", value.isMember("LQIOut")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.age", "age", value.isMember("age")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.allocated", "allocated", value.isMember("allocated")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("RouteTableStruct.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::RouteTableStruct::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::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.clientType", "clientType",
                                                                  value.isMember("clientType")));

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

    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.clientType);
    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::ScenesManagement::Structs::AttributeValuePairStruct::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("AttributeValuePairStruct.attributeID", "attributeID",
                                                                  value.isMember("attributeID")));

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

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

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

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

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::ScenesManagement::Structs::AttributeValuePairStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.attributeID);
    ComplexArgumentParser::Finalize(request.valueUnsigned8);
    ComplexArgumentParser::Finalize(request.valueSigned8);
    ComplexArgumentParser::Finalize(request.valueUnsigned16);
    ComplexArgumentParser::Finalize(request.valueSigned16);
    ComplexArgumentParser::Finalize(request.valueUnsigned32);
    ComplexArgumentParser::Finalize(request.valueSigned32);
    ComplexArgumentParser::Finalize(request.valueUnsigned64);
    ComplexArgumentParser::Finalize(request.valueSigned64);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ScenesManagement::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::ScenesManagement::Structs::ExtensionFieldSet::Type & request)
{
    ComplexArgumentParser::Finalize(request.clusterID);
    ComplexArgumentParser::Finalize(request.attributeValueList);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ScenesManagement::Structs::SceneInfoStruct::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("SceneInfoStruct.sceneCount", "sceneCount", value.isMember("sceneCount")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("SceneInfoStruct.currentScene", "currentScene", value.isMember("currentScene")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("SceneInfoStruct.currentGroup", "currentGroup", value.isMember("currentGroup")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("SceneInfoStruct.sceneValid", "sceneValid", value.isMember("sceneValid")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SceneInfoStruct.remainingCapacity", "remainingCapacity",
                                                                  value.isMember("remainingCapacity")));

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

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

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

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

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

    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::ScenesManagement::Structs::SceneInfoStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.sceneCount);
    ComplexArgumentParser::Finalize(request.currentScene);
    ComplexArgumentParser::Finalize(request.currentGroup);
    ComplexArgumentParser::Finalize(request.sceneValid);
    ComplexArgumentParser::Finalize(request.remainingCapacity);
    ComplexArgumentParser::Finalize(request.fabricIndex);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::HepaFilterMonitoring::Structs::ReplacementProductStruct::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(
        "ReplacementProductStruct.productIdentifierType", "productIdentifierType", value.isMember("productIdentifierType")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist(
        "ReplacementProductStruct.productIdentifierValue", "productIdentifierValue", value.isMember("productIdentifierValue")));

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::HepaFilterMonitoring::Structs::ReplacementProductStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.productIdentifierType);
    ComplexArgumentParser::Finalize(request.productIdentifierValue);
}

CHIP_ERROR ComplexArgumentParser::Setup(
    const char * label, chip::app::Clusters::ActivatedCarbonFilterMonitoring::Structs::ReplacementProductStruct::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(
        "ReplacementProductStruct.productIdentifierType", "productIdentifierType", value.isMember("productIdentifierType")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist(
        "ReplacementProductStruct.productIdentifierValue", "productIdentifierValue", value.isMember("productIdentifierValue")));

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

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::ActivatedCarbonFilterMonitoring::Structs::ReplacementProductStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.productIdentifierType);
    ComplexArgumentParser::Finalize(request.productIdentifierValue);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::ElectricalPowerMeasurement::Structs::HarmonicMeasurementStruct::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("HarmonicMeasurementStruct.order", "order", value.isMember("order")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("HarmonicMeasurementStruct.measurement", "measurement",
                                                                  value.isMember("measurement")));

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

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::ElectricalPowerMeasurement::Structs::HarmonicMeasurementStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.order);
    ComplexArgumentParser::Finalize(request.measurement);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::ElectricalPowerMeasurement::Structs::MeasurementRangeStruct::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("MeasurementRangeStruct.measurementType", "measurementType",
                                                                  value.isMember("measurementType")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MeasurementRangeStruct.min", "min", value.isMember("min")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MeasurementRangeStruct.max", "max", value.isMember("max")));

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

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

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

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

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

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

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::ElectricalPowerMeasurement::Structs::MeasurementRangeStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.measurementType);
    ComplexArgumentParser::Finalize(request.min);
    ComplexArgumentParser::Finalize(request.max);
    ComplexArgumentParser::Finalize(request.startTimestamp);
    ComplexArgumentParser::Finalize(request.endTimestamp);
    ComplexArgumentParser::Finalize(request.minTimestamp);
    ComplexArgumentParser::Finalize(request.maxTimestamp);
    ComplexArgumentParser::Finalize(request.startSystime);
    ComplexArgumentParser::Finalize(request.endSystime);
    ComplexArgumentParser::Finalize(request.minSystime);
    ComplexArgumentParser::Finalize(request.maxSystime);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::ElectricalEnergyMeasurement::Structs::CumulativeEnergyResetStruct::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("importedResetTimestamp"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "importedResetTimestamp");
        ReturnErrorOnFailure(
            ComplexArgumentParser::Setup(labelWithMember, request.importedResetTimestamp, value["importedResetTimestamp"]));
    }
    valueCopy.removeMember("importedResetTimestamp");

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

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

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::ElectricalEnergyMeasurement::Structs::CumulativeEnergyResetStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.importedResetTimestamp);
    ComplexArgumentParser::Finalize(request.exportedResetTimestamp);
    ComplexArgumentParser::Finalize(request.importedResetSystime);
    ComplexArgumentParser::Finalize(request.exportedResetSystime);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::ElectricalEnergyMeasurement::Structs::EnergyMeasurementStruct::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("EnergyMeasurementStruct.energy", "energy", value.isMember("energy")));

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::ElectricalEnergyMeasurement::Structs::EnergyMeasurementStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.energy);
    ComplexArgumentParser::Finalize(request.startTimestamp);
    ComplexArgumentParser::Finalize(request.endTimestamp);
    ComplexArgumentParser::Finalize(request.startSystime);
    ComplexArgumentParser::Finalize(request.endSystime);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::DemandResponseLoadControl::Structs::HeatingSourceControlStruct::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("HeatingSourceControlStruct.heatingSource", "heatingSource",
                                                                  value.isMember("heatingSource")));

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::DemandResponseLoadControl::Structs::HeatingSourceControlStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.heatingSource);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::DemandResponseLoadControl::Structs::PowerSavingsControlStruct::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("PowerSavingsControlStruct.powerSavings", "powerSavings",
                                                                  value.isMember("powerSavings")));

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::DemandResponseLoadControl::Structs::PowerSavingsControlStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.powerSavings);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::DemandResponseLoadControl::Structs::DutyCycleControlStruct::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("DutyCycleControlStruct.dutyCycle", "dutyCycle", value.isMember("dutyCycle")));

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::DemandResponseLoadControl::Structs::DutyCycleControlStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.dutyCycle);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::DemandResponseLoadControl::Structs::AverageLoadControlStruct::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("AverageLoadControlStruct.loadAdjustment", "loadAdjustment",
                                                                  value.isMember("loadAdjustment")));

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::DemandResponseLoadControl::Structs::AverageLoadControlStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.loadAdjustment);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::DemandResponseLoadControl::Structs::TemperatureControlStruct::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("coolingTempOffset"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "coolingTempOffset");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.coolingTempOffset, value["coolingTempOffset"]));
    }
    valueCopy.removeMember("coolingTempOffset");

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

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

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::DemandResponseLoadControl::Structs::TemperatureControlStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.coolingTempOffset);
    ComplexArgumentParser::Finalize(request.heatingtTempOffset);
    ComplexArgumentParser::Finalize(request.coolingTempSetpoint);
    ComplexArgumentParser::Finalize(request.heatingTempSetpoint);
}

CHIP_ERROR ComplexArgumentParser::Setup(
    const char * label, chip::app::Clusters::DemandResponseLoadControl::Structs::LoadControlEventTransitionStruct::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("LoadControlEventTransitionStruct.duration", "duration",
                                                                  value.isMember("duration")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("LoadControlEventTransitionStruct.control", "control", value.isMember("control")));

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

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

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::DemandResponseLoadControl::Structs::LoadControlEventTransitionStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.duration);
    ComplexArgumentParser::Finalize(request.control);
    ComplexArgumentParser::Finalize(request.temperatureControl);
    ComplexArgumentParser::Finalize(request.averageLoadControl);
    ComplexArgumentParser::Finalize(request.dutyCycleControl);
    ComplexArgumentParser::Finalize(request.powerSavingsControl);
    ComplexArgumentParser::Finalize(request.heatingSourceControl);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::DemandResponseLoadControl::Structs::LoadControlEventStruct::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("LoadControlEventStruct.eventID", "eventID", value.isMember("eventID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("LoadControlEventStruct.programID", "programID", value.isMember("programID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("LoadControlEventStruct.control", "control", value.isMember("control")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LoadControlEventStruct.deviceClass", "deviceClass",
                                                                  value.isMember("deviceClass")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LoadControlEventStruct.criticality", "criticality",
                                                                  value.isMember("criticality")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("LoadControlEventStruct.startTime", "startTime", value.isMember("startTime")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LoadControlEventStruct.transitions", "transitions",
                                                                  value.isMember("transitions")));

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

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

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

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::DemandResponseLoadControl::Structs::LoadControlEventStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.eventID);
    ComplexArgumentParser::Finalize(request.programID);
    ComplexArgumentParser::Finalize(request.control);
    ComplexArgumentParser::Finalize(request.deviceClass);
    ComplexArgumentParser::Finalize(request.enrollmentGroup);
    ComplexArgumentParser::Finalize(request.criticality);
    ComplexArgumentParser::Finalize(request.startTime);
    ComplexArgumentParser::Finalize(request.transitions);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::DemandResponseLoadControl::Structs::LoadControlProgramStruct::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("LoadControlProgramStruct.programID", "programID", value.isMember("programID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LoadControlProgramStruct.name", "name", value.isMember("name")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LoadControlProgramStruct.enrollmentGroup", "enrollmentGroup",
                                                                  value.isMember("enrollmentGroup")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LoadControlProgramStruct.randomStartMinutes",
                                                                  "randomStartMinutes", value.isMember("randomStartMinutes")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist(
        "LoadControlProgramStruct.randomDurationMinutes", "randomDurationMinutes", value.isMember("randomDurationMinutes")));

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

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

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

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::DemandResponseLoadControl::Structs::LoadControlProgramStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.programID);
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.enrollmentGroup);
    ComplexArgumentParser::Finalize(request.randomStartMinutes);
    ComplexArgumentParser::Finalize(request.randomDurationMinutes);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Messages::Structs::MessageResponseOptionStruct::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("messageResponseID"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "messageResponseID");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.messageResponseID, value["messageResponseID"]));
    }
    valueCopy.removeMember("messageResponseID");

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Messages::Structs::MessageResponseOptionStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.messageResponseID);
    ComplexArgumentParser::Finalize(request.label);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Messages::Structs::MessageStruct::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("MessageStruct.messageID", "messageID", value.isMember("messageID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("MessageStruct.priority", "priority", value.isMember("priority")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MessageStruct.messageControl", "messageControl",
                                                                  value.isMember("messageControl")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("MessageStruct.startTime", "startTime", value.isMember("startTime")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("MessageStruct.duration", "duration", value.isMember("duration")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("MessageStruct.messageText", "messageText", value.isMember("messageText")));

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

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

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Messages::Structs::MessageStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.messageID);
    ComplexArgumentParser::Finalize(request.priority);
    ComplexArgumentParser::Finalize(request.messageControl);
    ComplexArgumentParser::Finalize(request.startTime);
    ComplexArgumentParser::Finalize(request.duration);
    ComplexArgumentParser::Finalize(request.messageText);
    ComplexArgumentParser::Finalize(request.responses);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::DeviceEnergyManagement::Structs::CostStruct::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("CostStruct.costType", "costType", value.isMember("costType")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("CostStruct.value", "value", value.isMember("value")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("CostStruct.decimalPoints", "decimalPoints", value.isMember("decimalPoints")));

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::DeviceEnergyManagement::Structs::CostStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.costType);
    ComplexArgumentParser::Finalize(request.value);
    ComplexArgumentParser::Finalize(request.decimalPoints);
    ComplexArgumentParser::Finalize(request.currency);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::DeviceEnergyManagement::Structs::PowerAdjustStruct::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("PowerAdjustStruct.minPower", "minPower", value.isMember("minPower")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("PowerAdjustStruct.maxPower", "maxPower", value.isMember("maxPower")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("PowerAdjustStruct.minDuration", "minDuration", value.isMember("minDuration")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("PowerAdjustStruct.maxDuration", "maxDuration", value.isMember("maxDuration")));

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::DeviceEnergyManagement::Structs::PowerAdjustStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.minPower);
    ComplexArgumentParser::Finalize(request.maxPower);
    ComplexArgumentParser::Finalize(request.minDuration);
    ComplexArgumentParser::Finalize(request.maxDuration);
}

CHIP_ERROR
ComplexArgumentParser::Setup(const char * label,
                             chip::app::Clusters::DeviceEnergyManagement::Structs::PowerAdjustCapabilityStruct::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(
        "PowerAdjustCapabilityStruct.powerAdjustCapability", "powerAdjustCapability", value.isMember("powerAdjustCapability")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("PowerAdjustCapabilityStruct.cause", "cause", value.isMember("cause")));

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

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

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

void ComplexArgumentParser::Finalize(
    chip::app::Clusters::DeviceEnergyManagement::Structs::PowerAdjustCapabilityStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.powerAdjustCapability);
    ComplexArgumentParser::Finalize(request.cause);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::DeviceEnergyManagement::Structs::SlotStruct::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("SlotStruct.minDuration", "minDuration", value.isMember("minDuration")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("SlotStruct.maxDuration", "maxDuration", value.isMember("maxDuration")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SlotStruct.defaultDuration", "defaultDuration",
                                                                  value.isMember("defaultDuration")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SlotStruct.elapsedSlotTime", "elapsedSlotTime",
                                                                  value.isMember("elapsedSlotTime")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("SlotStruct.remainingSlotTime", "remainingSlotTime",
                                                                  value.isMember("remainingSlotTime")));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::DeviceEnergyManagement::Structs::SlotStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.minDuration);
    ComplexArgumentParser::Finalize(request.maxDuration);
    ComplexArgumentParser::Finalize(request.defaultDuration);
    ComplexArgumentParser::Finalize(request.elapsedSlotTime);
    ComplexArgumentParser::Finalize(request.remainingSlotTime);
    ComplexArgumentParser::Finalize(request.slotIsPausable);
    ComplexArgumentParser::Finalize(request.minPauseDuration);
    ComplexArgumentParser::Finalize(request.maxPauseDuration);
    ComplexArgumentParser::Finalize(request.manufacturerESAState);
    ComplexArgumentParser::Finalize(request.nominalPower);
    ComplexArgumentParser::Finalize(request.minPower);
    ComplexArgumentParser::Finalize(request.maxPower);
    ComplexArgumentParser::Finalize(request.nominalEnergy);
    ComplexArgumentParser::Finalize(request.costs);
    ComplexArgumentParser::Finalize(request.minPowerAdjustment);
    ComplexArgumentParser::Finalize(request.maxPowerAdjustment);
    ComplexArgumentParser::Finalize(request.minDurationAdjustment);
    ComplexArgumentParser::Finalize(request.maxDurationAdjustment);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::DeviceEnergyManagement::Structs::ForecastStruct::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("ForecastStruct.forecastID", "forecastID", value.isMember("forecastID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ForecastStruct.activeSlotNumber", "activeSlotNumber",
                                                                  value.isMember("activeSlotNumber")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ForecastStruct.startTime", "startTime", value.isMember("startTime")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ForecastStruct.endTime", "endTime", value.isMember("endTime")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ForecastStruct.isPausable", "isPausable", value.isMember("isPausable")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ForecastStruct.slots", "slots", value.isMember("slots")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ForecastStruct.forecastUpdateReason", "forecastUpdateReason",
                                                                  value.isMember("forecastUpdateReason")));

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

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

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

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

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::DeviceEnergyManagement::Structs::ForecastStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.forecastID);
    ComplexArgumentParser::Finalize(request.activeSlotNumber);
    ComplexArgumentParser::Finalize(request.startTime);
    ComplexArgumentParser::Finalize(request.endTime);
    ComplexArgumentParser::Finalize(request.earliestStartTime);
    ComplexArgumentParser::Finalize(request.latestEndTime);
    ComplexArgumentParser::Finalize(request.isPausable);
    ComplexArgumentParser::Finalize(request.slots);
    ComplexArgumentParser::Finalize(request.forecastUpdateReason);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::DeviceEnergyManagement::Structs::ConstraintsStruct::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("ConstraintsStruct.startTime", "startTime", value.isMember("startTime")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ConstraintsStruct.duration", "duration", value.isMember("duration")));

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::DeviceEnergyManagement::Structs::ConstraintsStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.startTime);
    ComplexArgumentParser::Finalize(request.duration);
    ComplexArgumentParser::Finalize(request.nominalPower);
    ComplexArgumentParser::Finalize(request.maximumEnergy);
    ComplexArgumentParser::Finalize(request.loadControl);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::DeviceEnergyManagement::Structs::SlotAdjustmentStruct::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("SlotAdjustmentStruct.slotIndex", "slotIndex", value.isMember("slotIndex")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("SlotAdjustmentStruct.duration", "duration", value.isMember("duration")));

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::DeviceEnergyManagement::Structs::SlotAdjustmentStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.slotIndex);
    ComplexArgumentParser::Finalize(request.nominalPower);
    ComplexArgumentParser::Finalize(request.duration);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::EnergyEvse::Structs::ChargingTargetStruct::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("ChargingTargetStruct.targetTimeMinutesPastMidnight",
                                                                  "targetTimeMinutesPastMidnight",
                                                                  value.isMember("targetTimeMinutesPastMidnight")));

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::EnergyEvse::Structs::ChargingTargetStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.targetTimeMinutesPastMidnight);
    ComplexArgumentParser::Finalize(request.targetSoC);
    ComplexArgumentParser::Finalize(request.addedEnergy);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::EnergyEvse::Structs::ChargingTargetScheduleStruct::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("ChargingTargetScheduleStruct.dayOfWeekForSequence",
                                                                  "dayOfWeekForSequence", value.isMember("dayOfWeekForSequence")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ChargingTargetScheduleStruct.chargingTargets", "chargingTargets",
                                                                  value.isMember("chargingTargets")));

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::EnergyEvse::Structs::ChargingTargetScheduleStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.dayOfWeekForSequence);
    ComplexArgumentParser::Finalize(request.chargingTargets);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::EnergyPreference::Structs::BalanceStruct::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("BalanceStruct.step", "step", value.isMember("step")));

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::EnergyPreference::Structs::BalanceStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.step);
    ComplexArgumentParser::Finalize(request.label);
}

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::ServiceArea::Structs::HomeLocationStruct::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("HomeLocationStruct.locationName", "locationName",
                                                                  value.isMember("locationName")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("HomeLocationStruct.floorNumber", "floorNumber", value.isMember("floorNumber")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("HomeLocationStruct.areaType", "areaType", value.isMember("areaType")));

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.locationName);
    ComplexArgumentParser::Finalize(request.floorNumber);
    ComplexArgumentParser::Finalize(request.areaType);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::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("LocationInfoStruct.locationInfo", "locationInfo",
                                                                  value.isMember("locationInfo")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("LocationInfoStruct.landmarkTag", "landmarkTag", value.isMember("landmarkTag")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("LocationInfoStruct.positionTag", "positionTag", value.isMember("positionTag")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("LocationInfoStruct.surfaceTag", "surfaceTag", value.isMember("surfaceTag")));

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.locationInfo);
    ComplexArgumentParser::Finalize(request.landmarkTag);
    ComplexArgumentParser::Finalize(request.positionTag);
    ComplexArgumentParser::Finalize(request.surfaceTag);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ServiceArea::Structs::LocationStruct::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("LocationStruct.locationID", "locationID", value.isMember("locationID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LocationStruct.mapID", "mapID", value.isMember("mapID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("LocationStruct.locationInfo", "locationInfo", value.isMember("locationInfo")));

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::LocationStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.locationID);
    ComplexArgumentParser::Finalize(request.mapID);
    ComplexArgumentParser::Finalize(request.locationInfo);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::MapStruct::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("MapStruct.mapID", "mapID", value.isMember("mapID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MapStruct.name", "name", value.isMember("name")));

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

    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::ServiceArea::Structs::MapStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.mapID);
    ComplexArgumentParser::Finalize(request.name);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ServiceArea::Structs::ProgressStruct::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("ProgressStruct.locationID", "locationID", value.isMember("locationID")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ProgressStruct.status", "status", value.isMember("status")));

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::ProgressStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.locationID);
    ComplexArgumentParser::Finalize(request.status);
    ComplexArgumentParser::Finalize(request.totalOperationalTime);
    ComplexArgumentParser::Finalize(request.estimatedTime);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Thermostat::Structs::ScheduleTransitionStruct::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("ScheduleTransitionStruct.dayOfWeek", "dayOfWeek", value.isMember("dayOfWeek")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ScheduleTransitionStruct.transitionTime", "transitionTime",
                                                                  value.isMember("transitionTime")));

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

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

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

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Thermostat::Structs::ScheduleTransitionStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.dayOfWeek);
    ComplexArgumentParser::Finalize(request.transitionTime);
    ComplexArgumentParser::Finalize(request.presetHandle);
    ComplexArgumentParser::Finalize(request.systemMode);
    ComplexArgumentParser::Finalize(request.coolingSetpoint);
    ComplexArgumentParser::Finalize(request.heatingSetpoint);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Thermostat::Structs::ScheduleStruct::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("ScheduleStruct.scheduleHandle", "scheduleHandle",
                                                                  value.isMember("scheduleHandle")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ScheduleStruct.systemMode", "systemMode", value.isMember("systemMode")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ScheduleStruct.transitions", "transitions", value.isMember("transitions")));

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

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

    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("presetHandle"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "presetHandle");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.presetHandle, value["presetHandle"]));
    }
    valueCopy.removeMember("presetHandle");

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Thermostat::Structs::ScheduleStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.scheduleHandle);
    ComplexArgumentParser::Finalize(request.systemMode);
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.presetHandle);
    ComplexArgumentParser::Finalize(request.transitions);
    ComplexArgumentParser::Finalize(request.builtIn);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Thermostat::Structs::PresetStruct::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("PresetStruct.presetHandle", "presetHandle", value.isMember("presetHandle")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("PresetStruct.presetScenario", "presetScenario",
                                                                  value.isMember("presetScenario")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("PresetStruct.builtIn", "builtIn", value.isMember("builtIn")));

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

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

    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("coolingSetpoint"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "coolingSetpoint");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.coolingSetpoint, value["coolingSetpoint"]));
    }
    valueCopy.removeMember("coolingSetpoint");

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Thermostat::Structs::PresetStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.presetHandle);
    ComplexArgumentParser::Finalize(request.presetScenario);
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.coolingSetpoint);
    ComplexArgumentParser::Finalize(request.heatingSetpoint);
    ComplexArgumentParser::Finalize(request.builtIn);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Thermostat::Structs::PresetTypeStruct::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("PresetTypeStruct.presetScenario", "presetScenario",
                                                                  value.isMember("presetScenario")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("PresetTypeStruct.numberOfPresets", "numberOfPresets",
                                                                  value.isMember("numberOfPresets")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("PresetTypeStruct.presetTypeFeatures", "presetTypeFeatures",
                                                                  value.isMember("presetTypeFeatures")));

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Thermostat::Structs::PresetTypeStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.presetScenario);
    ComplexArgumentParser::Finalize(request.numberOfPresets);
    ComplexArgumentParser::Finalize(request.presetTypeFeatures);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Thermostat::Structs::QueuedPresetStruct::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("QueuedPresetStruct.presetHandle", "presetHandle",
                                                                  value.isMember("presetHandle")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("QueuedPresetStruct.transitionTimestamp", "transitionTimestamp",
                                                                  value.isMember("transitionTimestamp")));

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Thermostat::Structs::QueuedPresetStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.presetHandle);
    ComplexArgumentParser::Finalize(request.transitionTimestamp);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Thermostat::Structs::ScheduleTypeStruct::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("ScheduleTypeStruct.systemMode", "systemMode", value.isMember("systemMode")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ScheduleTypeStruct.numberOfSchedules", "numberOfSchedules",
                                                                  value.isMember("numberOfSchedules")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ScheduleTypeStruct.scheduleTypeFeatures", "scheduleTypeFeatures",
                                                                  value.isMember("scheduleTypeFeatures")));

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Thermostat::Structs::ScheduleTypeStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.systemMode);
    ComplexArgumentParser::Finalize(request.numberOfSchedules);
    ComplexArgumentParser::Finalize(request.scheduleTypeFeatures);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Thermostat::Structs::WeeklyScheduleTransitionStruct::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("WeeklyScheduleTransitionStruct.transitionTime", "transitionTime",
                                                                  value.isMember("transitionTime")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("WeeklyScheduleTransitionStruct.heatSetpoint", "heatSetpoint",
                                                                  value.isMember("heatSetpoint")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("WeeklyScheduleTransitionStruct.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::WeeklyScheduleTransitionStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.transitionTime);
    ComplexArgumentParser::Finalize(request.heatSetpoint);
    ComplexArgumentParser::Finalize(request.coolSetpoint);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::OccupancySensing::Structs::HoldTimeLimitsStruct::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("HoldTimeLimitsStruct.holdTimeMin", "holdTimeMin", value.isMember("holdTimeMin")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("HoldTimeLimitsStruct.holdTimeMax", "holdTimeMax", value.isMember("holdTimeMax")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("HoldTimeLimitsStruct.holdTimeDefault", "holdTimeDefault",
                                                                  value.isMember("holdTimeDefault")));

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::OccupancySensing::Structs::HoldTimeLimitsStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.holdTimeMin);
    ComplexArgumentParser::Finalize(request.holdTimeMax);
    ComplexArgumentParser::Finalize(request.holdTimeDefault);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ThreadNetworkDirectory::Structs::ThreadNetworkStruct::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("ThreadNetworkStruct.extendedPanID", "extendedPanID",
                                                                  value.isMember("extendedPanID")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ThreadNetworkStruct.networkName", "networkName", value.isMember("networkName")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ThreadNetworkStruct.channel", "channel", value.isMember("channel")));

    char labelWithMember[kMaxLabelLength];
    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");

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::ThreadNetworkDirectory::Structs::ThreadNetworkStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.extendedPanID);
    ComplexArgumentParser::Finalize(request.networkName);
    ComplexArgumentParser::Finalize(request.channel);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Channel::Structs::ProgramCastStruct::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("ProgramCastStruct.name", "name", value.isMember("name")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ProgramCastStruct.role", "role", value.isMember("role")));

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Channel::Structs::ProgramCastStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.role);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Channel::Structs::ProgramCategoryStruct::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("ProgramCategoryStruct.category", "category", value.isMember("category")));

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Channel::Structs::ProgramCategoryStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.category);
    ComplexArgumentParser::Finalize(request.subCategory);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Channel::Structs::SeriesInfoStruct::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("SeriesInfoStruct.season", "season", value.isMember("season")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("SeriesInfoStruct.episode", "episode", value.isMember("episode")));

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Channel::Structs::SeriesInfoStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.season);
    ComplexArgumentParser::Finalize(request.episode);
}

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

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

    if (value.isMember("type"))
    {
        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::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);
    ComplexArgumentParser::Finalize(request.identifier);
    ComplexArgumentParser::Finalize(request.type);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Channel::Structs::ProgramStruct::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("ProgramStruct.identifier", "identifier", value.isMember("identifier")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ProgramStruct.channel", "channel", value.isMember("channel")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("ProgramStruct.startTime", "startTime", value.isMember("startTime")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ProgramStruct.endTime", "endTime", value.isMember("endTime")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ProgramStruct.title", "title", value.isMember("title")));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    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::Channel::Structs::ProgramStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.identifier);
    ComplexArgumentParser::Finalize(request.channel);
    ComplexArgumentParser::Finalize(request.startTime);
    ComplexArgumentParser::Finalize(request.endTime);
    ComplexArgumentParser::Finalize(request.title);
    ComplexArgumentParser::Finalize(request.subtitle);
    ComplexArgumentParser::Finalize(request.description);
    ComplexArgumentParser::Finalize(request.audioLanguages);
    ComplexArgumentParser::Finalize(request.ratings);
    ComplexArgumentParser::Finalize(request.thumbnailUrl);
    ComplexArgumentParser::Finalize(request.posterArtUrl);
    ComplexArgumentParser::Finalize(request.dvbiUrl);
    ComplexArgumentParser::Finalize(request.releaseDate);
    ComplexArgumentParser::Finalize(request.parentalGuidanceText);
    ComplexArgumentParser::Finalize(request.recordingFlag);
    ComplexArgumentParser::Finalize(request.seriesInfo);
    ComplexArgumentParser::Finalize(request.categoryList);
    ComplexArgumentParser::Finalize(request.castList);
    ComplexArgumentParser::Finalize(request.externalIDList);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Channel::Structs::PageTokenStruct::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("limit"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "limit");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.limit, value["limit"]));
    }
    valueCopy.removeMember("limit");

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Channel::Structs::PageTokenStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.limit);
    ComplexArgumentParser::Finalize(request.after);
    ComplexArgumentParser::Finalize(request.before);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Channel::Structs::ChannelPagingStruct::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("previousToken"))
    {
        snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "previousToken");
        ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.previousToken, value["previousToken"]));
    }
    valueCopy.removeMember("previousToken");

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::Channel::Structs::ChannelPagingStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.previousToken);
    ComplexArgumentParser::Finalize(request.nextToken);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::Channel::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::Channel::Structs::AdditionalInfoStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.name);
    ComplexArgumentParser::Finalize(request.value);
}

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::TrackAttributesStruct::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("TrackAttributesStruct.languageCode", "languageCode",
                                                                  value.isMember("languageCode")));

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::MediaPlayback::Structs::TrackAttributesStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.languageCode);
    ComplexArgumentParser::Finalize(request.displayName);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::MediaPlayback::Structs::TrackStruct::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("TrackStruct.id", "id", value.isMember("id")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TrackStruct.trackAttributes", "trackAttributes",
                                                                  value.isMember("trackAttributes")));

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::MediaPlayback::Structs::TrackStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.id);
    ComplexArgumentParser::Finalize(request.trackAttributes);
}

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::TrackPreferenceStruct::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("TrackPreferenceStruct.languageCode", "languageCode",
                                                                  value.isMember("languageCode")));
    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("TrackPreferenceStruct.audioOutputIndex", "audioOutputIndex",
                                                                  value.isMember("audioOutputIndex")));

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::ContentLauncher::Structs::TrackPreferenceStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.languageCode);
    ComplexArgumentParser::Finalize(request.characteristics);
    ComplexArgumentParser::Finalize(request.audioOutputIndex);
}

CHIP_ERROR ComplexArgumentParser::Setup(const char * label,
                                        chip::app::Clusters::ContentLauncher::Structs::PlaybackPreferencesStruct::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("PlaybackPreferencesStruct.playbackPosition", "playbackPosition",
                                                                  value.isMember("playbackPosition")));
    ReturnErrorOnFailure(
        ComplexArgumentParser::EnsureMemberExist("PlaybackPreferencesStruct.textTrack", "textTrack", value.isMember("textTrack")));

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

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::ContentLauncher::Structs::PlaybackPreferencesStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.playbackPosition);
    ComplexArgumentParser::Finalize(request.textTrack);
    ComplexArgumentParser::Finalize(request.audioTracks);
}

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::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::ContentControl::Structs::RatingNameStruct::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("RatingNameStruct.ratingName", "ratingName", value.isMember("ratingName")));

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

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

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

void ComplexArgumentParser::Finalize(chip::app::Clusters::ContentControl::Structs::RatingNameStruct::Type & request)
{
    ComplexArgumentParser::Finalize(request.ratingName);
    ComplexArgumentParser::Finalize(request.ratingNameDesc);
}

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