Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update metadata-tree from MetadaList Foo(path) to CHIP_ERROR Foo(path, ListBuilder &) #37127

Merged
merged 20 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
742dc89
Append-only API update: use CHIP_ERROR and builders for MetadataTree
andy31415 Jan 20, 2025
92e448d
Fix includes
andy31415 Jan 20, 2025
c19a4fd
Remove odd comment
andy31415 Jan 20, 2025
48dc77c
ScopedSpan == ReadOnlyBuffer and Build == TakeBuffer
andy31415 Jan 20, 2025
066d2ea
Update src/app/InteractionModelEngine.cpp
andy31415 Jan 20, 2025
e37165e
Update src/app/clusters/descriptor/descriptor.cpp
andy31415 Jan 20, 2025
ea07467
Update src/app/clusters/descriptor/descriptor.cpp
andy31415 Jan 20, 2025
28a8640
Update src/app/clusters/descriptor/descriptor.cpp
andy31415 Jan 20, 2025
63dc63f
Update src/app/clusters/descriptor/descriptor.cpp
andy31415 Jan 20, 2025
c11bf30
Update src/app/clusters/descriptor/descriptor.cpp
andy31415 Jan 20, 2025
94cdf80
Update src/app/data-model-provider/MetadataList.cpp
andy31415 Jan 20, 2025
b052497
Replaced a lot of auto with const auto for readability
andy31415 Jan 20, 2025
f902249
Update src/app/clusters/microwave-oven-control-server/microwave-oven-…
andy31415 Jan 20, 2025
9e8d062
Merge branch 'append_only_api' of github.com:andy31415/connectedhomei…
andy31415 Jan 20, 2025
f122b28
Remove old comment
andy31415 Jan 20, 2025
6ae480e
Fix some typos
andy31415 Jan 20, 2025
52fbc7f
Fix typo
andy31415 Jan 20, 2025
eaf9f0c
Merge branch 'master' into append_only_api
andy31415 Jan 20, 2025
493950d
Update src/app/data-model-provider/MetadataTypes.h
andy31415 Jan 23, 2025
ded4d53
Merge branch 'master' into append_only_api
andreilitvin Jan 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/access/ProviderDeviceTypeResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#pragma once

#include <access/AccessControl.h>
#include <app/data-model-provider/MetadataList.h>
#include <app/data-model-provider/MetadataTypes.h>
#include <app/data-model-provider/Provider.h>

namespace chip {
Expand All @@ -31,8 +33,9 @@ class DynamicProviderDeviceTypeResolver : public chip::Access::AccessControl::De

bool IsDeviceTypeOnEndpoint(chip::DeviceTypeId deviceType, chip::EndpointId endpoint) override
{
auto deviceTypes = mModelGetter()->DeviceTypes(endpoint);
for (auto & type : deviceTypes.GetSpanValidForLifetime())
app::DataModel::ListBuilder<app::DataModel::DeviceTypeEntry> builder;
(void) mModelGetter()->DeviceTypes(endpoint, builder);
for (auto & type : builder.TakeBuffer())
{
if (type.deviceTypeId == deviceType)
{
Expand Down
23 changes: 11 additions & 12 deletions src/app/AttributePathExpandIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <app/AttributePathExpandIterator.h>

#include <app/GlobalAttributes.h>
#include <app/data-model-provider/MetadataList.h>
#include <app/data-model-provider/MetadataLookup.h>
#include <app/data-model-provider/MetadataTypes.h>
#include <lib/core/DataModelTypes.h>
Expand Down Expand Up @@ -139,13 +140,13 @@ std::optional<AttributeId> AttributePathExpandIterator::NextAttributeId()
if (mAttributeIndex == kInvalidIndex)
{
// start a new iteration of attributes on the current cluster path.
mAttributes = mDataModelProvider->Attributes(mPosition.mOutputPath);
mAttributes = mDataModelProvider->AttributesIgnoreError(mPosition.mOutputPath);

if (mPosition.mOutputPath.mAttributeId != kInvalidAttributeId)
{
// Position on the correct attribute if we have a start point
mAttributeIndex = 0;
while ((mAttributeIndex < mAttributes.Size()) &&
while ((mAttributeIndex < mAttributes.size()) &&
(mAttributes[mAttributeIndex].attributeId != mPosition.mOutputPath.mAttributeId))
{
mAttributeIndex++;
Expand Down Expand Up @@ -199,7 +200,7 @@ std::optional<AttributeId> AttributePathExpandIterator::NextAttributeId()
return std::nullopt;
}

if (mAttributeIndex < mAttributes.Size())
if (mAttributeIndex < mAttributes.size())
{
return mAttributes[mAttributeIndex].attributeId;
}
Expand All @@ -222,13 +223,13 @@ std::optional<ClusterId> AttributePathExpandIterator::NextClusterId()
if (mClusterIndex == kInvalidIndex)
{
// start a new iteration on the current endpoint
mClusters = mDataModelProvider->ServerClusters(mPosition.mOutputPath.mEndpointId);
mClusters = mDataModelProvider->ServerClustersIgnoreError(mPosition.mOutputPath.mEndpointId);

if (mPosition.mOutputPath.mClusterId != kInvalidClusterId)
{
// Position on the correct cluster if we have a start point
mClusterIndex = 0;
while ((mClusterIndex < mClusters.Size()) && (mClusters[mClusterIndex].clusterId != mPosition.mOutputPath.mClusterId))
while ((mClusterIndex < mClusters.size()) && (mClusters[mClusterIndex].clusterId != mPosition.mOutputPath.mClusterId))
{
mClusterIndex++;
}
Expand All @@ -248,10 +249,8 @@ std::optional<ClusterId> AttributePathExpandIterator::NextClusterId()
{
const ClusterId clusterId = mPosition.mAttributePath->mValue.mClusterId;

auto span = mClusters.GetSpanValidForLifetime();

bool found = false;
for (auto & entry : span)
for (auto & entry : mClusters)
{
if (entry.clusterId == clusterId)
{
Expand All @@ -276,7 +275,7 @@ std::optional<ClusterId> AttributePathExpandIterator::NextClusterId()
}

VerifyOrReturnValue(mPosition.mAttributePath->mValue.HasWildcardClusterId(), std::nullopt);
VerifyOrReturnValue(mClusterIndex < mClusters.Size(), std::nullopt);
VerifyOrReturnValue(mClusterIndex < mClusters.size(), std::nullopt);

return mClusters[mClusterIndex].clusterId;
}
Expand All @@ -286,13 +285,13 @@ std::optional<EndpointId> AttributePathExpandIterator::NextEndpointId()
if (mEndpointIndex == kInvalidIndex)
{
// index is missing, have to start a new iteration
mEndpoints = mDataModelProvider->Endpoints();
mEndpoints = mDataModelProvider->EndpointsIgnoreError();

if (mPosition.mOutputPath.mEndpointId != kInvalidEndpointId)
{
// Position on the correct endpoint if we have a start point
mEndpointIndex = 0;
while ((mEndpointIndex < mEndpoints.Size()) && (mEndpoints[mEndpointIndex].id != mPosition.mOutputPath.mEndpointId))
while ((mEndpointIndex < mEndpoints.size()) && (mEndpoints[mEndpointIndex].id != mPosition.mOutputPath.mEndpointId))
{
mEndpointIndex++;
}
Expand All @@ -315,7 +314,7 @@ std::optional<EndpointId> AttributePathExpandIterator::NextEndpointId()
}

VerifyOrReturnValue(mPosition.mAttributePath->mValue.HasWildcardEndpointId(), std::nullopt);
VerifyOrReturnValue(mEndpointIndex < mEndpoints.Size(), std::nullopt);
VerifyOrReturnValue(mEndpointIndex < mEndpoints.size(), std::nullopt);

return mEndpoints[mEndpointIndex].id;
}
Expand Down
6 changes: 3 additions & 3 deletions src/app/AttributePathExpandIterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ class AttributePathExpandIterator
DataModel::Provider * mDataModelProvider;
Position & mPosition;

DataModel::MetadataList<DataModel::EndpointEntry> mEndpoints; // all endpoints
DataModel::ReadOnlyBuffer<DataModel::EndpointEntry> mEndpoints; // all endpoints
size_t mEndpointIndex = kInvalidIndex;

DataModel::MetadataList<DataModel::ServerClusterEntry> mClusters; // all clusters ON THE CURRENT endpoint
DataModel::ReadOnlyBuffer<DataModel::ServerClusterEntry> mClusters; // all clusters ON THE CURRENT endpoint
size_t mClusterIndex = kInvalidIndex;

DataModel::MetadataList<DataModel::AttributeEntry> mAttributes; // all attributes ON THE CURRENT cluster
DataModel::ReadOnlyBuffer<DataModel::AttributeEntry> mAttributes; // all attributes ON THE CURRENT cluster
size_t mAttributeIndex = kInvalidIndex;

/// Move to the next endpoint/cluster/attribute triplet that is valid given
Expand Down
13 changes: 7 additions & 6 deletions src/app/InteractionModelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@
#include <app/EventPathParams.h>
#include <app/RequiredPrivilege.h>
#include <app/data-model-provider/ActionReturnStatus.h>
#include <app/data-model-provider/MetadataList.h>
#include <app/data-model-provider/MetadataLookup.h>
#include <app/data-model-provider/MetadataTypes.h>
#include <app/data-model-provider/OperationTypes.h>
#include <app/data-model/List.h>
#include <app/util/IMClusterCommandHandler.h>
#include <app/util/af-types.h>
#include <app/util/endpoint-config-api.h>
Expand Down Expand Up @@ -91,8 +93,7 @@ bool MayHaveAccessibleEventPathForEndpoint(DataModel::Provider * aProvider, Endp
aSubjectDescriptor);
}

auto serverClusters = aProvider->ServerClusters(aEventPath.mEndpointId);
for (auto & cluster : serverClusters.GetSpanValidForLifetime())
for (auto & cluster : aProvider->ServerClustersIgnoreError(aEventPath.mEndpointId))
{
if (MayHaveAccessibleEventPathForEndpointAndCluster(ConcreteClusterPath(aEventPath.mEndpointId, cluster.clusterId),
aEventPath, aSubjectDescriptor))
Expand All @@ -114,8 +115,7 @@ bool MayHaveAccessibleEventPath(DataModel::Provider * aProvider, const EventPath
return MayHaveAccessibleEventPathForEndpoint(aProvider, aEventPath.mEndpointId, aEventPath, subjectDescriptor);
}

auto endpoints = aProvider->Endpoints();
for (const DataModel::EndpointEntry & ep : endpoints.GetSpanValidForLifetime())
for (const DataModel::EndpointEntry & ep : aProvider->EndpointsIgnoreError())
{
if (MayHaveAccessibleEventPathForEndpoint(aProvider, ep.id, aEventPath, subjectDescriptor))
{
Expand Down Expand Up @@ -1790,8 +1790,9 @@ Protocols::InteractionModel::Status InteractionModelEngine::CheckCommandExistenc
{
auto provider = GetDataModelProvider();

DataModel::MetadataList<DataModel::AcceptedCommandEntry> acceptedCommands = provider->AcceptedCommands(aCommandPath);
for (auto & existing : acceptedCommands.GetSpanValidForLifetime())
DataModel::ListBuilder<DataModel::AcceptedCommandEntry> acceptedCommands;
(void) provider->AcceptedCommands(aCommandPath, acceptedCommands);
for (auto & existing : acceptedCommands.TakeBuffer())
{
if (existing.commandId == aCommandPath.mCommandId)
{
Expand Down
80 changes: 45 additions & 35 deletions src/app/clusters/descriptor/descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
#include <app/AttributeAccessInterface.h>
#include <app/AttributeAccessInterfaceRegistry.h>
#include <app/InteractionModelEngine.h>
#include <app/data-model-provider/MetadataList.h>
#include <app/data-model-provider/MetadataTypes.h>
#include <app/data-model/List.h>
#include <app/util/attribute-storage.h>
#include <app/util/endpoint-config-api.h>
#include <lib/core/CHIPError.h>
Expand Down Expand Up @@ -60,7 +62,7 @@ bool IsDescendantOf(const DataModel::EndpointEntry * __restrict__ childEndpoint,
childEndpoint = nullptr; // we will look it up again

// find the requested value in the array to get its parent
for (auto & ep : allEndpoints)
for (const auto & ep : allEndpoints)
{
if (ep.id == lookupId)
{
Expand All @@ -83,7 +85,8 @@ class DescriptorAttrAccess : public AttributeAccessInterface
CHIP_ERROR ReadTagListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadPartsAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadDeviceAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadClientServerAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder, bool server);
CHIP_ERROR ReadClientClusters(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadServerClusters(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadFeatureMap(EndpointId endpoint, AttributeValueEncoder & aEncoder);
};
Expand All @@ -103,9 +106,11 @@ CHIP_ERROR DescriptorAttrAccess::ReadFeatureMap(EndpointId endpoint, AttributeVa

CHIP_ERROR DescriptorAttrAccess::ReadTagListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
return aEncoder.EncodeList([&endpoint](const auto & encoder) -> CHIP_ERROR {
auto tags = InteractionModelEngine::GetInstance()->GetDataModelProvider()->SemanticTags(endpoint);
for (auto & tag : tags.GetSpanValidForLifetime())
DataModel::ListBuilder<DataModel::Provider::SemanticTag> semanticTagsList;
ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->GetDataModelProvider()->SemanticTags(endpoint, semanticTagsList));

return aEncoder.EncodeList([&semanticTagsList](const auto & encoder) -> CHIP_ERROR {
for (const auto & tag : semanticTagsList.TakeBuffer())
{
ReturnErrorOnFailure(encoder.Encode(tag));
}
Expand All @@ -115,11 +120,13 @@ CHIP_ERROR DescriptorAttrAccess::ReadTagListAttribute(EndpointId endpoint, Attri

CHIP_ERROR DescriptorAttrAccess::ReadPartsAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
auto endpoints = InteractionModelEngine::GetInstance()->GetDataModelProvider()->Endpoints();
DataModel::ListBuilder<DataModel::EndpointEntry> endpointsList;
ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->GetDataModelProvider()->Endpoints(endpointsList));
auto endpoints = endpointsList.TakeBuffer();
if (endpoint == 0x00)
{
return aEncoder.EncodeList([&endpoints](const auto & encoder) -> CHIP_ERROR {
for (auto & ep : endpoints.GetSpanValidForLifetime())
for (const auto & ep : endpoints)
{
if (ep.id == 0)
{
Expand All @@ -133,15 +140,15 @@ CHIP_ERROR DescriptorAttrAccess::ReadPartsAttribute(EndpointId endpoint, Attribu

// find the given endpoint
unsigned idx = 0;
while (idx < endpoints.Size())
while (idx < endpoints.size())
{
if (endpoints[idx].id == endpoint)
{
break;
}
idx++;
}
if (idx >= endpoints.Size())
if (idx >= endpoints.size())
{
// not found
return CHIP_ERROR_NOT_FOUND;
Expand All @@ -154,9 +161,9 @@ CHIP_ERROR DescriptorAttrAccess::ReadPartsAttribute(EndpointId endpoint, Attribu
case DataModel::EndpointCompositionPattern::kFullFamily:
// encodes ALL endpoints that have the specified endpoint as a descendant
return aEncoder.EncodeList([&endpoints, endpoint](const auto & encoder) -> CHIP_ERROR {
for (auto & ep : endpoints.GetSpanValidForLifetime())
for (const auto & ep : endpoints)
{
if (IsDescendantOf(&ep, endpoint, endpoints.GetSpanValidForLifetime()))
if (IsDescendantOf(&ep, endpoint, endpoints))
{
ReturnErrorOnFailure(encoder.Encode(ep.id));
}
Expand All @@ -166,7 +173,7 @@ CHIP_ERROR DescriptorAttrAccess::ReadPartsAttribute(EndpointId endpoint, Attribu

case DataModel::EndpointCompositionPattern::kTree:
return aEncoder.EncodeList([&endpoints, endpoint](const auto & encoder) -> CHIP_ERROR {
for (auto & ep : endpoints.GetSpanValidForLifetime())
for (const auto & ep : endpoints)
{
if (ep.parentId != endpoint)
{
Expand All @@ -184,11 +191,14 @@ CHIP_ERROR DescriptorAttrAccess::ReadPartsAttribute(EndpointId endpoint, Attribu

CHIP_ERROR DescriptorAttrAccess::ReadDeviceAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
CHIP_ERROR err = aEncoder.EncodeList([&endpoint](const auto & encoder) -> CHIP_ERROR {
Descriptor::Structs::DeviceTypeStruct::Type deviceStruct;
DataModel::ListBuilder<DataModel::DeviceTypeEntry> deviceTypesList;
ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->GetDataModelProvider()->DeviceTypes(endpoint, deviceTypesList));

auto deviceTypes = InteractionModelEngine::GetInstance()->GetDataModelProvider()->DeviceTypes(endpoint);
for (auto & type : deviceTypes.GetSpanValidForLifetime())
auto deviceTypes = deviceTypesList.TakeBuffer();

CHIP_ERROR err = aEncoder.EncodeList([&deviceTypes](const auto & encoder) -> CHIP_ERROR {
Descriptor::Structs::DeviceTypeStruct::Type deviceStruct;
for (const auto & type : deviceTypes)
{
deviceStruct.deviceType = type.deviceTypeId;
deviceStruct.revision = type.deviceTypeRevision;
Expand All @@ -201,30 +211,30 @@ CHIP_ERROR DescriptorAttrAccess::ReadDeviceAttribute(EndpointId endpoint, Attrib
return err;
}

CHIP_ERROR DescriptorAttrAccess::ReadClientServerAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder, bool server)
CHIP_ERROR DescriptorAttrAccess::ReadServerClusters(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
CHIP_ERROR err = aEncoder.EncodeList([&endpoint, server](const auto & encoder) -> CHIP_ERROR {
if (server)
DataModel::ListBuilder<DataModel::ServerClusterEntry> builder;
ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->GetDataModelProvider()->ServerClusters(endpoint, builder));
return aEncoder.EncodeList([&builder](const auto & encoder) -> CHIP_ERROR {
for (const auto & cluster : builder.TakeBuffer())
{
auto clusters = InteractionModelEngine::GetInstance()->GetDataModelProvider()->ServerClusters(endpoint);
for (auto & cluster : clusters.GetSpanValidForLifetime())
{
ReturnErrorOnFailure(encoder.Encode(cluster.clusterId));
}
ReturnErrorOnFailure(encoder.Encode(cluster.clusterId));
}
else
return CHIP_NO_ERROR;
});
}

CHIP_ERROR DescriptorAttrAccess::ReadClientClusters(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
DataModel::ListBuilder<ClusterId> clusterIdList;
ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->GetDataModelProvider()->ClientClusters(endpoint, clusterIdList));
return aEncoder.EncodeList([&clusterIdList](const auto & encoder) -> CHIP_ERROR {
for (const auto & id : clusterIdList.TakeBuffer())
{
auto clusters = InteractionModelEngine::GetInstance()->GetDataModelProvider()->ClientClusters(endpoint);
for (auto & id : clusters.GetSpanValidForLifetime())
{
ReturnErrorOnFailure(encoder.Encode(id));
}
ReturnErrorOnFailure(encoder.Encode(id));
}

return CHIP_NO_ERROR;
});

return err;
}

CHIP_ERROR DescriptorAttrAccess::ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder)
Expand All @@ -244,10 +254,10 @@ CHIP_ERROR DescriptorAttrAccess::Read(const ConcreteReadAttributePath & aPath, A
return ReadDeviceAttribute(aPath.mEndpointId, aEncoder);
}
case ServerList::Id: {
return ReadClientServerAttribute(aPath.mEndpointId, aEncoder, true);
return ReadServerClusters(aPath.mEndpointId, aEncoder);
}
case ClientList::Id: {
return ReadClientServerAttribute(aPath.mEndpointId, aEncoder, false);
return ReadClientClusters(aPath.mEndpointId, aEncoder);
}
case PartsList::Id: {
return ReadPartsAttribute(aPath.mEndpointId, aEncoder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*
*/

#include "app/data-model-provider/MetadataList.h"
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app/AttributeAccessInterfaceRegistry.h>
#include <app/CommandHandlerInterfaceRegistry.h>
Expand Down Expand Up @@ -249,15 +250,17 @@ void Instance::HandleSetCookingParameters(HandlerContext & ctx, const Commands::

if (startAfterSetting.HasValue())
{
DataModel::MetadataList<DataModel::AcceptedCommandEntry> acceptedCommands =
InteractionModelEngine::GetInstance()->GetDataModelProvider()->AcceptedCommands(
ConcreteClusterPath(mEndpointId, OperationalState::Id));
Span<const DataModel::AcceptedCommandEntry> acceptedCommandsSpan = acceptedCommands.GetSpanValidForLifetime();

bool commandExists = std::find_if(acceptedCommandsSpan.begin(), acceptedCommandsSpan.end(),
[](const DataModel::AcceptedCommandEntry & entry) {
return entry.commandId == OperationalState::Commands::Start::Id;
}) != acceptedCommandsSpan.end();

DataModel::ListBuilder<DataModel::AcceptedCommandEntry> acceptedCommandsList;

InteractionModelEngine::GetInstance()->GetDataModelProvider()->AcceptedCommands(
ConcreteClusterPath(mEndpointId, OperationalState::Id), acceptedCommandsList);
auto acceptedCommands = acceptedCommandsList.TakeBuffer();

bool commandExists =
std::find_if(acceptedCommands.begin(), acceptedCommands.end(), [](const DataModel::AcceptedCommandEntry & entry) {
return entry.commandId == OperationalState::Commands::Start::Id;
}) != acceptedCommands.end();

VerifyOrExit(
commandExists, status = Status::InvalidCommand; ChipLogError(
Expand Down
1 change: 1 addition & 0 deletions src/app/data-model-provider/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ source_set("data-model-provider") {
"MetadataList.h",
"MetadataLookup.cpp",
"MetadataLookup.h",
"MetadataTypes.cpp",
"MetadataTypes.h",
"OperationTypes.h",
"Provider.h",
Expand Down
Loading
Loading