diff --git a/common/values/parsed_json_map_value.cc b/common/values/parsed_json_map_value.cc index ec8c91a4f..f6e9c3c03 100644 --- a/common/values/parsed_json_map_value.cc +++ b/common/values/parsed_json_map_value.cc @@ -33,6 +33,7 @@ #include "common/value.h" #include "common/values/parsed_json_value.h" #include "common/values/values.h" +#include "extensions/protobuf/internal/map_reflection.h" #include "internal/json.h" #include "internal/message_equality.h" #include "internal/status_macros.h" @@ -299,12 +300,14 @@ absl::Status ParsedJsonMapValue::ListKeys( well_known_types::GetStructReflectionOrDie(value_->GetDescriptor()); auto builder = NewListValueBuilder(arena); builder->Reserve(static_cast(reflection.FieldsSize(*value_))); - auto keys_begin = reflection.BeginFields(*value_); - const auto keys_end = reflection.EndFields(*value_); - for (; keys_begin != keys_end; ++keys_begin) { - CEL_RETURN_IF_ERROR(builder->Add( - Value::WrapMapFieldKeyString(keys_begin.GetKey(), value_, arena))); - } + CEL_RETURN_IF_ERROR(cel::extensions::protobuf_internal::ForEachMapEntry( + *value_->GetReflection(), *value_, *reflection.GetFieldsDescriptor(), + [&](auto key_ref, auto value_ref) -> absl::Status { + CEL_RETURN_IF_ERROR( + builder->Add(Value::WrapMapFieldKeyString(key_ref, value_, arena))); + return absl::OkStatus(); + })); + *result = std::move(*builder).Build(); return absl::OkStatus(); } @@ -321,6 +324,19 @@ absl::Status ParsedJsonMapValue::ForEach( well_known_types::GetStructReflectionOrDie(value_->GetDescriptor()); Value key_scratch; Value value_scratch; +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + for (auto entry : value_->GetReflection()->GetMap( + *value_, reflection.GetFieldsDescriptor())) { + // We have to copy until `google::protobuf::MapKey` is just a view. + key_scratch = StringValue(arena, entry.key().GetStringValue()); + value_scratch = common_internal::ParsedJsonValue( + &entry.value().GetMessageValue(), arena); + CEL_ASSIGN_OR_RETURN(auto ok, callback(key_scratch, value_scratch)); + if (!ok) { + break; + } + } +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS auto map_begin = reflection.BeginFields(*value_); const auto map_end = reflection.EndFields(*value_); for (; map_begin != map_end; ++map_begin) { @@ -333,6 +349,7 @@ absl::Status ParsedJsonMapValue::ForEach( break; } } +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS return absl::OkStatus(); } @@ -345,8 +362,19 @@ class ParsedJsonMapValueIterator final : public ValueIterator { : message_(message), reflection_(well_known_types::GetStructReflectionOrDie( message_->GetDescriptor())), +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + begin_(message->GetReflection() + ->GetMap(*message, reflection_.GetFieldsDescriptor()) + .begin()), + end_(message->GetReflection() + ->GetMap(*message, reflection_.GetFieldsDescriptor()) + .end()) +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS begin_(reflection_.BeginFields(*message_)), - end_(reflection_.EndFields(*message_)) {} + end_(reflection_.EndFields(*message_)) +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS + { + } bool HasNext() override { return begin_ != end_; } @@ -359,7 +387,11 @@ class ParsedJsonMapValueIterator final : public ValueIterator { "`ValueIterator::Next` called after `ValueIterator::HasNext` " "returned false"); } +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + *result = Value::WrapMapFieldKeyString(begin_->key(), message_, arena); +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS *result = Value::WrapMapFieldKeyString(begin_.GetKey(), message_, arena); +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS ++begin_; return absl::OkStatus(); } @@ -377,8 +409,13 @@ class ParsedJsonMapValueIterator final : public ValueIterator { if (begin_ == end_) { return false; } +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + *key_or_value = + Value::WrapMapFieldKeyString(begin_->key(), message_, arena); +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS *key_or_value = Value::WrapMapFieldKeyString(begin_.GetKey(), message_, arena); +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS ++begin_; return true; } @@ -396,11 +433,19 @@ class ParsedJsonMapValueIterator final : public ValueIterator { if (begin_ == end_) { return false; } +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + *key = Value::WrapMapFieldKeyString(begin_->key(), message_, arena); + if (value != nullptr) { + *value = common_internal::ParsedJsonValue( + &begin_->value().GetMessageValue(), arena); + } +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS *key = Value::WrapMapFieldKeyString(begin_.GetKey(), message_, arena); if (value != nullptr) { *value = common_internal::ParsedJsonValue( &begin_.GetValueRef().GetMessageValue(), arena); } +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS ++begin_; return true; } @@ -408,8 +453,13 @@ class ParsedJsonMapValueIterator final : public ValueIterator { private: const google::protobuf::Message* absl_nonnull const message_; const well_known_types::StructReflection reflection_; +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + proto2::GenericConstMapRef::iterator begin_; + const proto2::GenericConstMapRef::iterator end_; +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS google::protobuf::ConstMapIterator begin_; const google::protobuf::ConstMapIterator end_; +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS std::string scratch_; }; diff --git a/common/values/parsed_map_field_value.cc b/common/values/parsed_map_field_value.cc index 92787a8af..179eb7c0d 100644 --- a/common/values/parsed_map_field_value.cc +++ b/common/values/parsed_map_field_value.cc @@ -423,15 +423,14 @@ absl::Status ParsedMapFieldValue::ListKeys( field_->message_type()->map_key())); auto builder = NewListValueBuilder(arena); builder->Reserve(Size()); - auto begin = extensions::protobuf_internal::ConstMapBegin(*reflection, - *message_, *field_); - const auto end = extensions::protobuf_internal::ConstMapEnd( - *reflection, *message_, *field_); - for (; begin != end; ++begin) { - Value scratch; - (*key_accessor)(begin.GetKey(), message_, arena, &scratch); - CEL_RETURN_IF_ERROR(builder->Add(std::move(scratch))); - } + CEL_RETURN_IF_ERROR(extensions::protobuf_internal::ForEachMapEntry( + *reflection, *message_, *field_, + [&](auto key_ref, auto value_ref) -> absl::Status { + Value scratch; + (*key_accessor)(key_ref, message_, arena, &scratch); + CEL_RETURN_IF_ERROR(builder->Add(std::move(scratch))); + return absl::OkStatus(); + })); *result = std::move(*builder).Build(); return absl::OkStatus(); } @@ -454,12 +453,23 @@ absl::Status ParsedMapFieldValue::ForEach( CEL_ASSIGN_OR_RETURN( auto value_accessor, common_internal::MapFieldValueAccessorFor(value_field)); + Value key_scratch; + Value value_scratch; +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + for (auto entry : reflection->GetMap(*message_, field_)) { + (*key_accessor)(entry.key(), message_, arena, &key_scratch); + (*value_accessor)(entry.value(), message_, value_field, descriptor_pool, + message_factory, arena, &value_scratch); + CEL_ASSIGN_OR_RETURN(auto ok, callback(key_scratch, value_scratch)); + if (!ok) { + break; + } + } +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS auto begin = extensions::protobuf_internal::ConstMapBegin( *reflection, *message_, *field_); const auto end = extensions::protobuf_internal::ConstMapEnd( *reflection, *message_, *field_); - Value key_scratch; - Value value_scratch; for (; begin != end; ++begin) { (*key_accessor)(begin.GetKey(), message_, arena, &key_scratch); (*value_accessor)(begin.GetValueRef(), message_, value_field, @@ -470,6 +480,7 @@ absl::Status ParsedMapFieldValue::ForEach( break; } } +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS } return absl::OkStatus(); } @@ -487,10 +498,17 @@ class ParsedMapFieldValueIterator final : public ValueIterator { value_field_(field->message_type()->map_value()), key_accessor_(key_accessor), value_accessor_(value_accessor), +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + begin_(message->GetReflection()->GetMap(*message, field).begin()), + end_(message->GetReflection()->GetMap(*message, field).end()) +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS begin_(extensions::protobuf_internal::ConstMapBegin( *message_->GetReflection(), *message_, *field)), end_(extensions::protobuf_internal::ConstMapEnd( - *message_->GetReflection(), *message_, *field)) {} + *message_->GetReflection(), *message_, *field)) +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS + { + } bool HasNext() override { return begin_ != end_; } @@ -503,7 +521,11 @@ class ParsedMapFieldValueIterator final : public ValueIterator { "ValueIterator::Next called after ValueIterator::HasNext returned " "false"); } +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + (*key_accessor_)(begin_->key(), message_, arena, result); +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS (*key_accessor_)(begin_.GetKey(), message_, arena, result); +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS ++begin_; return absl::OkStatus(); } @@ -521,7 +543,11 @@ class ParsedMapFieldValueIterator final : public ValueIterator { if (begin_ == end_) { return false; } +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + (*key_accessor_)(begin_->key(), message_, arena, key_or_value); +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS (*key_accessor_)(begin_.GetKey(), message_, arena, key_or_value); +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS ++begin_; return true; } @@ -539,11 +565,19 @@ class ParsedMapFieldValueIterator final : public ValueIterator { if (begin_ == end_) { return false; } +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + (*key_accessor_)(begin_->key(), message_, arena, key); + if (value != nullptr) { + (*value_accessor_)(begin_->value(), message_, value_field_, + descriptor_pool, message_factory, arena, value); + } +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS (*key_accessor_)(begin_.GetKey(), message_, arena, key); if (value != nullptr) { (*value_accessor_)(begin_.GetValueRef(), message_, value_field_, descriptor_pool, message_factory, arena, value); } +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS ++begin_; return true; } @@ -553,8 +587,13 @@ class ParsedMapFieldValueIterator final : public ValueIterator { const google::protobuf::FieldDescriptor* absl_nonnull const value_field_; const absl_nonnull common_internal::MapFieldKeyAccessor key_accessor_; const absl_nonnull common_internal::MapFieldValueAccessor value_accessor_; +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + proto2::GenericConstMapRef::iterator begin_; + const proto2::GenericConstMapRef::iterator end_; +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS google::protobuf::ConstMapIterator begin_; const google::protobuf::ConstMapIterator end_; +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS }; } // namespace diff --git a/extensions/protobuf/internal/BUILD b/extensions/protobuf/internal/BUILD index 4a3a3e82b..78551caf6 100644 --- a/extensions/protobuf/internal/BUILD +++ b/extensions/protobuf/internal/BUILD @@ -28,6 +28,7 @@ cc_library( deps = [ "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/base:nullability", + "@com_google_absl//absl/status", "@com_google_protobuf//:protobuf", ], ) diff --git a/extensions/protobuf/internal/map_reflection.cc b/extensions/protobuf/internal/map_reflection.cc index 605e4437d..df25f8637 100644 --- a/extensions/protobuf/internal/map_reflection.cc +++ b/extensions/protobuf/internal/map_reflection.cc @@ -19,6 +19,54 @@ #include "google/protobuf/map_field.h" #include "google/protobuf/message.h" +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) +namespace cel::extensions::protobuf_internal { + +bool LookupMapValue(const google::protobuf::Reflection& reflection, + const google::protobuf::Message& message, + const google::protobuf::FieldDescriptor& field, + const google::protobuf::MapKey& key, + google::protobuf::MapValueConstRef* value) { + auto map = reflection.GetMap(message, &field); + auto it = map.find(key); + if (it == map.end()) return false; + *value = it->value(); + return true; +} + +bool ContainsMapKey(const google::protobuf::Reflection& reflection, + const google::protobuf::Message& message, + const google::protobuf::FieldDescriptor& field, + const google::protobuf::MapKey& key) { + return reflection.GetMap(message, &field).contains(key); +} + +int MapSize(const google::protobuf::Reflection& reflection, + const google::protobuf::Message& message, + const google::protobuf::FieldDescriptor& field) { + return reflection.GetMap(message, &field).size(); +} + +bool InsertOrLookupMapValue(const google::protobuf::Reflection& reflection, + google::protobuf::Message* message, + const google::protobuf::FieldDescriptor& field, + const google::protobuf::MapKey& key, + google::protobuf::MapValueRef* value) { + auto map = reflection.MutableMap(message, &field); + auto res = map.try_emplace(key); + *value = res.first->value(); + return res.second; +} + +bool DeleteMapValue(const google::protobuf::Reflection* absl_nonnull reflection, + google::protobuf::Message* absl_nonnull message, + const google::protobuf::FieldDescriptor* absl_nonnull field, + const google::protobuf::MapKey& key) { + return reflection->MutableMap(message, field).erase(key); +} + +} // namespace cel::extensions::protobuf_internal +#else namespace google::protobuf::expr { class CelMapReflectionFriend final { @@ -130,3 +178,4 @@ bool DeleteMapValue(const google::protobuf::Reflection* absl_nonnull reflection, } } // namespace cel::extensions::protobuf_internal +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS diff --git a/extensions/protobuf/internal/map_reflection.h b/extensions/protobuf/internal/map_reflection.h index 681d7693d..281fe8787 100644 --- a/extensions/protobuf/internal/map_reflection.h +++ b/extensions/protobuf/internal/map_reflection.h @@ -17,11 +17,13 @@ #include "absl/base/attributes.h" #include "absl/base/nullability.h" +#include "absl/status/status.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/map_field.h" #include "google/protobuf/message.h" -#ifndef GOOGLE_PROTOBUF_HAS_CEL_MAP_REFLECTION_FRIEND +#if !defined(GOOGLE_PROTOBUF_HAS_CEL_MAP_REFLECTION_FRIEND) && \ + !defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) #error "protobuf library is too old, please update to version 3.15.0 or newer" #endif @@ -42,6 +44,19 @@ int MapSize(const google::protobuf::Reflection& reflection, const google::protobuf::Message& message, const google::protobuf::FieldDescriptor& field); +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) +template +absl::Status ForEachMapEntry(const google::protobuf::Reflection& reflection, + const google::protobuf::Message& message, + const google::protobuf::FieldDescriptor& field, F f) { + for (auto entry : reflection.GetMap(message, &field)) { + if (auto status = f(entry.key(), entry.value()); !status.ok()) { + return status; + } + } + return absl::OkStatus(); +} +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS google::protobuf::ConstMapIterator ConstMapBegin(const google::protobuf::Reflection& reflection, const google::protobuf::Message& message, const google::protobuf::FieldDescriptor& field); @@ -49,6 +64,20 @@ google::protobuf::ConstMapIterator ConstMapBegin(const google::protobuf::Reflect google::protobuf::ConstMapIterator ConstMapEnd(const google::protobuf::Reflection& reflection, const google::protobuf::Message& message, const google::protobuf::FieldDescriptor& field); +template +absl::Status ForEachMapEntry(const google::protobuf::Reflection& reflection, + const google::protobuf::Message& message, + const google::protobuf::FieldDescriptor& field, F f) { + auto it = ConstMapBegin(reflection, message, field); + auto end = ConstMapEnd(reflection, message, field); + for (; it != end; ++it) { + if (auto status = f(it.GetKey(), it.GetValueRef()); !status.ok()) { + return status; + } + } + return absl::OkStatus(); +} +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS bool InsertOrLookupMapValue(const google::protobuf::Reflection& reflection, google::protobuf::Message* message, diff --git a/internal/json.cc b/internal/json.cc index cdd4c1a5d..4c29686c0 100644 --- a/internal/json.cc +++ b/internal/json.cc @@ -803,15 +803,14 @@ class MessageToJsonState { const auto* value_descriptor = field->message_type()->map_value(); CEL_ASSIGN_OR_RETURN(const auto value_to_value, GetMapFieldValueToValue(value_descriptor)); - auto begin = extensions::protobuf_internal::ConstMapBegin(*reflection, - message, *field); - const auto end = extensions::protobuf_internal::ConstMapEnd( - *reflection, message, *field); - for (; begin != end; ++begin) { - auto key = (*key_to_string)(begin.GetKey()); - CEL_RETURN_IF_ERROR((this->*value_to_value)( - begin.GetValueRef(), value_descriptor, InsertField(result, key))); - } + CEL_RETURN_IF_ERROR(extensions::protobuf_internal::ForEachMapEntry( + *reflection, message, *field, + [&](auto key_ref, auto value_ref) -> absl::Status { + auto key = (*key_to_string)(key_ref); + CEL_RETURN_IF_ERROR((this->*value_to_value)( + value_ref, value_descriptor, InsertField(result, key))); + return absl::OkStatus(); + })); return absl::OkStatus(); } @@ -1381,7 +1380,11 @@ class JsonMapIterator final { using Generated = typename google::protobuf::Map::const_iterator; +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + using Dynamic = proto2::GenericConstMapRef::iterator; +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS using Dynamic = google::protobuf::ConstMapIterator; +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS using Value = std::pair; @@ -1405,12 +1408,20 @@ class JsonMapIterator final { ++generated; }, [&](Dynamic& dynamic) -> void { +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + const auto& key = dynamic->key().GetStringValue(); + scratch.assign(key.data(), key.size()); + result = std::pair{absl::string_view(scratch), + &dynamic->value().GetMessageValue()}; + ++dynamic; +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS const auto& key = dynamic.GetKey().GetStringValue(); scratch.assign(key.data(), key.size()); result = std::pair{absl::string_view(scratch), &dynamic.GetValueRef().GetMessageValue()}; ++dynamic; +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS }), variant_); return result; @@ -1599,8 +1610,15 @@ class DynamicJsonAccessor final : public JsonAccessor { JsonMapIterator IterateFields( const google::protobuf::MessageLite& message) const override { +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + auto& msg = google::protobuf::DownCastMessage(message); + return msg.GetReflection() + ->GetMap(msg, reflection_.Struct().GetFieldsDescriptor()) + .begin(); +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS return reflection_.Struct().BeginFields( google::protobuf::DownCastMessage(message)); +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS } private: diff --git a/internal/message_equality.cc b/internal/message_equality.cc index 33ef78089..6b778c3ed 100644 --- a/internal/message_equality.cc +++ b/internal/message_equality.cc @@ -50,8 +50,6 @@ namespace cel::internal { namespace { -using ::cel::extensions::protobuf_internal::ConstMapBegin; -using ::cel::extensions::protobuf_internal::ConstMapEnd; using ::cel::extensions::protobuf_internal::LookupMapValue; using ::cel::extensions::protobuf_internal::MapSize; using ::google::protobuf::Descriptor; @@ -904,14 +902,42 @@ class MessageEqualsState final { MapSize(*rhs_reflection, rhs, *rhs_field)) { return false; } - auto lhs_begin = ConstMapBegin(*lhs_reflection, lhs, *lhs_field); - const auto lhs_end = ConstMapEnd(*lhs_reflection, lhs, *lhs_field); + Unique lhs_unpacked; EquatableValue lhs_value; Unique rhs_unpacked; EquatableValue rhs_value; google::protobuf::MapKey rhs_map_key; google::protobuf::MapValueConstRef rhs_map_value; +#if defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) + for (auto lhs_entry : lhs_reflection->GetMap(lhs, lhs_field)) { + if (!CoalesceMapKey(lhs_entry.key(), rhs_entry_key_field->cpp_type(), + &rhs_map_key)) { + return false; + } + if (!LookupMapValue(*rhs_reflection, rhs, *rhs_field, rhs_map_key, + &rhs_map_value)) { + return false; + } + CEL_ASSIGN_OR_RETURN( + lhs_value, + MapValueAsEquatableValue(&arena_, pool_, factory_, lhs_reflection_, + lhs_entry.value(), lhs_entry_value_field, + lhs_scratch_, lhs_unpacked)); + CEL_ASSIGN_OR_RETURN( + rhs_value, + MapValueAsEquatableValue(&arena_, pool_, factory_, rhs_reflection_, + rhs_map_value, rhs_entry_value_field, + rhs_scratch_, rhs_unpacked)); + if (!EquatableValueEquals(lhs_value, rhs_value)) { + return false; + } + } +#else // PROTOBUF_HAS_MAP_REFLECTION_APIS + using ::cel::extensions::protobuf_internal::ConstMapBegin; + using ::cel::extensions::protobuf_internal::ConstMapEnd; + auto lhs_begin = ConstMapBegin(*lhs_reflection, lhs, *lhs_field); + const auto lhs_end = ConstMapEnd(*lhs_reflection, lhs, *lhs_field); for (; lhs_begin != lhs_end; ++lhs_begin) { if (!CoalesceMapKey(lhs_begin.GetKey(), rhs_entry_key_field->cpp_type(), &rhs_map_key)) { @@ -935,6 +961,7 @@ class MessageEqualsState final { return false; } } +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS return true; } diff --git a/internal/well_known_types.cc b/internal/well_known_types.cc index 02e50c3e3..a1f9c4c93 100644 --- a/internal/well_known_types.cc +++ b/internal/well_known_types.cc @@ -1643,6 +1643,7 @@ int StructReflection::FieldsSize(const google::protobuf::Message& message) const message, *fields_field_); } +#if !defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) google::protobuf::ConstMapIterator StructReflection::BeginFields( const google::protobuf::Message& message) const { ABSL_DCHECK(IsInitialized()); @@ -1658,6 +1659,7 @@ google::protobuf::ConstMapIterator StructReflection::EndFields( return cel::extensions::protobuf_internal::ConstMapEnd( *message.GetReflection(), message, *fields_field_); } +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS bool StructReflection::ContainsField(const google::protobuf::Message& message, absl::string_view name) const { diff --git a/internal/well_known_types.h b/internal/well_known_types.h index f63e5e76b..9ce9cc9e1 100644 --- a/internal/well_known_types.h +++ b/internal/well_known_types.h @@ -1194,11 +1194,13 @@ class StructReflection final { int FieldsSize(const google::protobuf::Message& message) const; +#if !defined(PROTOBUF_HAS_MAP_REFLECTION_APIS) google::protobuf::ConstMapIterator BeginFields( const google::protobuf::Message& message ABSL_ATTRIBUTE_LIFETIME_BOUND) const; google::protobuf::ConstMapIterator EndFields( const google::protobuf::Message& message ABSL_ATTRIBUTE_LIFETIME_BOUND) const; +#endif // PROTOBUF_HAS_MAP_REFLECTION_APIS bool ContainsField(const google::protobuf::Message& message, absl::string_view name) const;