/proc/self/cwd/common/legacy_value.cc
Line | Count | Source |
1 | | // Copyright 2024 Google LLC |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include "common/legacy_value.h" |
16 | | |
17 | | #include <cstddef> |
18 | | #include <cstdint> |
19 | | #include <memory> |
20 | | #include <string> |
21 | | #include <utility> |
22 | | #include <vector> |
23 | | |
24 | | #include "google/protobuf/struct.pb.h" |
25 | | #include "absl/base/attributes.h" |
26 | | #include "absl/base/nullability.h" |
27 | | #include "absl/base/optimization.h" |
28 | | #include "absl/functional/overload.h" |
29 | | #include "absl/log/absl_check.h" |
30 | | #include "absl/status/status.h" |
31 | | #include "absl/status/statusor.h" |
32 | | #include "absl/strings/cord.h" |
33 | | #include "absl/strings/str_cat.h" |
34 | | #include "absl/strings/string_view.h" |
35 | | #include "absl/types/optional.h" |
36 | | #include "absl/types/span.h" |
37 | | #include "absl/types/variant.h" |
38 | | #include "base/attribute.h" |
39 | | #include "common/casting.h" |
40 | | #include "common/kind.h" |
41 | | #include "common/memory.h" |
42 | | #include "common/type.h" |
43 | | #include "common/unknown.h" |
44 | | #include "common/value.h" |
45 | | #include "common/value_kind.h" |
46 | | #include "common/values/list_value_builder.h" |
47 | | #include "common/values/map_value_builder.h" |
48 | | #include "common/values/values.h" |
49 | | #include "eval/internal/cel_value_equal.h" |
50 | | #include "eval/public/cel_value.h" |
51 | | #include "eval/public/containers/field_backed_list_impl.h" |
52 | | #include "eval/public/containers/field_backed_map_impl.h" |
53 | | #include "eval/public/message_wrapper.h" |
54 | | #include "eval/public/structs/cel_proto_wrap_util.h" |
55 | | #include "eval/public/structs/legacy_type_adapter.h" |
56 | | #include "eval/public/structs/legacy_type_info_apis.h" |
57 | | #include "eval/public/structs/proto_message_type_adapter.h" |
58 | | #include "internal/json.h" |
59 | | #include "internal/status_macros.h" |
60 | | #include "internal/well_known_types.h" |
61 | | #include "runtime/runtime_options.h" |
62 | | #include "google/protobuf/arena.h" |
63 | | #include "google/protobuf/descriptor.h" |
64 | | #include "google/protobuf/io/zero_copy_stream.h" |
65 | | #include "google/protobuf/message.h" |
66 | | #include "google/protobuf/message_lite.h" |
67 | | |
68 | | // TODO(uncreated-issue/76): improve coverage for JSON/Any handling |
69 | | |
70 | | namespace cel { |
71 | | |
72 | | namespace { |
73 | | |
74 | | using google::api::expr::runtime::CelList; |
75 | | using google::api::expr::runtime::CelMap; |
76 | | using google::api::expr::runtime::CelValue; |
77 | | using google::api::expr::runtime::FieldBackedListImpl; |
78 | | using google::api::expr::runtime::FieldBackedMapImpl; |
79 | | using google::api::expr::runtime::GetGenericProtoTypeInfoInstance; |
80 | | using google::api::expr::runtime::LegacyTypeInfoApis; |
81 | | using google::api::expr::runtime::MessageWrapper; |
82 | | using ::google::api::expr::runtime::internal::MaybeWrapValueToMessage; |
83 | | |
84 | 28 | absl::Status InvalidMapKeyTypeError(ValueKind kind) { |
85 | 28 | return absl::InvalidArgumentError( |
86 | 28 | absl::StrCat("Invalid map key type: '", ValueKindToString(kind), "'")); |
87 | 28 | } |
88 | | |
89 | | MessageWrapper AsMessageWrapper( |
90 | | const google::protobuf::Message* absl_nullability_unknown message_ptr, |
91 | 285 | const LegacyTypeInfoApis* absl_nullability_unknown type_info) { |
92 | 285 | return MessageWrapper(message_ptr, type_info); |
93 | 285 | } |
94 | | |
95 | | class CelListIterator final : public ValueIterator { |
96 | | public: |
97 | | explicit CelListIterator(const CelList* cel_list) |
98 | 0 | : cel_list_(cel_list), size_(cel_list_->size()) {} |
99 | | |
100 | 0 | bool HasNext() override { return index_ < size_; } |
101 | | |
102 | | absl::Status Next(const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
103 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
104 | | google::protobuf::Arena* absl_nonnull arena, |
105 | 0 | Value* absl_nonnull result) override { |
106 | 0 | if (!HasNext()) { |
107 | 0 | return absl::FailedPreconditionError( |
108 | 0 | "ValueIterator::Next() called when ValueIterator::HasNext() returns " |
109 | 0 | "false"); |
110 | 0 | } |
111 | 0 | auto cel_value = cel_list_->Get(arena, index_); |
112 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, cel_value, *result)); |
113 | 0 | ++index_; |
114 | 0 | return absl::OkStatus(); |
115 | 0 | } |
116 | | |
117 | | absl::StatusOr<bool> Next1( |
118 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
119 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
120 | | google::protobuf::Arena* absl_nonnull arena, |
121 | 0 | Value* absl_nonnull key_or_value) override { |
122 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
123 | 0 | ABSL_DCHECK(message_factory != nullptr); |
124 | 0 | ABSL_DCHECK(arena != nullptr); |
125 | 0 | ABSL_DCHECK(key_or_value != nullptr); |
126 | |
|
127 | 0 | if (index_ >= size_) { |
128 | 0 | return false; |
129 | 0 | } |
130 | 0 | auto cel_value = cel_list_->Get(arena, index_); |
131 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, cel_value, *key_or_value)); |
132 | 0 | ++index_; |
133 | 0 | return true; |
134 | 0 | } |
135 | | |
136 | | absl::StatusOr<bool> Next2( |
137 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
138 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
139 | | google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull key, |
140 | 0 | Value* absl_nullable value) override { |
141 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
142 | 0 | ABSL_DCHECK(message_factory != nullptr); |
143 | 0 | ABSL_DCHECK(arena != nullptr); |
144 | 0 | ABSL_DCHECK(key != nullptr); |
145 | |
|
146 | 0 | if (index_ >= size_) { |
147 | 0 | return false; |
148 | 0 | } |
149 | 0 | if (value != nullptr) { |
150 | 0 | auto cel_value = cel_list_->Get(arena, index_); |
151 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, cel_value, *value)); |
152 | 0 | } |
153 | 0 | *key = IntValue(index_); |
154 | 0 | ++index_; |
155 | 0 | return true; |
156 | 0 | } |
157 | | |
158 | | private: |
159 | | const CelList* const cel_list_; |
160 | | const int size_; |
161 | | int index_ = 0; |
162 | | }; |
163 | | |
164 | | class CelMapIterator final : public ValueIterator { |
165 | | public: |
166 | | explicit CelMapIterator(const CelMap* cel_map) |
167 | 0 | : cel_map_(cel_map), size_(cel_map->size()) {} |
168 | | |
169 | 0 | bool HasNext() override { return index_ < size_; } |
170 | | |
171 | | absl::Status Next(const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
172 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
173 | | google::protobuf::Arena* absl_nonnull arena, |
174 | 0 | Value* absl_nonnull result) override { |
175 | 0 | if (!HasNext()) { |
176 | 0 | return absl::FailedPreconditionError( |
177 | 0 | "ValueIterator::Next() called when ValueIterator::HasNext() returns " |
178 | 0 | "false"); |
179 | 0 | } |
180 | 0 | CEL_RETURN_IF_ERROR(ProjectKeys(arena)); |
181 | 0 | auto cel_value = (*cel_list_)->Get(arena, index_); |
182 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, cel_value, *result)); |
183 | 0 | ++index_; |
184 | 0 | return absl::OkStatus(); |
185 | 0 | } |
186 | | |
187 | | absl::StatusOr<bool> Next1( |
188 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
189 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
190 | | google::protobuf::Arena* absl_nonnull arena, |
191 | 0 | Value* absl_nonnull key_or_value) override { |
192 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
193 | 0 | ABSL_DCHECK(message_factory != nullptr); |
194 | 0 | ABSL_DCHECK(arena != nullptr); |
195 | 0 | ABSL_DCHECK(key_or_value != nullptr); |
196 | |
|
197 | 0 | if (index_ >= size_) { |
198 | 0 | return false; |
199 | 0 | } |
200 | 0 | CEL_RETURN_IF_ERROR(ProjectKeys(arena)); |
201 | 0 | auto cel_value = (*cel_list_)->Get(arena, index_); |
202 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, cel_value, *key_or_value)); |
203 | 0 | ++index_; |
204 | 0 | return true; |
205 | 0 | } |
206 | | |
207 | | absl::StatusOr<bool> Next2( |
208 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
209 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
210 | | google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull key, |
211 | 0 | Value* absl_nullable value) override { |
212 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
213 | 0 | ABSL_DCHECK(message_factory != nullptr); |
214 | 0 | ABSL_DCHECK(arena != nullptr); |
215 | 0 | ABSL_DCHECK(key != nullptr); |
216 | |
|
217 | 0 | if (index_ >= size_) { |
218 | 0 | return false; |
219 | 0 | } |
220 | 0 | CEL_RETURN_IF_ERROR(ProjectKeys(arena)); |
221 | 0 | auto cel_key = (*cel_list_)->Get(arena, index_); |
222 | 0 | if (value != nullptr) { |
223 | 0 | auto cel_value = cel_map_->Get(arena, cel_key); |
224 | 0 | if (!cel_value) { |
225 | 0 | return absl::DataLossError( |
226 | 0 | "map iterator returned key that was not present in the map"); |
227 | 0 | } |
228 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, *cel_value, *value)); |
229 | 0 | } |
230 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, cel_key, *key)); |
231 | 0 | ++index_; |
232 | 0 | return true; |
233 | 0 | } |
234 | | |
235 | | private: |
236 | 0 | absl::Status ProjectKeys(google::protobuf::Arena* arena) { |
237 | 0 | if (cel_list_.ok() && *cel_list_ == nullptr) { |
238 | 0 | cel_list_ = cel_map_->ListKeys(arena); |
239 | 0 | } |
240 | 0 | return cel_list_.status(); |
241 | 0 | } |
242 | | |
243 | | const CelMap* const cel_map_; |
244 | | const int size_ = 0; |
245 | | absl::StatusOr<const CelList*> cel_list_ = nullptr; |
246 | | int index_ = 0; |
247 | | }; |
248 | | |
249 | | } // namespace |
250 | | |
251 | | namespace common_internal { |
252 | | |
253 | | namespace { |
254 | | |
255 | | CelValue LegacyTrivialStructValue(google::protobuf::Arena* absl_nonnull arena, |
256 | 1 | const Value& value) { |
257 | 1 | if (auto legacy_struct_value = common_internal::AsLegacyStructValue(value); |
258 | 1 | legacy_struct_value) { |
259 | 1 | return CelValue::CreateMessageWrapper( |
260 | 1 | AsMessageWrapper(legacy_struct_value->message_ptr(), |
261 | 1 | legacy_struct_value->legacy_type_info())); |
262 | 1 | } |
263 | 0 | if (auto parsed_message_value = value.AsParsedMessage(); |
264 | 0 | parsed_message_value) { |
265 | 0 | auto maybe_cloned = parsed_message_value->Clone(arena); |
266 | 0 | return CelValue::CreateMessageWrapper(MessageWrapper( |
267 | 0 | cel::to_address(maybe_cloned), &GetGenericProtoTypeInfoInstance())); |
268 | 0 | } |
269 | 0 | return CelValue::CreateError(google::protobuf::Arena::Create<absl::Status>( |
270 | 0 | arena, absl::InvalidArgumentError(absl::StrCat( |
271 | 0 | "unsupported conversion from cel::StructValue to CelValue: ", |
272 | 0 | value.GetRuntimeType().DebugString())))); |
273 | 0 | } |
274 | | |
275 | | CelValue LegacyTrivialListValue(google::protobuf::Arena* absl_nonnull arena, |
276 | 274 | const Value& value) { |
277 | 274 | if (auto legacy_list_value = common_internal::AsLegacyListValue(value); |
278 | 274 | legacy_list_value) { |
279 | 274 | return CelValue::CreateList(legacy_list_value->cel_list()); |
280 | 274 | } |
281 | 0 | if (auto parsed_repeated_field_value = value.AsParsedRepeatedField(); |
282 | 0 | parsed_repeated_field_value) { |
283 | 0 | auto maybe_cloned = parsed_repeated_field_value->Clone(arena); |
284 | 0 | return CelValue::CreateList(google::protobuf::Arena::Create<FieldBackedListImpl>( |
285 | 0 | arena, &maybe_cloned.message(), maybe_cloned.field(), arena)); |
286 | 0 | } |
287 | 0 | if (auto parsed_json_list_value = value.AsParsedJsonList(); |
288 | 0 | parsed_json_list_value) { |
289 | 0 | auto maybe_cloned = parsed_json_list_value->Clone(arena); |
290 | 0 | return CelValue::CreateList(google::protobuf::Arena::Create<FieldBackedListImpl>( |
291 | 0 | arena, cel::to_address(maybe_cloned), |
292 | 0 | well_known_types::GetListValueReflectionOrDie( |
293 | 0 | maybe_cloned->GetDescriptor()) |
294 | 0 | .GetValuesDescriptor(), |
295 | 0 | arena)); |
296 | 0 | } |
297 | 0 | if (auto custom_list_value = value.AsCustomList(); custom_list_value) { |
298 | 0 | auto status_or_compat_list = common_internal::MakeCompatListValue( |
299 | 0 | *custom_list_value, google::protobuf::DescriptorPool::generated_pool(), |
300 | 0 | google::protobuf::MessageFactory::generated_factory(), arena); |
301 | 0 | if (!status_or_compat_list.ok()) { |
302 | 0 | return CelValue::CreateError(google::protobuf::Arena::Create<absl::Status>( |
303 | 0 | arena, std::move(status_or_compat_list).status())); |
304 | 0 | } |
305 | 0 | return CelValue::CreateList(*status_or_compat_list); |
306 | 0 | } |
307 | 0 | return CelValue::CreateError(google::protobuf::Arena::Create<absl::Status>( |
308 | 0 | arena, absl::InvalidArgumentError(absl::StrCat( |
309 | 0 | "unsupported conversion from cel::ListValue to CelValue: ", |
310 | 0 | value.GetRuntimeType().DebugString())))); |
311 | 0 | } |
312 | | |
313 | | CelValue LegacyTrivialMapValue(google::protobuf::Arena* absl_nonnull arena, |
314 | 44 | const Value& value) { |
315 | 44 | if (auto legacy_map_value = common_internal::AsLegacyMapValue(value); |
316 | 44 | legacy_map_value) { |
317 | 44 | return CelValue::CreateMap(legacy_map_value->cel_map()); |
318 | 44 | } |
319 | 0 | if (auto parsed_map_field_value = value.AsParsedMapField(); |
320 | 0 | parsed_map_field_value) { |
321 | 0 | auto maybe_cloned = parsed_map_field_value->Clone(arena); |
322 | 0 | return CelValue::CreateMap(google::protobuf::Arena::Create<FieldBackedMapImpl>( |
323 | 0 | arena, &maybe_cloned.message(), maybe_cloned.field(), arena)); |
324 | 0 | } |
325 | 0 | if (auto parsed_json_map_value = value.AsParsedJsonMap(); |
326 | 0 | parsed_json_map_value) { |
327 | 0 | auto maybe_cloned = parsed_json_map_value->Clone(arena); |
328 | 0 | return CelValue::CreateMap(google::protobuf::Arena::Create<FieldBackedMapImpl>( |
329 | 0 | arena, cel::to_address(maybe_cloned), |
330 | 0 | well_known_types::GetStructReflectionOrDie( |
331 | 0 | maybe_cloned->GetDescriptor()) |
332 | 0 | .GetFieldsDescriptor(), |
333 | 0 | arena)); |
334 | 0 | } |
335 | 0 | if (auto custom_map_value = value.AsCustomMap(); custom_map_value) { |
336 | 0 | auto status_or_compat_map = common_internal::MakeCompatMapValue( |
337 | 0 | *custom_map_value, google::protobuf::DescriptorPool::generated_pool(), |
338 | 0 | google::protobuf::MessageFactory::generated_factory(), arena); |
339 | 0 | if (!status_or_compat_map.ok()) { |
340 | 0 | return CelValue::CreateError(google::protobuf::Arena::Create<absl::Status>( |
341 | 0 | arena, std::move(status_or_compat_map).status())); |
342 | 0 | } |
343 | 0 | return CelValue::CreateMap(*status_or_compat_map); |
344 | 0 | } |
345 | 0 | return CelValue::CreateError(google::protobuf::Arena::Create<absl::Status>( |
346 | 0 | arena, absl::InvalidArgumentError(absl::StrCat( |
347 | 0 | "unsupported conversion from cel::MapValue to CelValue: ", |
348 | 0 | value.GetRuntimeType().DebugString())))); |
349 | 0 | } |
350 | | |
351 | | } // namespace |
352 | | |
353 | | google::api::expr::runtime::CelValue UnsafeLegacyValue( |
354 | 0 | const Value& value, bool stable, google::protobuf::Arena* absl_nonnull arena) { |
355 | 0 | switch (value.kind()) { |
356 | 0 | case ValueKind::kNull: |
357 | 0 | return CelValue::CreateNull(); |
358 | 0 | case ValueKind::kBool: |
359 | 0 | return CelValue::CreateBool(value.GetBool()); |
360 | 0 | case ValueKind::kInt: |
361 | 0 | return CelValue::CreateInt64(value.GetInt()); |
362 | 0 | case ValueKind::kUint: |
363 | 0 | return CelValue::CreateUint64(value.GetUint()); |
364 | 0 | case ValueKind::kDouble: |
365 | 0 | return CelValue::CreateDouble(value.GetDouble()); |
366 | 0 | case ValueKind::kString: |
367 | 0 | return CelValue::CreateStringView( |
368 | 0 | LegacyStringValue(value.GetString(), stable, arena)); |
369 | 0 | case ValueKind::kBytes: |
370 | 0 | return CelValue::CreateBytesView( |
371 | 0 | LegacyBytesValue(value.GetBytes(), stable, arena)); |
372 | 0 | case ValueKind::kStruct: |
373 | 0 | return LegacyTrivialStructValue(arena, value); |
374 | 0 | case ValueKind::kDuration: |
375 | 0 | return CelValue::CreateDuration(value.GetDuration().ToDuration()); |
376 | 0 | case ValueKind::kTimestamp: |
377 | 0 | return CelValue::CreateTimestamp(value.GetTimestamp().ToTime()); |
378 | 0 | case ValueKind::kList: |
379 | 0 | return LegacyTrivialListValue(arena, value); |
380 | 0 | case ValueKind::kMap: |
381 | 0 | return LegacyTrivialMapValue(arena, value); |
382 | 0 | case ValueKind::kType: |
383 | 0 | return CelValue::CreateCelTypeView(value.GetType().name()); |
384 | 0 | default: |
385 | | // Everything else is unsupported. |
386 | 0 | return CelValue::CreateError(google::protobuf::Arena::Create<absl::Status>( |
387 | 0 | arena, absl::InvalidArgumentError(absl::StrCat( |
388 | 0 | "unsupported conversion from cel::Value to CelValue: ", |
389 | 0 | value->GetRuntimeType().DebugString())))); |
390 | 0 | } |
391 | 0 | } |
392 | | |
393 | | } // namespace common_internal |
394 | | |
395 | | namespace common_internal { |
396 | | |
397 | 0 | std::string LegacyListValue::DebugString() const { |
398 | 0 | return CelValue::CreateList(impl_).DebugString(); |
399 | 0 | } |
400 | | |
401 | | // See `ValueInterface::SerializeTo`. |
402 | | absl::Status LegacyListValue::SerializeTo( |
403 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
404 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
405 | 0 | google::protobuf::io::ZeroCopyOutputStream* absl_nonnull output) const { |
406 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
407 | 0 | ABSL_DCHECK(message_factory != nullptr); |
408 | 0 | ABSL_DCHECK(output != nullptr); |
409 | |
|
410 | 0 | const google::protobuf::Descriptor* descriptor = |
411 | 0 | descriptor_pool->FindMessageTypeByName("google.protobuf.ListValue"); |
412 | 0 | if (descriptor == nullptr) { |
413 | 0 | return absl::InternalError( |
414 | 0 | "unable to locate descriptor for message type: " |
415 | 0 | "google.protobuf.ListValue"); |
416 | 0 | } |
417 | | |
418 | 0 | google::protobuf::Arena arena; |
419 | 0 | const google::protobuf::Message* wrapped = MaybeWrapValueToMessage( |
420 | 0 | descriptor, message_factory, CelValue::CreateList(impl_), &arena); |
421 | 0 | if (wrapped == nullptr) { |
422 | 0 | return absl::UnknownError("failed to convert legacy map to JSON"); |
423 | 0 | } |
424 | 0 | if (!wrapped->SerializePartialToZeroCopyStream(output)) { |
425 | 0 | return absl::UnknownError( |
426 | 0 | absl::StrCat("failed to serialize message: ", wrapped->GetTypeName())); |
427 | 0 | } |
428 | 0 | return absl::OkStatus(); |
429 | 0 | } |
430 | | |
431 | | absl::Status LegacyListValue::ConvertToJson( |
432 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
433 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
434 | 0 | google::protobuf::Message* absl_nonnull json) const { |
435 | 0 | { |
436 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
437 | 0 | ABSL_DCHECK(message_factory != nullptr); |
438 | 0 | ABSL_DCHECK(json != nullptr); |
439 | 0 | ABSL_DCHECK_EQ(json->GetDescriptor()->well_known_type(), |
440 | 0 | google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE); |
441 | |
|
442 | 0 | google::protobuf::Arena arena; |
443 | 0 | const google::protobuf::Message* wrapped = |
444 | 0 | MaybeWrapValueToMessage(json->GetDescriptor(), message_factory, |
445 | 0 | CelValue::CreateList(impl_), &arena); |
446 | 0 | if (wrapped == nullptr) { |
447 | 0 | return absl::UnknownError("failed to convert legacy list to JSON"); |
448 | 0 | } |
449 | | |
450 | 0 | if (wrapped->GetDescriptor() == json->GetDescriptor()) { |
451 | | // We can directly use google::protobuf::Message::Copy(). |
452 | 0 | json->CopyFrom(*wrapped); |
453 | 0 | } else { |
454 | | // Equivalent descriptors but not identical. Must serialize and |
455 | | // deserialize. |
456 | 0 | absl::Cord serialized; |
457 | 0 | if (!wrapped->SerializePartialToString(&serialized)) { |
458 | 0 | return absl::UnknownError(absl::StrCat("failed to serialize message: ", |
459 | 0 | wrapped->GetTypeName())); |
460 | 0 | } |
461 | 0 | if (!json->ParsePartialFromString(serialized)) { |
462 | 0 | return absl::UnknownError( |
463 | 0 | absl::StrCat("failed to parsed message: ", json->GetTypeName())); |
464 | 0 | } |
465 | 0 | } |
466 | 0 | return absl::OkStatus(); |
467 | 0 | } |
468 | 0 | } |
469 | | |
470 | | absl::Status LegacyListValue::ConvertToJsonArray( |
471 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
472 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
473 | 0 | google::protobuf::Message* absl_nonnull json) const { |
474 | 0 | { |
475 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
476 | 0 | ABSL_DCHECK(message_factory != nullptr); |
477 | 0 | ABSL_DCHECK(json != nullptr); |
478 | 0 | ABSL_DCHECK_EQ(json->GetDescriptor()->well_known_type(), |
479 | 0 | google::protobuf::Descriptor::WELLKNOWNTYPE_LISTVALUE); |
480 | |
|
481 | 0 | google::protobuf::Arena arena; |
482 | 0 | const google::protobuf::Message* wrapped = |
483 | 0 | MaybeWrapValueToMessage(json->GetDescriptor(), message_factory, |
484 | 0 | CelValue::CreateList(impl_), &arena); |
485 | 0 | if (wrapped == nullptr) { |
486 | 0 | return absl::UnknownError("failed to convert legacy list to JSON"); |
487 | 0 | } |
488 | | |
489 | 0 | if (wrapped->GetDescriptor() == json->GetDescriptor()) { |
490 | | // We can directly use google::protobuf::Message::Copy(). |
491 | 0 | json->CopyFrom(*wrapped); |
492 | 0 | } else { |
493 | | // Equivalent descriptors but not identical. Must serialize and |
494 | | // deserialize. |
495 | 0 | absl::Cord serialized; |
496 | 0 | if (!wrapped->SerializePartialToString(&serialized)) { |
497 | 0 | return absl::UnknownError(absl::StrCat("failed to serialize message: ", |
498 | 0 | wrapped->GetTypeName())); |
499 | 0 | } |
500 | 0 | if (!json->ParsePartialFromString(serialized)) { |
501 | 0 | return absl::UnknownError( |
502 | 0 | absl::StrCat("failed to parsed message: ", json->GetTypeName())); |
503 | 0 | } |
504 | 0 | } |
505 | 0 | return absl::OkStatus(); |
506 | 0 | } |
507 | 0 | } |
508 | | |
509 | 0 | bool LegacyListValue::IsEmpty() const { return impl_->empty(); } |
510 | | |
511 | 16 | size_t LegacyListValue::Size() const { |
512 | 16 | return static_cast<size_t>(impl_->size()); |
513 | 16 | } |
514 | | |
515 | | // See LegacyListValueInterface::Get for documentation. |
516 | | absl::Status LegacyListValue::Get( |
517 | | size_t index, const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
518 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
519 | 0 | google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const { |
520 | 0 | if (ABSL_PREDICT_FALSE(index < 0 || index >= impl_->size())) { |
521 | 0 | *result = ErrorValue(absl::InvalidArgumentError("index out of bounds")); |
522 | 0 | return absl::OkStatus(); |
523 | 0 | } |
524 | 0 | CEL_RETURN_IF_ERROR( |
525 | 0 | ModernValue(arena, impl_->Get(arena, static_cast<int>(index)), *result)); |
526 | 0 | return absl::OkStatus(); |
527 | 0 | } |
528 | | |
529 | | absl::Status LegacyListValue::ForEach( |
530 | | ForEachWithIndexCallback callback, |
531 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
532 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
533 | 0 | google::protobuf::Arena* absl_nonnull arena) const { |
534 | 0 | const auto size = impl_->size(); |
535 | 0 | Value element; |
536 | 0 | for (int index = 0; index < size; ++index) { |
537 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, impl_->Get(arena, index), element)); |
538 | 0 | CEL_ASSIGN_OR_RETURN(auto ok, callback(index, Value(element))); |
539 | 0 | if (!ok) { |
540 | 0 | break; |
541 | 0 | } |
542 | 0 | } |
543 | 0 | return absl::OkStatus(); |
544 | 0 | } |
545 | | |
546 | | absl::StatusOr<absl_nonnull ValueIteratorPtr> LegacyListValue::NewIterator() |
547 | 0 | const { |
548 | 0 | return std::make_unique<CelListIterator>(impl_); |
549 | 0 | } |
550 | | |
551 | | absl::Status LegacyListValue::Contains( |
552 | | const Value& other, |
553 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
554 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
555 | 0 | google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const { |
556 | 0 | CEL_ASSIGN_OR_RETURN(auto legacy_other, LegacyValue(arena, other)); |
557 | 0 | const auto* cel_list = impl_; |
558 | 0 | for (int i = 0; i < cel_list->size(); ++i) { |
559 | 0 | auto element = cel_list->Get(arena, i); |
560 | 0 | absl::optional<bool> equal = |
561 | 0 | interop_internal::CelValueEqualImpl(element, legacy_other); |
562 | | // Heterogeneous equality behavior is to just return false if equality |
563 | | // undefined. |
564 | 0 | if (equal.has_value() && *equal) { |
565 | 0 | *result = TrueValue(); |
566 | 0 | return absl::OkStatus(); |
567 | 0 | } |
568 | 0 | } |
569 | 0 | *result = FalseValue(); |
570 | 0 | return absl::OkStatus(); |
571 | 0 | } |
572 | | |
573 | 0 | std::string LegacyMapValue::DebugString() const { |
574 | 0 | return CelValue::CreateMap(impl_).DebugString(); |
575 | 0 | } |
576 | | |
577 | | absl::Status LegacyMapValue::SerializeTo( |
578 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
579 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
580 | 0 | google::protobuf::io::ZeroCopyOutputStream* absl_nonnull output) const { |
581 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
582 | 0 | ABSL_DCHECK(message_factory != nullptr); |
583 | 0 | ABSL_DCHECK(output != nullptr); |
584 | |
|
585 | 0 | const google::protobuf::Descriptor* descriptor = |
586 | 0 | descriptor_pool->FindMessageTypeByName("google.protobuf.Struct"); |
587 | 0 | if (descriptor == nullptr) { |
588 | 0 | return absl::InternalError( |
589 | 0 | "unable to locate descriptor for message type: google.protobuf.Struct"); |
590 | 0 | } |
591 | | |
592 | 0 | google::protobuf::Arena arena; |
593 | 0 | const google::protobuf::Message* wrapped = MaybeWrapValueToMessage( |
594 | 0 | descriptor, message_factory, CelValue::CreateMap(impl_), &arena); |
595 | 0 | if (wrapped == nullptr) { |
596 | 0 | return absl::UnknownError("failed to convert legacy map to JSON"); |
597 | 0 | } |
598 | 0 | if (!wrapped->SerializePartialToZeroCopyStream(output)) { |
599 | 0 | return absl::UnknownError( |
600 | 0 | absl::StrCat("failed to serialize message: ", wrapped->GetTypeName())); |
601 | 0 | } |
602 | 0 | return absl::OkStatus(); |
603 | 0 | } |
604 | | |
605 | | absl::Status LegacyMapValue::ConvertToJson( |
606 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
607 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
608 | 0 | google::protobuf::Message* absl_nonnull json) const { |
609 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
610 | 0 | ABSL_DCHECK(message_factory != nullptr); |
611 | 0 | ABSL_DCHECK(json != nullptr); |
612 | 0 | ABSL_DCHECK_EQ(json->GetDescriptor()->well_known_type(), |
613 | 0 | google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE); |
614 | |
|
615 | 0 | google::protobuf::Arena arena; |
616 | 0 | const google::protobuf::Message* wrapped = |
617 | 0 | MaybeWrapValueToMessage(json->GetDescriptor(), message_factory, |
618 | 0 | CelValue::CreateMap(impl_), &arena); |
619 | 0 | if (wrapped == nullptr) { |
620 | 0 | return absl::UnknownError("failed to convert legacy map to JSON"); |
621 | 0 | } |
622 | | |
623 | 0 | if (wrapped->GetDescriptor() == json->GetDescriptor()) { |
624 | | // We can directly use google::protobuf::Message::Copy(). |
625 | 0 | json->CopyFrom(*wrapped); |
626 | 0 | } else { |
627 | | // Equivalent descriptors but not identical. Must serialize and deserialize. |
628 | 0 | absl::Cord serialized; |
629 | 0 | if (!wrapped->SerializePartialToString(&serialized)) { |
630 | 0 | return absl::UnknownError(absl::StrCat("failed to serialize message: ", |
631 | 0 | wrapped->GetTypeName())); |
632 | 0 | } |
633 | 0 | if (!json->ParsePartialFromString(serialized)) { |
634 | 0 | return absl::UnknownError( |
635 | 0 | absl::StrCat("failed to parsed message: ", json->GetTypeName())); |
636 | 0 | } |
637 | 0 | } |
638 | 0 | return absl::OkStatus(); |
639 | 0 | } |
640 | | |
641 | | absl::Status LegacyMapValue::ConvertToJsonObject( |
642 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
643 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
644 | 0 | google::protobuf::Message* absl_nonnull json) const { |
645 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
646 | 0 | ABSL_DCHECK(message_factory != nullptr); |
647 | 0 | ABSL_DCHECK(json != nullptr); |
648 | 0 | ABSL_DCHECK_EQ(json->GetDescriptor()->well_known_type(), |
649 | 0 | google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT); |
650 | |
|
651 | 0 | google::protobuf::Arena arena; |
652 | 0 | const google::protobuf::Message* wrapped = |
653 | 0 | MaybeWrapValueToMessage(json->GetDescriptor(), message_factory, |
654 | 0 | CelValue::CreateMap(impl_), &arena); |
655 | 0 | if (wrapped == nullptr) { |
656 | 0 | return absl::UnknownError("failed to convert legacy map to JSON"); |
657 | 0 | } |
658 | | |
659 | 0 | if (wrapped->GetDescriptor() == json->GetDescriptor()) { |
660 | | // We can directly use google::protobuf::Message::Copy(). |
661 | 0 | json->CopyFrom(*wrapped); |
662 | 0 | } else { |
663 | | // Equivalent descriptors but not identical. Must serialize and deserialize. |
664 | 0 | absl::Cord serialized; |
665 | 0 | if (!wrapped->SerializePartialToString(&serialized)) { |
666 | 0 | return absl::UnknownError(absl::StrCat("failed to serialize message: ", |
667 | 0 | wrapped->GetTypeName())); |
668 | 0 | } |
669 | 0 | if (!json->ParsePartialFromString(serialized)) { |
670 | 0 | return absl::UnknownError( |
671 | 0 | absl::StrCat("failed to parsed message: ", json->GetTypeName())); |
672 | 0 | } |
673 | 0 | } |
674 | 0 | return absl::OkStatus(); |
675 | 0 | } |
676 | | |
677 | 0 | bool LegacyMapValue::IsEmpty() const { return impl_->empty(); } |
678 | | |
679 | 1 | size_t LegacyMapValue::Size() const { |
680 | 1 | return static_cast<size_t>(impl_->size()); |
681 | 1 | } |
682 | | |
683 | | absl::Status LegacyMapValue::Get( |
684 | | const Value& key, |
685 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
686 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
687 | 433 | google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const { |
688 | 433 | switch (key.kind()) { |
689 | 0 | case ValueKind::kError: |
690 | 0 | ABSL_FALLTHROUGH_INTENDED; |
691 | 0 | case ValueKind::kUnknown: |
692 | 0 | *result = Value{key}; |
693 | 0 | return absl::OkStatus(); |
694 | 7 | case ValueKind::kBool: |
695 | 7 | ABSL_FALLTHROUGH_INTENDED; |
696 | 7 | case ValueKind::kInt: |
697 | 7 | ABSL_FALLTHROUGH_INTENDED; |
698 | 7 | case ValueKind::kUint: |
699 | 7 | ABSL_FALLTHROUGH_INTENDED; |
700 | 433 | case ValueKind::kString: |
701 | 433 | break; |
702 | 0 | default: |
703 | 0 | *result = ErrorValue(InvalidMapKeyTypeError(key.kind())); |
704 | 0 | return absl::OkStatus(); |
705 | 433 | } |
706 | 866 | CEL_ASSIGN_OR_RETURN(auto cel_key, LegacyValue(arena, key)); |
707 | 866 | auto cel_value = impl_->Get(arena, cel_key); |
708 | 866 | if (!cel_value.has_value()) { |
709 | 426 | *result = NoSuchKeyError(key.DebugString()); |
710 | 426 | return absl::OkStatus(); |
711 | 426 | } |
712 | 433 | CEL_RETURN_IF_ERROR(ModernValue(arena, *cel_value, *result)); |
713 | 7 | return absl::OkStatus(); |
714 | 7 | } |
715 | | |
716 | | absl::StatusOr<bool> LegacyMapValue::Find( |
717 | | const Value& key, |
718 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
719 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
720 | 158 | google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const { |
721 | 158 | switch (key.kind()) { |
722 | 0 | case ValueKind::kError: |
723 | 0 | ABSL_FALLTHROUGH_INTENDED; |
724 | 0 | case ValueKind::kUnknown: |
725 | 0 | *result = Value{key}; |
726 | 0 | return false; |
727 | 0 | case ValueKind::kBool: |
728 | 0 | ABSL_FALLTHROUGH_INTENDED; |
729 | 100 | case ValueKind::kInt: |
730 | 100 | ABSL_FALLTHROUGH_INTENDED; |
731 | 158 | case ValueKind::kUint: |
732 | 158 | ABSL_FALLTHROUGH_INTENDED; |
733 | 158 | case ValueKind::kString: |
734 | 158 | break; |
735 | 0 | default: |
736 | 0 | *result = ErrorValue(InvalidMapKeyTypeError(key.kind())); |
737 | 158 | } |
738 | 316 | CEL_ASSIGN_OR_RETURN(auto cel_key, LegacyValue(arena, key)); |
739 | 316 | auto cel_value = impl_->Get(arena, cel_key); |
740 | 316 | if (!cel_value.has_value()) { |
741 | 0 | *result = NullValue{}; |
742 | 0 | return false; |
743 | 0 | } |
744 | 158 | CEL_RETURN_IF_ERROR(ModernValue(arena, *cel_value, *result)); |
745 | 158 | return true; |
746 | 158 | } |
747 | | |
748 | | absl::Status LegacyMapValue::Has( |
749 | | const Value& key, |
750 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
751 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
752 | 148 | google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const { |
753 | 148 | switch (key.kind()) { |
754 | 0 | case ValueKind::kError: |
755 | 0 | ABSL_FALLTHROUGH_INTENDED; |
756 | 0 | case ValueKind::kUnknown: |
757 | 0 | *result = Value{key}; |
758 | 0 | return absl::OkStatus(); |
759 | 6 | case ValueKind::kBool: |
760 | 6 | ABSL_FALLTHROUGH_INTENDED; |
761 | 52 | case ValueKind::kInt: |
762 | 52 | ABSL_FALLTHROUGH_INTENDED; |
763 | 98 | case ValueKind::kUint: |
764 | 98 | ABSL_FALLTHROUGH_INTENDED; |
765 | 120 | case ValueKind::kString: |
766 | 120 | break; |
767 | 28 | default: |
768 | 28 | *result = ErrorValue(InvalidMapKeyTypeError(key.kind())); |
769 | 28 | return absl::OkStatus(); |
770 | 148 | } |
771 | 240 | CEL_ASSIGN_OR_RETURN(auto cel_key, LegacyValue(arena, key)); |
772 | 240 | absl::StatusOr<bool> has = impl_->Has(cel_key); |
773 | 240 | if (!has.ok()) { |
774 | 98 | *result = ErrorValue(std::move(has).status()); |
775 | 98 | return absl::OkStatus(); |
776 | 98 | } |
777 | | |
778 | 22 | *result = BoolValue(*has); |
779 | 22 | return absl::OkStatus(); |
780 | 240 | } |
781 | | |
782 | | absl::Status LegacyMapValue::ListKeys( |
783 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
784 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
785 | 0 | google::protobuf::Arena* absl_nonnull arena, ListValue* absl_nonnull result) const { |
786 | 0 | CEL_ASSIGN_OR_RETURN(auto keys, impl_->ListKeys(arena)); |
787 | 0 | *result = ListValue{common_internal::LegacyListValue(keys)}; |
788 | 0 | return absl::OkStatus(); |
789 | 0 | } |
790 | | |
791 | | absl::Status LegacyMapValue::ForEach( |
792 | | ForEachCallback callback, |
793 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
794 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
795 | 0 | google::protobuf::Arena* absl_nonnull arena) const { |
796 | 0 | CEL_ASSIGN_OR_RETURN(auto keys, impl_->ListKeys(arena)); |
797 | 0 | const auto size = keys->size(); |
798 | 0 | Value key; |
799 | 0 | Value value; |
800 | 0 | for (int index = 0; index < size; ++index) { |
801 | 0 | auto cel_key = keys->Get(arena, index); |
802 | 0 | auto cel_value = *impl_->Get(arena, cel_key); |
803 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, cel_key, key)); |
804 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, cel_value, value)); |
805 | 0 | CEL_ASSIGN_OR_RETURN(auto ok, callback(key, value)); |
806 | 0 | if (!ok) { |
807 | 0 | break; |
808 | 0 | } |
809 | 0 | } |
810 | 0 | return absl::OkStatus(); |
811 | 0 | } |
812 | | |
813 | | absl::StatusOr<absl_nonnull ValueIteratorPtr> LegacyMapValue::NewIterator() |
814 | 0 | const { |
815 | 0 | return std::make_unique<CelMapIterator>(impl_); |
816 | 0 | } |
817 | | |
818 | 0 | absl::string_view LegacyStructValue::GetTypeName() const { |
819 | 0 | auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_); |
820 | 0 | return message_wrapper.legacy_type_info()->GetTypename(message_wrapper); |
821 | 0 | } |
822 | | |
823 | 0 | std::string LegacyStructValue::DebugString() const { |
824 | 0 | auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_); |
825 | 0 | return message_wrapper.legacy_type_info()->DebugString(message_wrapper); |
826 | 0 | } |
827 | | |
828 | | absl::Status LegacyStructValue::SerializeTo( |
829 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
830 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
831 | 0 | google::protobuf::io::ZeroCopyOutputStream* absl_nonnull output) const { |
832 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
833 | 0 | ABSL_DCHECK(message_factory != nullptr); |
834 | 0 | ABSL_DCHECK(output != nullptr); |
835 | |
|
836 | 0 | auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_); |
837 | 0 | if (ABSL_PREDICT_TRUE( |
838 | 0 | message_wrapper.message_ptr()->SerializePartialToZeroCopyStream( |
839 | 0 | output))) { |
840 | 0 | return absl::OkStatus(); |
841 | 0 | } |
842 | 0 | return absl::UnknownError("failed to serialize protocol buffer message"); |
843 | 0 | } |
844 | | |
845 | | absl::Status LegacyStructValue::ConvertToJson( |
846 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
847 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
848 | 0 | google::protobuf::Message* absl_nonnull json) const { |
849 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
850 | 0 | ABSL_DCHECK(message_factory != nullptr); |
851 | 0 | ABSL_DCHECK(json != nullptr); |
852 | 0 | ABSL_DCHECK_EQ(json->GetDescriptor()->well_known_type(), |
853 | 0 | google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE); |
854 | |
|
855 | 0 | auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_); |
856 | |
|
857 | 0 | return internal::MessageToJson( |
858 | 0 | *google::protobuf::DownCastMessage<google::protobuf::Message>(message_wrapper.message_ptr()), |
859 | 0 | descriptor_pool, message_factory, json); |
860 | 0 | } |
861 | | |
862 | | absl::Status LegacyStructValue::ConvertToJsonObject( |
863 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
864 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
865 | 0 | google::protobuf::Message* absl_nonnull json) const { |
866 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
867 | 0 | ABSL_DCHECK(message_factory != nullptr); |
868 | 0 | ABSL_DCHECK(json != nullptr); |
869 | 0 | ABSL_DCHECK_EQ(json->GetDescriptor()->well_known_type(), |
870 | 0 | google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT); |
871 | |
|
872 | 0 | auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_); |
873 | |
|
874 | 0 | return internal::MessageToJson( |
875 | 0 | *google::protobuf::DownCastMessage<google::protobuf::Message>(message_wrapper.message_ptr()), |
876 | 0 | descriptor_pool, message_factory, json); |
877 | 0 | } |
878 | | |
879 | | absl::Status LegacyStructValue::Equal( |
880 | | const Value& other, |
881 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
882 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
883 | 1 | google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const { |
884 | 1 | if (auto legacy_struct_value = common_internal::AsLegacyStructValue(other); |
885 | 1 | legacy_struct_value.has_value()) { |
886 | 0 | auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_); |
887 | 0 | const auto* access_apis = |
888 | 0 | message_wrapper.legacy_type_info()->GetAccessApis(message_wrapper); |
889 | 0 | if (ABSL_PREDICT_FALSE(access_apis == nullptr)) { |
890 | 0 | return absl::UnimplementedError( |
891 | 0 | absl::StrCat("legacy access APIs missing for ", GetTypeName())); |
892 | 0 | } |
893 | 0 | auto other_message_wrapper = |
894 | 0 | AsMessageWrapper(legacy_struct_value->message_ptr(), |
895 | 0 | legacy_struct_value->legacy_type_info()); |
896 | 0 | *result = BoolValue{ |
897 | 0 | access_apis->IsEqualTo(message_wrapper, other_message_wrapper)}; |
898 | 0 | return absl::OkStatus(); |
899 | 0 | } |
900 | 1 | if (auto struct_value = other.AsStruct(); struct_value.has_value()) { |
901 | 0 | return common_internal::StructValueEqual( |
902 | 0 | common_internal::LegacyStructValue(message_ptr_, legacy_type_info_), |
903 | 0 | *struct_value, descriptor_pool, message_factory, arena, result); |
904 | 0 | } |
905 | 1 | *result = FalseValue(); |
906 | 1 | return absl::OkStatus(); |
907 | 1 | } |
908 | | |
909 | 0 | bool LegacyStructValue::IsZeroValue() const { |
910 | 0 | auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_); |
911 | 0 | const auto* access_apis = |
912 | 0 | message_wrapper.legacy_type_info()->GetAccessApis(message_wrapper); |
913 | 0 | if (ABSL_PREDICT_FALSE(access_apis == nullptr)) { |
914 | 0 | return false; |
915 | 0 | } |
916 | 0 | return access_apis->ListFields(message_wrapper).empty(); |
917 | 0 | } |
918 | | |
919 | | absl::Status LegacyStructValue::GetFieldByName( |
920 | | absl::string_view name, ProtoWrapperTypeOptions unboxing_options, |
921 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
922 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
923 | 284 | google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const { |
924 | 284 | auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_); |
925 | 284 | const auto* access_apis = |
926 | 284 | message_wrapper.legacy_type_info()->GetAccessApis(message_wrapper); |
927 | 284 | if (ABSL_PREDICT_FALSE(access_apis == nullptr)) { |
928 | 0 | *result = NoSuchFieldError(name); |
929 | 0 | return absl::OkStatus(); |
930 | 0 | } |
931 | 568 | CEL_ASSIGN_OR_RETURN( |
932 | 568 | auto cel_value, |
933 | 568 | access_apis->GetField(name, message_wrapper, unboxing_options, |
934 | 568 | MemoryManagerRef::Pooling(arena))); |
935 | 568 | CEL_RETURN_IF_ERROR(ModernValue(arena, cel_value, *result)); |
936 | 284 | return absl::OkStatus(); |
937 | 568 | } |
938 | | |
939 | | absl::Status LegacyStructValue::GetFieldByNumber( |
940 | | int64_t number, ProtoWrapperTypeOptions unboxing_options, |
941 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
942 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
943 | 0 | google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const { |
944 | 0 | return absl::UnimplementedError( |
945 | 0 | "access to fields by numbers is not available for legacy structs"); |
946 | 0 | } |
947 | | |
948 | | absl::StatusOr<bool> LegacyStructValue::HasFieldByName( |
949 | 0 | absl::string_view name) const { |
950 | 0 | auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_); |
951 | 0 | const auto* access_apis = |
952 | 0 | message_wrapper.legacy_type_info()->GetAccessApis(message_wrapper); |
953 | 0 | if (ABSL_PREDICT_FALSE(access_apis == nullptr)) { |
954 | 0 | return NoSuchFieldError(name).NativeValue(); |
955 | 0 | } |
956 | 0 | return access_apis->HasField(name, message_wrapper); |
957 | 0 | } |
958 | | |
959 | 0 | absl::StatusOr<bool> LegacyStructValue::HasFieldByNumber(int64_t number) const { |
960 | 0 | return absl::UnimplementedError( |
961 | 0 | "access to fields by numbers is not available for legacy structs"); |
962 | 0 | } |
963 | | |
964 | | absl::Status LegacyStructValue::ForEachField( |
965 | | ForEachFieldCallback callback, |
966 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
967 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
968 | 0 | google::protobuf::Arena* absl_nonnull arena) const { |
969 | 0 | auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_); |
970 | 0 | const auto* access_apis = |
971 | 0 | message_wrapper.legacy_type_info()->GetAccessApis(message_wrapper); |
972 | 0 | if (ABSL_PREDICT_FALSE(access_apis == nullptr)) { |
973 | 0 | return absl::UnimplementedError( |
974 | 0 | absl::StrCat("legacy access APIs missing for ", GetTypeName())); |
975 | 0 | } |
976 | 0 | auto field_names = access_apis->ListFields(message_wrapper); |
977 | 0 | Value value; |
978 | 0 | for (const auto& field_name : field_names) { |
979 | 0 | CEL_ASSIGN_OR_RETURN( |
980 | 0 | auto cel_value, |
981 | 0 | access_apis->GetField(field_name, message_wrapper, |
982 | 0 | ProtoWrapperTypeOptions::kUnsetNull, |
983 | 0 | MemoryManagerRef::Pooling(arena))); |
984 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, cel_value, value)); |
985 | 0 | CEL_ASSIGN_OR_RETURN(auto ok, callback(field_name, value)); |
986 | 0 | if (!ok) { |
987 | 0 | break; |
988 | 0 | } |
989 | 0 | } |
990 | 0 | return absl::OkStatus(); |
991 | 0 | } |
992 | | |
993 | | absl::Status LegacyStructValue::Qualify( |
994 | | absl::Span<const SelectQualifier> qualifiers, bool presence_test, |
995 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
996 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
997 | | google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result, |
998 | 0 | int* absl_nonnull count) const { |
999 | 0 | if (ABSL_PREDICT_FALSE(qualifiers.empty())) { |
1000 | 0 | return absl::InvalidArgumentError("invalid select qualifier path."); |
1001 | 0 | } |
1002 | 0 | auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_); |
1003 | 0 | const auto* access_apis = |
1004 | 0 | message_wrapper.legacy_type_info()->GetAccessApis(message_wrapper); |
1005 | 0 | if (ABSL_PREDICT_FALSE(access_apis == nullptr)) { |
1006 | 0 | absl::string_view field_name = absl::visit( |
1007 | 0 | absl::Overload( |
1008 | 0 | [](const FieldSpecifier& field) -> absl::string_view { |
1009 | 0 | return field.name; |
1010 | 0 | }, |
1011 | 0 | [](const AttributeQualifier& field) -> absl::string_view { |
1012 | 0 | return field.GetStringKey().value_or("<invalid field>"); |
1013 | 0 | }), |
1014 | 0 | qualifiers.front()); |
1015 | 0 | *result = NoSuchFieldError(field_name); |
1016 | 0 | *count = -1; |
1017 | 0 | return absl::OkStatus(); |
1018 | 0 | } |
1019 | 0 | CEL_ASSIGN_OR_RETURN( |
1020 | 0 | auto legacy_result, |
1021 | 0 | access_apis->Qualify(qualifiers, message_wrapper, presence_test, |
1022 | 0 | MemoryManager::Pooling(arena))); |
1023 | 0 | CEL_RETURN_IF_ERROR(ModernValue(arena, legacy_result.value, *result)); |
1024 | 0 | *count = legacy_result.qualifier_count; |
1025 | 0 | return absl::OkStatus(); |
1026 | 0 | } |
1027 | | |
1028 | | } // namespace common_internal |
1029 | | |
1030 | | absl::Status ModernValue(google::protobuf::Arena* arena, |
1031 | | google::api::expr::runtime::CelValue legacy_value, |
1032 | 2.10k | Value& result) { |
1033 | 2.10k | switch (legacy_value.type()) { |
1034 | 42 | case CelValue::Type::kNullType: |
1035 | 42 | result = NullValue{}; |
1036 | 42 | return absl::OkStatus(); |
1037 | 1 | case CelValue::Type::kBool: |
1038 | 1 | result = BoolValue{legacy_value.BoolOrDie()}; |
1039 | 1 | return absl::OkStatus(); |
1040 | 76 | case CelValue::Type::kInt64: |
1041 | 76 | result = IntValue{legacy_value.Int64OrDie()}; |
1042 | 76 | return absl::OkStatus(); |
1043 | 104 | case CelValue::Type::kUint64: |
1044 | 104 | result = UintValue{legacy_value.Uint64OrDie()}; |
1045 | 104 | return absl::OkStatus(); |
1046 | 117 | case CelValue::Type::kDouble: |
1047 | 117 | result = DoubleValue{legacy_value.DoubleOrDie()}; |
1048 | 117 | return absl::OkStatus(); |
1049 | 26 | case CelValue::Type::kString: |
1050 | 26 | result = StringValue(Borrower::Arena(arena), |
1051 | 26 | legacy_value.StringOrDie().value()); |
1052 | 26 | return absl::OkStatus(); |
1053 | 102 | case CelValue::Type::kBytes: |
1054 | 102 | result = |
1055 | 102 | BytesValue(Borrower::Arena(arena), legacy_value.BytesOrDie().value()); |
1056 | 102 | return absl::OkStatus(); |
1057 | 289 | case CelValue::Type::kMessage: { |
1058 | 289 | auto message_wrapper = legacy_value.MessageWrapperOrDie(); |
1059 | 289 | result = common_internal::LegacyStructValue( |
1060 | 289 | google::protobuf::DownCastMessage<google::protobuf::Message>( |
1061 | 289 | message_wrapper.message_ptr()), |
1062 | 289 | message_wrapper.legacy_type_info()); |
1063 | 289 | return absl::OkStatus(); |
1064 | 0 | } |
1065 | 6 | case CelValue::Type::kDuration: |
1066 | 6 | result = UnsafeDurationValue(legacy_value.DurationOrDie()); |
1067 | 6 | return absl::OkStatus(); |
1068 | 48 | case CelValue::Type::kTimestamp: |
1069 | 48 | result = UnsafeTimestampValue(legacy_value.TimestampOrDie()); |
1070 | 48 | return absl::OkStatus(); |
1071 | 87 | case CelValue::Type::kList: |
1072 | 87 | result = |
1073 | 87 | ListValue(common_internal::LegacyListValue(legacy_value.ListOrDie())); |
1074 | 87 | return absl::OkStatus(); |
1075 | 677 | case CelValue::Type::kMap: |
1076 | 677 | result = |
1077 | 677 | MapValue(common_internal::LegacyMapValue(legacy_value.MapOrDie())); |
1078 | 677 | return absl::OkStatus(); |
1079 | 0 | case CelValue::Type::kUnknownSet: |
1080 | 0 | result = UnknownValue{*legacy_value.UnknownSetOrDie()}; |
1081 | 0 | return absl::OkStatus(); |
1082 | 0 | case CelValue::Type::kCelType: { |
1083 | 0 | auto type_name = legacy_value.CelTypeOrDie().value(); |
1084 | 0 | if (type_name.empty()) { |
1085 | 0 | return absl::InvalidArgumentError("empty type name in CelValue"); |
1086 | 0 | } |
1087 | 0 | result = TypeValue(common_internal::LegacyRuntimeType(type_name)); |
1088 | 0 | return absl::OkStatus(); |
1089 | 0 | } |
1090 | 528 | case CelValue::Type::kError: |
1091 | 528 | result = ErrorValue{*legacy_value.ErrorOrDie()}; |
1092 | 528 | return absl::OkStatus(); |
1093 | 0 | case CelValue::Type::kAny: |
1094 | 0 | return absl::InternalError(absl::StrCat( |
1095 | 0 | "illegal attempt to convert special CelValue type ", |
1096 | 0 | CelValue::TypeName(legacy_value.type()), " to cel::Value")); |
1097 | 0 | default: |
1098 | 0 | break; |
1099 | 2.10k | } |
1100 | 0 | return absl::InvalidArgumentError(absl::StrCat( |
1101 | 0 | "cel::Value does not support ", KindToString(legacy_value.type()))); |
1102 | 2.10k | } |
1103 | | |
1104 | | absl::StatusOr<google::api::expr::runtime::CelValue> LegacyValue( |
1105 | 711 | google::protobuf::Arena* arena, const Value& modern_value) { |
1106 | 711 | switch (modern_value.kind()) { |
1107 | 0 | case ValueKind::kNull: |
1108 | 0 | return CelValue::CreateNull(); |
1109 | 13 | case ValueKind::kBool: |
1110 | 13 | return CelValue::CreateBool(Cast<BoolValue>(modern_value).NativeValue()); |
1111 | 146 | case ValueKind::kInt: |
1112 | 146 | return CelValue::CreateInt64(Cast<IntValue>(modern_value).NativeValue()); |
1113 | 104 | case ValueKind::kUint: |
1114 | 104 | return CelValue::CreateUint64( |
1115 | 104 | Cast<UintValue>(modern_value).NativeValue()); |
1116 | 0 | case ValueKind::kDouble: |
1117 | 0 | return CelValue::CreateDouble( |
1118 | 0 | Cast<DoubleValue>(modern_value).NativeValue()); |
1119 | 448 | case ValueKind::kString: |
1120 | 448 | return CelValue::CreateStringView(common_internal::LegacyStringValue( |
1121 | 448 | modern_value.GetString(), /*stable=*/false, arena)); |
1122 | 0 | case ValueKind::kBytes: |
1123 | 0 | return CelValue::CreateBytesView(common_internal::LegacyBytesValue( |
1124 | 0 | modern_value.GetBytes(), /*stable=*/false, arena)); |
1125 | 0 | case ValueKind::kStruct: |
1126 | 0 | return common_internal::LegacyTrivialStructValue(arena, modern_value); |
1127 | 0 | case ValueKind::kDuration: |
1128 | 0 | return CelValue::CreateUncheckedDuration( |
1129 | 0 | modern_value.GetDuration().NativeValue()); |
1130 | 0 | case ValueKind::kTimestamp: |
1131 | 0 | return CelValue::CreateTimestamp( |
1132 | 0 | modern_value.GetTimestamp().NativeValue()); |
1133 | 0 | case ValueKind::kList: |
1134 | 0 | return common_internal::LegacyTrivialListValue(arena, modern_value); |
1135 | 0 | case ValueKind::kMap: |
1136 | 0 | return common_internal::LegacyTrivialMapValue(arena, modern_value); |
1137 | 0 | case ValueKind::kUnknown: |
1138 | 0 | return CelValue::CreateUnknownSet(google::protobuf::Arena::Create<Unknown>( |
1139 | 0 | arena, Cast<UnknownValue>(modern_value).NativeValue())); |
1140 | 0 | case ValueKind::kType: |
1141 | 0 | return CelValue::CreateCelType( |
1142 | 0 | CelValue::CelTypeHolder(google::protobuf::Arena::Create<std::string>( |
1143 | 0 | arena, Cast<TypeValue>(modern_value).NativeValue().name()))); |
1144 | 0 | case ValueKind::kError: |
1145 | 0 | return CelValue::CreateError(google::protobuf::Arena::Create<absl::Status>( |
1146 | 0 | arena, Cast<ErrorValue>(modern_value).NativeValue())); |
1147 | 0 | default: |
1148 | 0 | return absl::InvalidArgumentError( |
1149 | 0 | absl::StrCat("google::api::expr::runtime::CelValue does not support ", |
1150 | 0 | ValueKindToString(modern_value.kind()))); |
1151 | 711 | } |
1152 | 711 | } |
1153 | | |
1154 | | namespace interop_internal { |
1155 | | |
1156 | | absl::StatusOr<Value> FromLegacyValue(google::protobuf::Arena* arena, |
1157 | 0 | const CelValue& legacy_value, bool) { |
1158 | 0 | switch (legacy_value.type()) { |
1159 | 0 | case CelValue::Type::kNullType: |
1160 | 0 | return NullValue{}; |
1161 | 0 | case CelValue::Type::kBool: |
1162 | 0 | return BoolValue(legacy_value.BoolOrDie()); |
1163 | 0 | case CelValue::Type::kInt64: |
1164 | 0 | return IntValue(legacy_value.Int64OrDie()); |
1165 | 0 | case CelValue::Type::kUint64: |
1166 | 0 | return UintValue(legacy_value.Uint64OrDie()); |
1167 | 0 | case CelValue::Type::kDouble: |
1168 | 0 | return DoubleValue(legacy_value.DoubleOrDie()); |
1169 | 0 | case CelValue::Type::kString: |
1170 | 0 | return StringValue(Borrower::Arena(arena), |
1171 | 0 | legacy_value.StringOrDie().value()); |
1172 | 0 | case CelValue::Type::kBytes: |
1173 | 0 | return BytesValue(Borrower::Arena(arena), |
1174 | 0 | legacy_value.BytesOrDie().value()); |
1175 | 0 | case CelValue::Type::kMessage: { |
1176 | 0 | auto message_wrapper = legacy_value.MessageWrapperOrDie(); |
1177 | 0 | return common_internal::LegacyStructValue( |
1178 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>( |
1179 | 0 | message_wrapper.message_ptr()), |
1180 | 0 | message_wrapper.legacy_type_info()); |
1181 | 0 | } |
1182 | 0 | case CelValue::Type::kDuration: |
1183 | 0 | return UnsafeDurationValue(legacy_value.DurationOrDie()); |
1184 | 0 | case CelValue::Type::kTimestamp: |
1185 | 0 | return UnsafeTimestampValue(legacy_value.TimestampOrDie()); |
1186 | 0 | case CelValue::Type::kList: |
1187 | 0 | return ListValue( |
1188 | 0 | common_internal::LegacyListValue(legacy_value.ListOrDie())); |
1189 | 0 | case CelValue::Type::kMap: |
1190 | 0 | return MapValue(common_internal::LegacyMapValue(legacy_value.MapOrDie())); |
1191 | 0 | case CelValue::Type::kUnknownSet: |
1192 | 0 | return UnknownValue{*legacy_value.UnknownSetOrDie()}; |
1193 | 0 | case CelValue::Type::kCelType: |
1194 | 0 | return CreateTypeValueFromView(arena, |
1195 | 0 | legacy_value.CelTypeOrDie().value()); |
1196 | 0 | case CelValue::Type::kError: |
1197 | 0 | return ErrorValue(*legacy_value.ErrorOrDie()); |
1198 | 0 | case CelValue::Type::kAny: |
1199 | 0 | return absl::InternalError(absl::StrCat( |
1200 | 0 | "illegal attempt to convert special CelValue type ", |
1201 | 0 | CelValue::TypeName(legacy_value.type()), " to cel::Value")); |
1202 | 0 | default: |
1203 | 0 | break; |
1204 | 0 | } |
1205 | 0 | return absl::UnimplementedError(absl::StrCat( |
1206 | 0 | "conversion from CelValue to cel::Value for type ", |
1207 | 0 | CelValue::TypeName(legacy_value.type()), " is not yet implemented")); |
1208 | 0 | } |
1209 | | |
1210 | | absl::StatusOr<google::api::expr::runtime::CelValue> ToLegacyValue( |
1211 | 9.89k | google::protobuf::Arena* arena, const Value& value, bool) { |
1212 | 9.89k | switch (value.kind()) { |
1213 | 2 | case ValueKind::kNull: |
1214 | 2 | return CelValue::CreateNull(); |
1215 | 3.34k | case ValueKind::kBool: |
1216 | 3.34k | return CelValue::CreateBool(Cast<BoolValue>(value).NativeValue()); |
1217 | 421 | case ValueKind::kInt: |
1218 | 421 | return CelValue::CreateInt64(Cast<IntValue>(value).NativeValue()); |
1219 | 143 | case ValueKind::kUint: |
1220 | 143 | return CelValue::CreateUint64(Cast<UintValue>(value).NativeValue()); |
1221 | 329 | case ValueKind::kDouble: |
1222 | 329 | return CelValue::CreateDouble(Cast<DoubleValue>(value).NativeValue()); |
1223 | 203 | case ValueKind::kString: |
1224 | 203 | return CelValue::CreateStringView(common_internal::LegacyStringValue( |
1225 | 203 | value.GetString(), /*stable=*/false, arena)); |
1226 | 67 | case ValueKind::kBytes: |
1227 | 67 | return CelValue::CreateBytesView(common_internal::LegacyBytesValue( |
1228 | 67 | value.GetBytes(), /*stable=*/false, arena)); |
1229 | 1 | case ValueKind::kStruct: |
1230 | 1 | return common_internal::LegacyTrivialStructValue(arena, value); |
1231 | 1 | case ValueKind::kDuration: |
1232 | 1 | return CelValue::CreateUncheckedDuration( |
1233 | 1 | Cast<DurationValue>(value).NativeValue()); |
1234 | 1 | case ValueKind::kTimestamp: |
1235 | 1 | return CelValue::CreateTimestamp( |
1236 | 1 | Cast<TimestampValue>(value).NativeValue()); |
1237 | 274 | case ValueKind::kList: |
1238 | 274 | return common_internal::LegacyTrivialListValue(arena, value); |
1239 | 44 | case ValueKind::kMap: |
1240 | 44 | return common_internal::LegacyTrivialMapValue(arena, value); |
1241 | 0 | case ValueKind::kUnknown: |
1242 | 0 | return CelValue::CreateUnknownSet(google::protobuf::Arena::Create<Unknown>( |
1243 | 0 | arena, Cast<UnknownValue>(value).NativeValue())); |
1244 | 12 | case ValueKind::kType: |
1245 | 12 | return CelValue::CreateCelType( |
1246 | 12 | CelValue::CelTypeHolder(google::protobuf::Arena::Create<std::string>( |
1247 | 12 | arena, Cast<TypeValue>(value).NativeValue().name()))); |
1248 | 5.05k | case ValueKind::kError: |
1249 | 5.05k | return CelValue::CreateError(google::protobuf::Arena::Create<absl::Status>( |
1250 | 5.05k | arena, Cast<ErrorValue>(value).NativeValue())); |
1251 | 0 | default: |
1252 | 0 | return absl::InvalidArgumentError( |
1253 | 0 | absl::StrCat("google::api::expr::runtime::CelValue does not support ", |
1254 | 0 | ValueKindToString(value.kind()))); |
1255 | 9.89k | } |
1256 | 9.89k | } |
1257 | | |
1258 | | Value LegacyValueToModernValueOrDie( |
1259 | | google::protobuf::Arena* arena, const google::api::expr::runtime::CelValue& value, |
1260 | 0 | bool unchecked) { |
1261 | 0 | auto status_or_value = FromLegacyValue(arena, value, unchecked); |
1262 | 0 | ABSL_CHECK_OK(status_or_value.status()); // Crash OK |
1263 | 0 | return std::move(*status_or_value); |
1264 | 0 | } |
1265 | | |
1266 | | std::vector<Value> LegacyValueToModernValueOrDie( |
1267 | | google::protobuf::Arena* arena, |
1268 | | absl::Span<const google::api::expr::runtime::CelValue> values, |
1269 | 0 | bool unchecked) { |
1270 | 0 | std::vector<Value> modern_values; |
1271 | 0 | modern_values.reserve(values.size()); |
1272 | 0 | for (const auto& value : values) { |
1273 | 0 | modern_values.push_back( |
1274 | 0 | LegacyValueToModernValueOrDie(arena, value, unchecked)); |
1275 | 0 | } |
1276 | 0 | return modern_values; |
1277 | 0 | } |
1278 | | |
1279 | | google::api::expr::runtime::CelValue ModernValueToLegacyValueOrDie( |
1280 | 9.89k | google::protobuf::Arena* arena, const Value& value, bool unchecked) { |
1281 | 9.89k | auto status_or_value = ToLegacyValue(arena, value, unchecked); |
1282 | 9.89k | ABSL_CHECK_OK(status_or_value.status()); // Crash OK |
1283 | 9.89k | return std::move(*status_or_value); |
1284 | 9.89k | } |
1285 | | |
1286 | | TypeValue CreateTypeValueFromView(google::protobuf::Arena* arena, |
1287 | 0 | absl::string_view input) { |
1288 | 0 | return TypeValue(common_internal::LegacyRuntimeType(input)); |
1289 | 0 | } |
1290 | | |
1291 | | } // namespace interop_internal |
1292 | | |
1293 | | } // namespace cel |