/proc/self/cwd/common/values/parsed_json_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/values/parsed_json_value.h" |
16 | | |
17 | | #include <string> |
18 | | #include <utility> |
19 | | |
20 | | #include "absl/base/attributes.h" |
21 | | #include "absl/base/nullability.h" |
22 | | #include "absl/functional/overload.h" |
23 | | #include "absl/status/status.h" |
24 | | #include "absl/strings/cord.h" |
25 | | #include "absl/strings/str_cat.h" |
26 | | #include "absl/strings/string_view.h" |
27 | | #include "absl/types/variant.h" |
28 | | #include "common/value.h" |
29 | | #include "internal/well_known_types.h" |
30 | | #include "google/protobuf/arena.h" |
31 | | #include "google/protobuf/message.h" |
32 | | |
33 | | namespace cel::common_internal { |
34 | | |
35 | | namespace { |
36 | | |
37 | | using ::cel::well_known_types::AsVariant; |
38 | | using ::cel::well_known_types::GetValueReflectionOrDie; |
39 | | |
40 | | google::protobuf::Arena* absl_nonnull MessageArenaOr( |
41 | | const google::protobuf::Message* absl_nonnull message, |
42 | 1.33k | google::protobuf::Arena* absl_nonnull or_arena) { |
43 | 1.33k | google::protobuf::Arena* absl_nullable arena = message->GetArena(); |
44 | 1.33k | if (arena == nullptr) { |
45 | 0 | arena = or_arena; |
46 | 0 | } |
47 | 1.33k | return arena; |
48 | 1.33k | } |
49 | | |
50 | | } // namespace |
51 | | |
52 | | Value ParsedJsonValue(const google::protobuf::Message* absl_nonnull message, |
53 | 46.5k | google::protobuf::Arena* absl_nonnull arena) { |
54 | 46.5k | const auto reflection = GetValueReflectionOrDie(message->GetDescriptor()); |
55 | 46.5k | const auto kind_case = reflection.GetKindCase(*message); |
56 | 46.5k | switch (kind_case) { |
57 | 0 | case google::protobuf::Value::KIND_NOT_SET: |
58 | 0 | ABSL_FALLTHROUGH_INTENDED; |
59 | 244 | case google::protobuf::Value::kNullValue: |
60 | 244 | return NullValue(); |
61 | 14.7k | case google::protobuf::Value::kBoolValue: |
62 | 14.7k | return BoolValue(reflection.GetBoolValue(*message)); |
63 | 28.8k | case google::protobuf::Value::kNumberValue: |
64 | 28.8k | return DoubleValue(reflection.GetNumberValue(*message)); |
65 | 1.35k | case google::protobuf::Value::kStringValue: { |
66 | 1.35k | std::string scratch; |
67 | 1.35k | return absl::visit( |
68 | 1.35k | absl::Overload( |
69 | 1.35k | [&](absl::string_view string) -> StringValue { |
70 | 1.35k | if (string.empty()) { |
71 | 754 | return StringValue(); |
72 | 754 | } |
73 | 601 | if (string.data() == scratch.data() && |
74 | 0 | string.size() == scratch.size()) { |
75 | 0 | return StringValue::From(std::move(scratch), arena); |
76 | 601 | } else { |
77 | 601 | if (google::protobuf::Arena* message_arena = message->GetArena(); |
78 | 601 | message_arena != nullptr) { |
79 | 601 | return StringValue::Wrap(string, message_arena); |
80 | 601 | } |
81 | 0 | return StringValue::From(string, arena); |
82 | 601 | } |
83 | 601 | }, |
84 | 1.35k | [&](absl::Cord&& cord) -> StringValue { |
85 | 0 | if (cord.empty()) { |
86 | 0 | return StringValue(); |
87 | 0 | } |
88 | 0 | return StringValue::From(std::move(cord), arena); |
89 | 0 | }), |
90 | 1.35k | AsVariant(reflection.GetStringValue(*message, scratch))); |
91 | 0 | } |
92 | 472 | case google::protobuf::Value::kListValue: |
93 | 472 | return ParsedJsonListValue(&reflection.GetListValue(*message), |
94 | 472 | MessageArenaOr(message, arena)); |
95 | 864 | case google::protobuf::Value::kStructValue: |
96 | 864 | return ParsedJsonMapValue(&reflection.GetStructValue(*message), |
97 | 864 | MessageArenaOr(message, arena)); |
98 | 0 | default: |
99 | 0 | return ErrorValue::From(absl::InvalidArgumentError(absl::StrCat( |
100 | 0 | "unexpected value kind case: ", kind_case)), |
101 | 0 | arena); |
102 | 46.5k | } |
103 | 46.5k | } |
104 | | |
105 | | } // namespace cel::common_internal |