Skip to content

Commit 3b7c7d9

Browse files
jckingcopybara-github
authored andcommitted
Add dispatch table support for OpaqueValue
PiperOrigin-RevId: 736555181
1 parent e5f7fd1 commit 3b7c7d9

File tree

8 files changed

+751
-291
lines changed

8 files changed

+751
-291
lines changed

common/value_testing.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class OptionalValueMatcherImpl
152152
return false;
153153
}
154154
const auto& optional_value = v.GetOptional();
155-
if (!optional_value->HasValue()) {
155+
if (!optional_value.HasValue()) {
156156
*listener << "OptionalValue is not engaged";
157157
return false;
158158
}
@@ -177,7 +177,7 @@ MATCHER(OptionalValueIsEmptyImpl, "is empty OptionalValue") {
177177
}
178178
const auto& optional_value = v.GetOptional();
179179
*result_listener << (optional_value.HasValue() ? "is not empty" : "is empty");
180-
return !optional_value->HasValue();
180+
return !optional_value.HasValue();
181181
}
182182

183183
} // namespace

common/values/opaque_value.cc

Lines changed: 124 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,25 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#include <string>
1516
#include <type_traits>
1617
#include <utility>
1718

1819
#include "absl/base/nullability.h"
1920
#include "absl/base/optimization.h"
2021
#include "absl/log/absl_check.h"
22+
#include "absl/status/status.h"
23+
#include "absl/strings/cord.h"
24+
#include "absl/strings/str_cat.h"
25+
#include "absl/strings/string_view.h"
2126
#include "absl/types/optional.h"
22-
#include "common/memory.h"
2327
#include "common/native_type.h"
2428
#include "common/optional_ref.h"
29+
#include "common/type.h"
2530
#include "common/value.h"
2631
#include "google/protobuf/arena.h"
32+
#include "google/protobuf/descriptor.h"
33+
#include "google/protobuf/message.h"
2734

2835
namespace cel {
2936

@@ -36,18 +43,128 @@ OpaqueValue OpaqueValue::Clone(absl::Nonnull<google::protobuf::Arena*> arena) co
3643
ABSL_DCHECK(arena != nullptr);
3744
ABSL_DCHECK(*this);
3845

39-
if (ABSL_PREDICT_FALSE(!interface_)) {
40-
return OpaqueValue();
46+
if (ABSL_PREDICT_FALSE(dispatcher_ == nullptr)) {
47+
OpaqueValueInterface::Content content =
48+
content_.To<OpaqueValueInterface::Content>();
49+
if (content.interface == nullptr) {
50+
return *this;
51+
}
52+
if (content.arena != arena) {
53+
return content.interface->Clone(arena);
54+
}
55+
return *this;
4156
}
42-
if (interface_.arena() != arena) {
43-
return interface_->Clone(arena);
57+
if (dispatcher_->get_arena(dispatcher_, content_) != arena) {
58+
return dispatcher_->clone(dispatcher_, content_, arena);
4459
}
4560
return *this;
4661
}
4762

63+
OpaqueType OpaqueValue::GetRuntimeType() const {
64+
ABSL_DCHECK(*this);
65+
66+
if (ABSL_PREDICT_FALSE(dispatcher_ == nullptr)) {
67+
OpaqueValueInterface::Content content =
68+
content_.To<OpaqueValueInterface::Content>();
69+
ABSL_DCHECK(content.interface != nullptr);
70+
return content.interface->GetRuntimeType();
71+
}
72+
return dispatcher_->get_runtime_type(dispatcher_, content_);
73+
}
74+
75+
absl::string_view OpaqueValue::GetTypeName() const {
76+
ABSL_DCHECK(*this);
77+
78+
if (ABSL_PREDICT_FALSE(dispatcher_ == nullptr)) {
79+
OpaqueValueInterface::Content content =
80+
content_.To<OpaqueValueInterface::Content>();
81+
ABSL_DCHECK(content.interface != nullptr);
82+
return content.interface->GetTypeName();
83+
}
84+
return dispatcher_->get_type_name(dispatcher_, content_);
85+
}
86+
87+
std::string OpaqueValue::DebugString() const {
88+
ABSL_DCHECK(*this);
89+
90+
if (ABSL_PREDICT_FALSE(dispatcher_ == nullptr)) {
91+
OpaqueValueInterface::Content content =
92+
content_.To<OpaqueValueInterface::Content>();
93+
ABSL_DCHECK(content.interface != nullptr);
94+
return content.interface->DebugString();
95+
}
96+
return dispatcher_->debug_string(dispatcher_, content_);
97+
}
98+
99+
// See Value::SerializeTo().
100+
absl::Status OpaqueValue::SerializeTo(
101+
absl::Nonnull<const google::protobuf::DescriptorPool*> descriptor_pool,
102+
absl::Nonnull<google::protobuf::MessageFactory*> message_factory,
103+
absl::Nonnull<absl::Cord*> value) const {
104+
ABSL_DCHECK(descriptor_pool != nullptr);
105+
ABSL_DCHECK(message_factory != nullptr);
106+
ABSL_DCHECK(value != nullptr);
107+
108+
return absl::FailedPreconditionError(
109+
absl::StrCat(GetTypeName(), "is unserializable"));
110+
}
111+
112+
// See Value::ConvertToJson().
113+
absl::Status OpaqueValue::ConvertToJson(
114+
absl::Nonnull<const google::protobuf::DescriptorPool*> descriptor_pool,
115+
absl::Nonnull<google::protobuf::MessageFactory*> message_factory,
116+
absl::Nonnull<google::protobuf::Message*> json) const {
117+
ABSL_DCHECK(descriptor_pool != nullptr);
118+
ABSL_DCHECK(message_factory != nullptr);
119+
ABSL_DCHECK(json != nullptr);
120+
121+
return absl::FailedPreconditionError(
122+
absl::StrCat(GetTypeName(), " is not convertable to JSON"));
123+
}
124+
125+
absl::Status OpaqueValue::Equal(
126+
const Value& other,
127+
absl::Nonnull<const google::protobuf::DescriptorPool*> descriptor_pool,
128+
absl::Nonnull<google::protobuf::MessageFactory*> message_factory,
129+
absl::Nonnull<google::protobuf::Arena*> arena, absl::Nonnull<Value*> result) const {
130+
ABSL_DCHECK(descriptor_pool != nullptr);
131+
ABSL_DCHECK(message_factory != nullptr);
132+
ABSL_DCHECK(arena != nullptr);
133+
ABSL_DCHECK(result != nullptr);
134+
135+
if (auto other_opaque = other.AsOpaque(); other_opaque) {
136+
if (ABSL_PREDICT_FALSE(dispatcher_ == nullptr)) {
137+
OpaqueValueInterface::Content content =
138+
content_.To<OpaqueValueInterface::Content>();
139+
ABSL_DCHECK(content.interface != nullptr);
140+
return content.interface->Equal(*other_opaque, descriptor_pool,
141+
message_factory, arena, result);
142+
}
143+
return dispatcher_->equal(dispatcher_, content_, *other_opaque,
144+
descriptor_pool, message_factory, arena, result);
145+
}
146+
*result = FalseValue();
147+
return absl::OkStatus();
148+
}
149+
150+
NativeTypeId OpaqueValue::GetTypeId() const {
151+
ABSL_DCHECK(*this);
152+
153+
if (ABSL_PREDICT_FALSE(dispatcher_ == nullptr)) {
154+
OpaqueValueInterface::Content content =
155+
content_.To<OpaqueValueInterface::Content>();
156+
if (content.interface == nullptr) {
157+
return NativeTypeId();
158+
}
159+
return NativeTypeId::Of(*content.interface);
160+
}
161+
return dispatcher_->get_type_id(dispatcher_, content_);
162+
}
163+
48164
bool OpaqueValue::IsOptional() const {
49-
return NativeTypeId::Of(*interface_) ==
50-
NativeTypeId::For<OptionalValueInterface>();
165+
return dispatcher_ != nullptr &&
166+
dispatcher_->get_type_id(dispatcher_, content_) ==
167+
NativeTypeId::For<OptionalValue>();
51168
}
52169

53170
optional_ref<const OptionalValue> OpaqueValue::AsOptional() const& {

0 commit comments

Comments
 (0)