From 035cea4364184e52d24626e83f0846d59e8746f1 Mon Sep 17 00:00:00 2001 From: Jonathan Tatum Date: Wed, 12 Aug 2026 09:34:43 -0700 Subject: [PATCH] Restrict usages of TrivialTypeInfo to the singleton. PiperOrigin-RevId: 963494493 --- eval/public/BUILD | 7 +++++++ eval/public/structs/BUILD | 1 + eval/public/structs/trivial_legacy_type_info.h | 14 ++++++++++++-- .../structs/trivial_legacy_type_info_test.cc | 8 -------- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/eval/public/BUILD b/eval/public/BUILD index 7e172cd94..0c9c6f23e 100644 --- a/eval/public/BUILD +++ b/eval/public/BUILD @@ -29,6 +29,13 @@ licenses(["notice"]) exports_files(["LICENSE"]) +# No new users should depend on MessageWrapper using legacy APIs. +# This was added as a temporary workaround for implementing custom reflection operations +# on messages that were compiled with the LITE_RUNTIME (MessageLite) option. +# Internally, we now assume legacy Message types are always normal (Message) protobuf messages with +# standard reflection operations. +# Custom structs (including MessageLite protos) should use the modern API (see +# `cel::CustomStructValue`). cc_library( name = "message_wrapper", hdrs = [ diff --git a/eval/public/structs/BUILD b/eval/public/structs/BUILD index 14bd607a3..82e6fd5de 100644 --- a/eval/public/structs/BUILD +++ b/eval/public/structs/BUILD @@ -374,6 +374,7 @@ cc_library( ":legacy_type_info_apis", "//eval/public:message_wrapper", "@com_google_absl//absl/base:no_destructor", + "@com_google_absl//absl/base:nullability", "@com_google_absl//absl/strings:string_view", ], ) diff --git a/eval/public/structs/trivial_legacy_type_info.h b/eval/public/structs/trivial_legacy_type_info.h index 2189bd478..dd413e723 100644 --- a/eval/public/structs/trivial_legacy_type_info.h +++ b/eval/public/structs/trivial_legacy_type_info.h @@ -18,6 +18,7 @@ #include #include "absl/base/no_destructor.h" +#include "absl/base/nullability.h" #include "absl/strings/string_view.h" #include "eval/public/message_wrapper.h" #include "eval/public/structs/legacy_type_info_apis.h" @@ -27,7 +28,12 @@ namespace google::api::expr::runtime { // Implementation of type info APIs suitable for testing where no message // operations need to be supported. class TrivialTypeInfo : public LegacyTypeInfoApis { + private: + struct Key {}; + public: + explicit TrivialTypeInfo(Key&) {} + absl::string_view GetTypename(const MessageWrapper& wrapper) const override { return "opaque"; } @@ -43,10 +49,14 @@ class TrivialTypeInfo : public LegacyTypeInfoApis { return nullptr; } - static const TrivialTypeInfo* GetInstance() { - static absl::NoDestructor kInstance; + static const TrivialTypeInfo* absl_nonnull GetInstance() { + static absl::NoDestructor kKey; + static absl::NoDestructor kInstance(*kKey); return &*kInstance; } + + private: + TrivialTypeInfo() = default; }; } // namespace google::api::expr::runtime diff --git a/eval/public/structs/trivial_legacy_type_info_test.cc b/eval/public/structs/trivial_legacy_type_info_test.cc index ea7b3977e..5001c85d5 100644 --- a/eval/public/structs/trivial_legacy_type_info_test.cc +++ b/eval/public/structs/trivial_legacy_type_info_test.cc @@ -21,35 +21,27 @@ namespace google::api::expr::runtime { namespace { TEST(TrivialTypeInfo, GetTypename) { - TrivialTypeInfo info; MessageWrapper wrapper; - EXPECT_EQ(info.GetTypename(wrapper), "opaque"); EXPECT_EQ(TrivialTypeInfo::GetInstance()->GetTypename(wrapper), "opaque"); } TEST(TrivialTypeInfo, DebugString) { - TrivialTypeInfo info; MessageWrapper wrapper; - EXPECT_EQ(info.DebugString(wrapper), "opaque"); EXPECT_EQ(TrivialTypeInfo::GetInstance()->DebugString(wrapper), "opaque"); } TEST(TrivialTypeInfo, GetAccessApis) { - TrivialTypeInfo info; MessageWrapper wrapper; - EXPECT_EQ(info.GetAccessApis(wrapper), nullptr); EXPECT_EQ(TrivialTypeInfo::GetInstance()->GetAccessApis(wrapper), nullptr); } TEST(TrivialTypeInfo, FindFieldByName) { - TrivialTypeInfo info; MessageWrapper wrapper; - EXPECT_EQ(info.FindFieldByName("foo"), std::nullopt); EXPECT_EQ(TrivialTypeInfo::GetInstance()->FindFieldByName("foo"), std::nullopt); }