From 3ad5ba84c57a789b8c6ca242c382edb6e1003d1a Mon Sep 17 00:00:00 2001 From: Jonathan Tatum Date: Wed, 5 Aug 2026 12:36:54 -0700 Subject: [PATCH] Decouple LegacyTypeProvider and cel::TypeProvider Move the implementation to the concrete / internal class LegacyRuntimeTypeProvider. PiperOrigin-RevId: 959810409 --- eval/public/structs/BUILD | 22 +--- eval/public/structs/legacy_type_provider.h | 31 +---- .../structs/legacy_type_provider_test.cc | 22 +--- .../structs/proto_message_type_adapter.h | 9 +- .../protobuf_descriptor_type_provider_test.cc | 60 --------- runtime/internal/BUILD | 33 +++++ .../internal/legacy_runtime_type_provider.cc | 106 +++++---------- .../internal/legacy_runtime_type_provider.h | 23 +++- .../legacy_runtime_type_provider_test.cc | 121 ++++++++++++++++++ 9 files changed, 222 insertions(+), 205 deletions(-) rename eval/public/structs/legacy_type_provider.cc => runtime/internal/legacy_runtime_type_provider.cc (62%) create mode 100644 runtime/internal/legacy_runtime_type_provider_test.cc diff --git a/eval/public/structs/BUILD b/eval/public/structs/BUILD index 75b4685a0..3ffe5994c 100644 --- a/eval/public/structs/BUILD +++ b/eval/public/structs/BUILD @@ -229,26 +229,12 @@ cc_test( cc_library( name = "legacy_type_provider", - srcs = ["legacy_type_provider.cc"], hdrs = ["legacy_type_provider.h"], deps = [ ":legacy_type_adapter", ":legacy_type_info_apis", - "//common:legacy_value", - "//common:memory", - "//common:type", - "//common:value", - "//eval/public:message_wrapper", - "//extensions/protobuf:memory_manager", - "//internal:status_macros", "@com_google_absl//absl/base:core_headers", - "@com_google_absl//absl/base:nullability", - "@com_google_absl//absl/status", - "@com_google_absl//absl/status:statusor", - "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:string_view", - "@com_google_absl//absl/types:optional", - "@com_google_protobuf//:protobuf", ], ) @@ -359,15 +345,11 @@ cc_test( deps = [ ":legacy_type_info_apis", ":protobuf_descriptor_type_provider", - "//common:type", "//eval/public:cel_value", "//eval/public/testing:matchers", "//extensions/protobuf:memory_manager", "//internal:testing", - "//internal:testing_descriptor_pool", - "//internal:testing_message_factory", "@com_google_absl//absl/status:status_matchers", - "@com_google_cel_spec//proto/cel/expr/conformance/proto3:test_all_types_cc_proto", "@com_google_protobuf//:protobuf", "@com_google_protobuf//:wrappers_cc_proto", ], @@ -413,12 +395,10 @@ cc_test( ":legacy_type_adapter", ":legacy_type_info_apis", ":legacy_type_provider", - ":proto_message_type_adapter", ":trivial_legacy_type_info", - "//common:type", - "//eval/testutil:test_message_cc_proto", "//internal:testing", "@com_google_absl//absl/strings:string_view", + "@com_google_absl//absl/types:optional", ], ) diff --git a/eval/public/structs/legacy_type_provider.h b/eval/public/structs/legacy_type_provider.h index 6148caee7..b00645d0e 100644 --- a/eval/public/structs/legacy_type_provider.h +++ b/eval/public/structs/legacy_type_provider.h @@ -18,24 +18,20 @@ #include #include "absl/base/attributes.h" -#include "absl/base/nullability.h" -#include "absl/status/statusor.h" #include "absl/strings/string_view.h" -#include "common/type.h" -#include "common/type_reflector.h" -#include "common/value.h" #include "eval/public/structs/legacy_type_adapter.h" #include "eval/public/structs/legacy_type_info_apis.h" -#include "google/protobuf/arena.h" -#include "google/protobuf/message.h" namespace google::api::expr::runtime { -// An internal extension of cel::TypeProvider that also deals with legacy types. +// Provides legacy type adapters for google::api::expr::runtime::CelValue +// wrapping messages. // -// Note: This API is not finalized. Consult the CEL team before introducing new -// implementations. -class LegacyTypeProvider : public cel::TypeReflector { +// Note: internal use of this type is limited to interop with the Legacy +// (CelValue) runtime with an internal implementation. +// +// New implementations cannot be registered with the evaluator. +class LegacyTypeProvider { public: virtual ~LegacyTypeProvider() = default; @@ -60,19 +56,6 @@ class LegacyTypeProvider : public cel::TypeReflector { ABSL_ATTRIBUTE_UNUSED absl::string_view name) const { return std::nullopt; } - - absl::StatusOr NewValueBuilder( - absl::string_view name, - google::protobuf::MessageFactory* absl_nonnull message_factory, - google::protobuf::Arena* absl_nonnull arena) const final; - - protected: - absl::StatusOr> FindTypeImpl( - absl::string_view name) const final; - - absl::StatusOr> - FindStructTypeFieldByNameImpl(absl::string_view type, - absl::string_view name) const final; }; } // namespace google::api::expr::runtime diff --git a/eval/public/structs/legacy_type_provider_test.cc b/eval/public/structs/legacy_type_provider_test.cc index cd683bb50..c8059da7c 100644 --- a/eval/public/structs/legacy_type_provider_test.cc +++ b/eval/public/structs/legacy_type_provider_test.cc @@ -17,12 +17,10 @@ #include #include "absl/strings/string_view.h" -#include "common/type.h" +#include "absl/types/optional.h" #include "eval/public/structs/legacy_type_adapter.h" #include "eval/public/structs/legacy_type_info_apis.h" -#include "eval/public/structs/proto_message_type_adapter.h" #include "eval/public/structs/trivial_legacy_type_info.h" -#include "eval/testutil/test_message.pb.h" #include "internal/testing.h" namespace google::api::expr::runtime { @@ -73,23 +71,5 @@ TEST(LegacyTypeProviderTest, NonEmptyTypeProviderProvidesSomeTypes) { EXPECT_EQ(provider.ProvideLegacyTypeInfo("other"), std::nullopt); } -TEST(LegacyTypeProviderTest, FindStructTypeFieldByName) { - ProtoMessageTypeAdapter adapter(TestMessage::descriptor(), nullptr); - LegacyTypeProviderTestImpl provider(&adapter); - - ASSERT_OK_AND_ASSIGN( - absl::optional field, - provider.FindStructTypeFieldByName("test", "int32_value")); - ASSERT_TRUE(field.has_value()); - EXPECT_EQ(field->name(), "int32_value"); - EXPECT_EQ(field->number(), 1); - EXPECT_EQ(field->GetType(), cel::IntType()); - - ASSERT_OK_AND_ASSIGN( - absl::optional not_found_field, - provider.FindStructTypeFieldByName("test", "unknown_field")); - EXPECT_FALSE(not_found_field.has_value()); -} - } // namespace } // namespace google::api::expr::runtime diff --git a/eval/public/structs/proto_message_type_adapter.h b/eval/public/structs/proto_message_type_adapter.h index eb89a467c..f4e6b4c8b 100644 --- a/eval/public/structs/proto_message_type_adapter.h +++ b/eval/public/structs/proto_message_type_adapter.h @@ -28,6 +28,7 @@ #include "eval/public/structs/legacy_type_info_apis.h" #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" +#include "google/protobuf/message.h" namespace google::api::expr::runtime { @@ -40,7 +41,7 @@ class ProtoMessageTypeAdapter : public LegacyTypeInfoApis, public LegacyTypeAccessApis, public LegacyTypeMutationApis { public: - ProtoMessageTypeAdapter(const google::protobuf::Descriptor* descriptor, + ProtoMessageTypeAdapter(const google::protobuf::Descriptor* absl_nonnull descriptor, google::protobuf::MessageFactory* message_factory) : message_factory_(message_factory), descriptor_(descriptor) {} @@ -107,6 +108,10 @@ class ProtoMessageTypeAdapter : public LegacyTypeInfoApis, std::vector ListFields( const CelValue::MessageWrapper& instance) const override; + const google::protobuf::Descriptor* absl_nonnull descriptor() const { + return descriptor_; + } + private: // Helper for standardizing error messages for SetField operation. absl::Status ValidateSetFieldOp(bool assertion, absl::string_view field, @@ -117,7 +122,7 @@ class ProtoMessageTypeAdapter : public LegacyTypeInfoApis, google::protobuf::Message* message) const; google::protobuf::MessageFactory* message_factory_; - const google::protobuf::Descriptor* descriptor_; + const google::protobuf::Descriptor* absl_nonnull descriptor_; }; // Creates a CelValue from the given field on the proto message. This is the diff --git a/eval/public/structs/protobuf_descriptor_type_provider_test.cc b/eval/public/structs/protobuf_descriptor_type_provider_test.cc index 1d07fd657..f2b7900ef 100644 --- a/eval/public/structs/protobuf_descriptor_type_provider_test.cc +++ b/eval/public/structs/protobuf_descriptor_type_provider_test.cc @@ -18,15 +18,11 @@ #include "google/protobuf/wrappers.pb.h" #include "absl/status/status_matchers.h" -#include "common/type.h" #include "eval/public/cel_value.h" #include "eval/public/structs/legacy_type_info_apis.h" #include "eval/public/testing/matchers.h" #include "extensions/protobuf/memory_manager.h" #include "internal/testing.h" -#include "internal/testing_descriptor_pool.h" -#include "internal/testing_message_factory.h" -#include "cel/expr/conformance/proto3/test_all_types.pb.h" #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/message.h" @@ -35,7 +31,6 @@ namespace google::api::expr::runtime { namespace { using ::absl_testing::IsOk; -using ::cel::expr::conformance::proto3::TestAllTypes; using ::cel::extensions::ProtoMemoryManager; TEST(ProtobufDescriptorProvider, Basic) { @@ -101,60 +96,5 @@ TEST(ProtobufDescriptorProvider, NotFound) { ASSERT_FALSE(type_info.has_value()); } -TEST(ProtobufDescriptorProvider, FindType) { - ProtobufDescriptorProvider provider( - cel::internal::GetTestingDescriptorPool(), - cel::internal::GetTestingMessageFactory()); - ASSERT_OK_AND_ASSIGN(std::optional wrapper_type, - provider.FindType("google.protobuf.Int64Value")); - ASSERT_TRUE(wrapper_type.has_value()); - EXPECT_TRUE(wrapper_type->Is()); - EXPECT_EQ(wrapper_type->name(), "google.protobuf.Int64Value"); - - ASSERT_OK_AND_ASSIGN( - std::optional msg_type, - provider.FindType("cel.expr.conformance.proto3.TestAllTypes")); - ASSERT_TRUE(msg_type.has_value()); - EXPECT_TRUE(msg_type->Is()); - EXPECT_EQ(msg_type->name(), "cel.expr.conformance.proto3.TestAllTypes"); -} - -TEST(ProtobufDescriptorProvider, FindStructTypeFieldByName) { - ProtobufDescriptorProvider provider( - google::protobuf::DescriptorPool::generated_pool(), - google::protobuf::MessageFactory::generated_factory()); - ASSERT_OK_AND_ASSIGN(std::optional field, - provider.FindStructTypeFieldByName( - "google.protobuf.Int64Value", "value")); - ASSERT_TRUE(field.has_value()); - EXPECT_EQ(field->name(), "value"); - EXPECT_EQ(field->number(), 1); - EXPECT_EQ(field->GetType(), cel::IntType()); -} - -TEST(ProtobufDescriptorProvider, FindTypeNotFound) { - ProtobufDescriptorProvider provider( - google::protobuf::DescriptorPool::generated_pool(), - google::protobuf::MessageFactory::generated_factory()); - ASSERT_OK_AND_ASSIGN(std::optional type, - provider.FindType("UnknownType")); - EXPECT_FALSE(type.has_value()); -} - -TEST(ProtobufDescriptorProvider, FindStructTypeFieldByNameNotFound) { - ProtobufDescriptorProvider provider( - google::protobuf::DescriptorPool::generated_pool(), - google::protobuf::MessageFactory::generated_factory()); - ASSERT_OK_AND_ASSIGN(std::optional field, - provider.FindStructTypeFieldByName( - "google.protobuf.Int64Value", "unknown_field")); - EXPECT_FALSE(field.has_value()); - - ASSERT_OK_AND_ASSIGN( - std::optional field2, - provider.FindStructTypeFieldByName("UnknownType", "value")); - EXPECT_FALSE(field2.has_value()); -} - } // namespace } // namespace google::api::expr::runtime diff --git a/runtime/internal/BUILD b/runtime/internal/BUILD index 6c96de1cf..44671102a 100644 --- a/runtime/internal/BUILD +++ b/runtime/internal/BUILD @@ -181,10 +181,43 @@ cc_library( cc_library( name = "legacy_runtime_type_provider", + srcs = ["legacy_runtime_type_provider.cc"], hdrs = ["legacy_runtime_type_provider.h"], deps = [ + "//common:legacy_value", + "//common:memory", + "//common:type", + "//common:value", + "//eval/public:message_wrapper", + "//eval/public/structs:legacy_type_adapter", + "//eval/public/structs:legacy_type_info_apis", + "//eval/public/structs:proto_message_type_adapter", "//eval/public/structs:protobuf_descriptor_type_provider", + "//extensions/protobuf:memory_manager", + "//internal:status_macros", "@com_google_absl//absl/base:nullability", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:string_view", + "@com_google_absl//absl/types:optional", + "@com_google_protobuf//:protobuf", + ], +) + +cc_test( + name = "legacy_runtime_type_provider_test", + srcs = ["legacy_runtime_type_provider_test.cc"], + deps = [ + ":legacy_runtime_type_provider", + "//common:type", + "//common:value", + "//internal:testing", + "//internal:testing_descriptor_pool", + "//internal:testing_message_factory", + "@com_google_absl//absl/status:status_matchers", + "@com_google_absl//absl/types:optional", + "@com_google_cel_spec//proto/cel/expr/conformance/proto3:test_all_types_cc_proto", "@com_google_protobuf//:protobuf", ], ) diff --git a/eval/public/structs/legacy_type_provider.cc b/runtime/internal/legacy_runtime_type_provider.cc similarity index 62% rename from eval/public/structs/legacy_type_provider.cc rename to runtime/internal/legacy_runtime_type_provider.cc index cd7079451..5db0b448e 100644 --- a/eval/public/structs/legacy_type_provider.cc +++ b/runtime/internal/legacy_runtime_type_provider.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "eval/public/structs/legacy_type_provider.h" +#include "runtime/internal/legacy_runtime_type_provider.h" #include #include @@ -33,73 +33,21 @@ #include "eval/public/message_wrapper.h" #include "eval/public/structs/legacy_type_adapter.h" #include "eval/public/structs/legacy_type_info_apis.h" +#include "eval/public/structs/proto_message_type_adapter.h" #include "extensions/protobuf/memory_manager.h" #include "internal/status_macros.h" #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/message.h" -namespace google::api::expr::runtime { +namespace cel::runtime_internal { namespace { using google::api::expr::runtime::LegacyTypeAdapter; +using google::api::expr::runtime::LegacyTypeInfoApis; using google::api::expr::runtime::MessageWrapper; -class LegacyStructValueBuilder final : public cel::StructValueBuilder { - public: - LegacyStructValueBuilder(cel::MemoryManagerRef memory_manager, - LegacyTypeAdapter adapter, - MessageWrapper::Builder builder) - : memory_manager_(memory_manager), - adapter_(adapter), - builder_(std::move(builder)) {} - - absl::StatusOr> SetFieldByName( - absl::string_view name, cel::Value value) override { - CEL_ASSIGN_OR_RETURN( - auto legacy_value, - LegacyValue(cel::extensions::ProtoMemoryManagerArena(memory_manager_), - value), - _.With(cel::ErrorValueReturn())); - CEL_RETURN_IF_ERROR(adapter_.mutation_apis()->SetField( - name, legacy_value, memory_manager_, builder_)) - .With(cel::ErrorValueReturn()); - return std::nullopt; - } - - absl::StatusOr> SetFieldByNumber( - int64_t number, cel::Value value) override { - CEL_ASSIGN_OR_RETURN( - auto legacy_value, - LegacyValue(cel::extensions::ProtoMemoryManagerArena(memory_manager_), - value), - _.With(cel::ErrorValueReturn())); - CEL_RETURN_IF_ERROR(adapter_.mutation_apis()->SetFieldByNumber( - number, legacy_value, memory_manager_, builder_)) - .With(cel::ErrorValueReturn()); - return std::nullopt; - } - - absl::StatusOr Build() && override { - CEL_ASSIGN_OR_RETURN(auto message, - adapter_.mutation_apis()->AdaptFromWellKnownType( - memory_manager_, std::move(builder_))); - if (!message.IsMessage()) { - return absl::FailedPreconditionError("expected MessageWrapper"); - } - auto message_wrapper = message.MessageWrapperOrDie(); - return cel::common_internal::LegacyStructValue( - google::protobuf::DownCastMessage(message_wrapper.message_ptr()), - message_wrapper.legacy_type_info()); - } - - private: - cel::MemoryManagerRef memory_manager_; - LegacyTypeAdapter adapter_; - MessageWrapper::Builder builder_; -}; - class LegacyValueBuilder final : public cel::ValueBuilder { public: LegacyValueBuilder(cel::MemoryManagerRef memory_manager, @@ -155,28 +103,34 @@ class LegacyValueBuilder final : public cel::ValueBuilder { } // namespace -absl::StatusOr -LegacyTypeProvider::NewValueBuilder( +absl::StatusOr +LegacyRuntimeTypeProvider::NewValueBuilder( absl::string_view name, google::protobuf::MessageFactory* absl_nonnull message_factory, google::protobuf::Arena* absl_nonnull arena) const { - if (auto type_adapter = ProvideLegacyType(name); type_adapter.has_value()) { - const auto* mutation_apis = type_adapter->mutation_apis(); - if (mutation_apis == nullptr) { - return absl::FailedPreconditionError( - absl::StrCat("LegacyTypeMutationApis missing for type: ", name)); - } - CEL_ASSIGN_OR_RETURN( - auto builder, - mutation_apis->NewInstance(cel::MemoryManagerRef::Pooling(arena))); - return std::make_unique( - cel::MemoryManagerRef::Pooling(arena), *type_adapter, - std::move(builder)); + auto type_adapter = ProvideLegacyType(name); + + if (!type_adapter.has_value()) { + return nullptr; } - return nullptr; + + // We know the implementation should not do this, but can't prove it to type + // system. + // Defensive checks but impractical to exercise. + const auto* mutation_apis = type_adapter->mutation_apis(); + if (mutation_apis == nullptr) { + return absl::FailedPreconditionError( + absl::StrCat("LegacyTypeMutationApis missing for type: ", name)); + } + + CEL_ASSIGN_OR_RETURN( + auto builder, + mutation_apis->NewInstance(cel::MemoryManagerRef::Pooling(arena))); + return std::make_unique( + cel::MemoryManagerRef::Pooling(arena), *type_adapter, std::move(builder)); } -absl::StatusOr> LegacyTypeProvider::FindTypeImpl( +absl::StatusOr> LegacyRuntimeTypeProvider::FindTypeImpl( absl::string_view name) const { if (auto type = cel::FindWellKnownType(name); type.has_value()) { return type; @@ -192,14 +146,14 @@ absl::StatusOr> LegacyTypeProvider::FindTypeImpl( return std::nullopt; } -absl::StatusOr> -LegacyTypeProvider::FindStructTypeFieldByNameImpl( +absl::StatusOr> +LegacyRuntimeTypeProvider::FindStructTypeFieldByNameImpl( absl::string_view type, absl::string_view name) const { if (auto result = cel::FindWellKnownTypeFieldByName(type, name); result.has_value()) { return result; } - absl::optional type_info = + std::optional type_info = ProvideLegacyTypeInfo(type); if (!type_info.has_value()) { return std::nullopt; @@ -229,4 +183,4 @@ LegacyTypeProvider::FindStructTypeFieldByNameImpl( return cel::common_internal::BasicStructTypeField(name, 0, cel::DynType{}); } -} // namespace google::api::expr::runtime +} // namespace cel::runtime_internal diff --git a/runtime/internal/legacy_runtime_type_provider.h b/runtime/internal/legacy_runtime_type_provider.h index 503a79b46..45aef5d75 100644 --- a/runtime/internal/legacy_runtime_type_provider.h +++ b/runtime/internal/legacy_runtime_type_provider.h @@ -15,21 +15,42 @@ #ifndef THIRD_PARTY_CEL_CPP_RUNTIME_INTERNAL_LEGACY_RUNTIME_TYPE_PROVIDER_H_ #define THIRD_PARTY_CEL_CPP_RUNTIME_INTERNAL_LEGACY_RUNTIME_TYPE_PROVIDER_H_ +#include + #include "absl/base/nullability.h" +#include "absl/status/statusor.h" +#include "absl/strings/string_view.h" +#include "common/type.h" +#include "common/type_reflector.h" +#include "common/value.h" #include "eval/public/structs/protobuf_descriptor_type_provider.h" +#include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/message.h" namespace cel::runtime_internal { class LegacyRuntimeTypeProvider final - : public google::api::expr::runtime::ProtobufDescriptorProvider { + : public google::api::expr::runtime::ProtobufDescriptorProvider, + public TypeReflector { public: LegacyRuntimeTypeProvider( const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, google::protobuf::MessageFactory* absl_nullable message_factory) : google::api::expr::runtime::ProtobufDescriptorProvider( descriptor_pool, message_factory) {} + + absl::StatusOr NewValueBuilder( + absl::string_view name, + google::protobuf::MessageFactory* absl_nonnull message_factory, + google::protobuf::Arena* absl_nonnull arena) const override; + + protected: + absl::StatusOr> FindTypeImpl( + absl::string_view name) const override; + + absl::StatusOr> FindStructTypeFieldByNameImpl( + absl::string_view type, absl::string_view name) const override; }; } // namespace cel::runtime_internal diff --git a/runtime/internal/legacy_runtime_type_provider_test.cc b/runtime/internal/legacy_runtime_type_provider_test.cc new file mode 100644 index 000000000..eceac65a9 --- /dev/null +++ b/runtime/internal/legacy_runtime_type_provider_test.cc @@ -0,0 +1,121 @@ +// Copyright 2024 Google LLC +// +// 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 +// +// https://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. + +#include "runtime/internal/legacy_runtime_type_provider.h" + +#include +#include + +#include "common/type.h" +#include "common/value.h" +#include "internal/testing.h" +#include "internal/testing_descriptor_pool.h" +#include "internal/testing_message_factory.h" +#include "cel/expr/conformance/proto3/test_all_types.pb.h" +#include "google/protobuf/arena.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/message.h" + +namespace cel::runtime_internal { +namespace { + +using ::cel::expr::conformance::proto3::TestAllTypes; + +TEST(LegacyRuntimeTypeProviderTest, FindType) { + LegacyRuntimeTypeProvider provider(cel::internal::GetTestingDescriptorPool(), + cel::internal::GetTestingMessageFactory()); + ASSERT_OK_AND_ASSIGN(std::optional wrapper_type, + provider.FindType("google.protobuf.Int64Value")); + ASSERT_TRUE(wrapper_type.has_value()); + EXPECT_TRUE(wrapper_type->Is()); + EXPECT_EQ(wrapper_type->name(), "google.protobuf.Int64Value"); + + ASSERT_OK_AND_ASSIGN( + std::optional msg_type, + provider.FindType("cel.expr.conformance.proto3.TestAllTypes")); + ASSERT_TRUE(msg_type.has_value()); + EXPECT_TRUE(msg_type->Is()); + EXPECT_EQ(msg_type->name(), "cel.expr.conformance.proto3.TestAllTypes"); +} + +TEST(LegacyRuntimeTypeProviderTest, FindTypeNotFound) { + LegacyRuntimeTypeProvider provider( + google::protobuf::DescriptorPool::generated_pool(), + google::protobuf::MessageFactory::generated_factory()); + ASSERT_OK_AND_ASSIGN(std::optional type, + provider.FindType("UnknownType")); + EXPECT_FALSE(type.has_value()); +} + +TEST(LegacyRuntimeTypeProviderTest, FindStructTypeFieldByName) { + LegacyRuntimeTypeProvider provider( + google::protobuf::DescriptorPool::generated_pool(), + google::protobuf::MessageFactory::generated_factory()); + ASSERT_OK_AND_ASSIGN(std::optional field, + provider.FindStructTypeFieldByName( + "google.protobuf.Int64Value", "value")); + ASSERT_TRUE(field.has_value()); + EXPECT_EQ(field->name(), "value"); + EXPECT_EQ(field->number(), 1); + EXPECT_EQ(field->GetType(), IntType()); +} + +TEST(LegacyRuntimeTypeProviderTest, FindStructTypeFieldByNameNotFound) { + LegacyRuntimeTypeProvider provider( + google::protobuf::DescriptorPool::generated_pool(), + google::protobuf::MessageFactory::generated_factory()); + ASSERT_OK_AND_ASSIGN(std::optional field, + provider.FindStructTypeFieldByName( + "google.protobuf.Int64Value", "unknown_field")); + EXPECT_FALSE(field.has_value()); + + ASSERT_OK_AND_ASSIGN( + std::optional field2, + provider.FindStructTypeFieldByName("UnknownType", "value")); + EXPECT_FALSE(field2.has_value()); +} + +TEST(LegacyRuntimeTypeProviderTest, NewValueBuilder) { + LegacyRuntimeTypeProvider provider(cel::internal::GetTestingDescriptorPool(), + cel::internal::GetTestingMessageFactory()); + google::protobuf::Arena arena; + ASSERT_OK_AND_ASSIGN(auto builder, + provider.NewValueBuilder( + "cel.expr.conformance.proto3.TestAllTypes", + cel::internal::GetTestingMessageFactory(), &arena)); + ASSERT_NE(builder, nullptr); + + ASSERT_OK_AND_ASSIGN(auto field_result, + builder->SetFieldByName("single_int64", IntValue(42))); + EXPECT_FALSE(field_result.has_value()); + + ASSERT_OK_AND_ASSIGN(auto value, std::move(*builder).Build()); + EXPECT_TRUE(value.Is()); +} + +TEST(LegacyRuntimeTypeProviderTest, NewValueBuilderNotFound) { + LegacyRuntimeTypeProvider provider( + google::protobuf::DescriptorPool::generated_pool(), + google::protobuf::MessageFactory::generated_factory()); + google::protobuf::LinkMessageReflection(); + google::protobuf::Arena arena; + ASSERT_OK_AND_ASSIGN( + auto builder, + provider.NewValueBuilder( + "UnknownType", google::protobuf::MessageFactory::generated_factory(), &arena)); + EXPECT_EQ(builder, nullptr); +} + +} // namespace +} // namespace cel::runtime_internal