/proc/self/cwd/runtime/internal/function_adapter.h
Line | Count | Source |
1 | | // Copyright 2023 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 | | // Definitions for implementation details of the function adapter utility. |
16 | | |
17 | | #ifndef THIRD_PARTY_CEL_CPP_RUNTIME_INTERNAL_FUNCTION_ADAPTER_H_ |
18 | | #define THIRD_PARTY_CEL_CPP_RUNTIME_INTERNAL_FUNCTION_ADAPTER_H_ |
19 | | |
20 | | #include <cstdint> |
21 | | #include <type_traits> |
22 | | #include <utility> |
23 | | |
24 | | #include "absl/status/status.h" |
25 | | #include "absl/status/statusor.h" |
26 | | #include "absl/time/time.h" |
27 | | #include "common/casting.h" |
28 | | #include "common/kind.h" |
29 | | #include "common/value.h" |
30 | | |
31 | | namespace cel::runtime_internal { |
32 | | |
33 | | // Helper for triggering static asserts in an unspecialized template overload. |
34 | | template <typename T> |
35 | | struct UnhandledType : std::false_type {}; |
36 | | |
37 | | // Adapts the type param Type to the appropriate Kind. |
38 | | // A static assertion fails if the provided type does not map to a cel::Value |
39 | | // kind. |
40 | | template <typename Type> |
41 | | constexpr Kind AdaptedKind() { |
42 | | static_assert(UnhandledType<Type>::value, |
43 | | "Unsupported primitive type to cel::Kind conversion"); |
44 | | return Kind::kNotForUseWithExhaustiveSwitchStatements; |
45 | | } |
46 | | |
47 | | template <> |
48 | 624k | constexpr Kind AdaptedKind<int64_t>() { |
49 | 624k | return Kind::kInt64; |
50 | 624k | } |
51 | | |
52 | | template <> |
53 | 595k | constexpr Kind AdaptedKind<uint64_t>() { |
54 | 595k | return Kind::kUint64; |
55 | 595k | } |
56 | | |
57 | | template <> |
58 | 580k | constexpr Kind AdaptedKind<double>() { |
59 | 580k | return Kind::kDouble; |
60 | 580k | } |
61 | | |
62 | | template <> |
63 | 217k | constexpr Kind AdaptedKind<bool>() { |
64 | 217k | return Kind::kBool; |
65 | 217k | } |
66 | | |
67 | | template <> |
68 | 522k | constexpr Kind AdaptedKind<absl::Time>() { |
69 | 522k | return Kind::kTimestamp; |
70 | 522k | } |
71 | | |
72 | | template <> |
73 | 304k | constexpr Kind AdaptedKind<absl::Duration>() { |
74 | 304k | return Kind::kDuration; |
75 | 304k | } |
76 | | |
77 | | // Value types without a generic C++ type representation can be referenced by |
78 | | // cref or value of the cel::*Value type. |
79 | | #define VALUE_ADAPTED_KIND_OVL(value_type, kind) \ |
80 | | template <> \ |
81 | 1.30M | constexpr Kind AdaptedKind<const value_type&>() { \ |
82 | 1.30M | return kind; \ |
83 | 1.30M | } \ cel::Kind cel::runtime_internal::AdaptedKind<cel::Value const&>() Line | Count | Source | 81 | 87.1k | constexpr Kind AdaptedKind<const value_type&>() { \ | 82 | 87.1k | return kind; \ | 83 | 87.1k | } \ |
cel::Kind cel::runtime_internal::AdaptedKind<cel::StringValue const&>() Line | Count | Source | 81 | 682k | constexpr Kind AdaptedKind<const value_type&>() { \ | 82 | 682k | return kind; \ | 83 | 682k | } \ |
cel::Kind cel::runtime_internal::AdaptedKind<cel::BytesValue const&>() Line | Count | Source | 81 | 188k | constexpr Kind AdaptedKind<const value_type&>() { \ | 82 | 188k | return kind; \ | 83 | 188k | } \ |
Unexecuted instantiation: cel::Kind cel::runtime_internal::AdaptedKind<cel::StructValue const&>() cel::Kind cel::runtime_internal::AdaptedKind<cel::MapValue const&>() Line | Count | Source | 81 | 246k | constexpr Kind AdaptedKind<const value_type&>() { \ | 82 | 246k | return kind; \ | 83 | 246k | } \ |
cel::Kind cel::runtime_internal::AdaptedKind<cel::ListValue const&>() Line | Count | Source | 81 | 101k | constexpr Kind AdaptedKind<const value_type&>() { \ | 82 | 101k | return kind; \ | 83 | 101k | } \ |
Unexecuted instantiation: cel::Kind cel::runtime_internal::AdaptedKind<cel::NullValue const&>() Unexecuted instantiation: cel::Kind cel::runtime_internal::AdaptedKind<cel::OpaqueValue const&>() Unexecuted instantiation: cel::Kind cel::runtime_internal::AdaptedKind<cel::TypeValue const&>() |
84 | | \ |
85 | | template <> \ |
86 | 87.1k | constexpr Kind AdaptedKind<value_type>() { \ |
87 | 87.1k | return kind; \ |
88 | 87.1k | } cel::Kind cel::runtime_internal::AdaptedKind<cel::Value>() Line | Count | Source | 86 | 29.0k | constexpr Kind AdaptedKind<value_type>() { \ | 87 | 29.0k | return kind; \ | 88 | 29.0k | } |
cel::Kind cel::runtime_internal::AdaptedKind<cel::StringValue>() Line | Count | Source | 86 | 29.0k | constexpr Kind AdaptedKind<value_type>() { \ | 87 | 29.0k | return kind; \ | 88 | 29.0k | } |
cel::Kind cel::runtime_internal::AdaptedKind<cel::BytesValue>() Line | Count | Source | 86 | 14.5k | constexpr Kind AdaptedKind<value_type>() { \ | 87 | 14.5k | return kind; \ | 88 | 14.5k | } |
Unexecuted instantiation: cel::Kind cel::runtime_internal::AdaptedKind<cel::StructValue>() Unexecuted instantiation: cel::Kind cel::runtime_internal::AdaptedKind<cel::MapValue>() cel::Kind cel::runtime_internal::AdaptedKind<cel::ListValue>() Line | Count | Source | 86 | 14.5k | constexpr Kind AdaptedKind<value_type>() { \ | 87 | 14.5k | return kind; \ | 88 | 14.5k | } |
Unexecuted instantiation: cel::Kind cel::runtime_internal::AdaptedKind<cel::NullValue>() Unexecuted instantiation: cel::Kind cel::runtime_internal::AdaptedKind<cel::OpaqueValue>() Unexecuted instantiation: cel::Kind cel::runtime_internal::AdaptedKind<cel::TypeValue>() |
89 | | |
90 | | VALUE_ADAPTED_KIND_OVL(Value, Kind::kAny); |
91 | | VALUE_ADAPTED_KIND_OVL(StringValue, Kind::kString); |
92 | | VALUE_ADAPTED_KIND_OVL(BytesValue, Kind::kBytes); |
93 | | VALUE_ADAPTED_KIND_OVL(StructValue, Kind::kStruct); |
94 | | VALUE_ADAPTED_KIND_OVL(MapValue, Kind::kMap); |
95 | | VALUE_ADAPTED_KIND_OVL(ListValue, Kind::kList); |
96 | | VALUE_ADAPTED_KIND_OVL(NullValue, Kind::kNullType); |
97 | | VALUE_ADAPTED_KIND_OVL(OpaqueValue, Kind::kOpaque); |
98 | | VALUE_ADAPTED_KIND_OVL(TypeValue, Kind::kType); |
99 | | |
100 | | #undef VALUE_ADAPTED_KIND_OVL |
101 | | |
102 | | // Adapt a Value to its corresponding argument type in a wrapped c++ |
103 | | // function. |
104 | | struct ValueToAdaptedVisitor { |
105 | 28.1k | absl::Status operator()(int64_t* out) const { |
106 | 28.1k | if (!input.IsInt()) { |
107 | 0 | return absl::InvalidArgumentError("expected int value"); |
108 | 0 | } |
109 | 28.1k | *out = input.GetInt().NativeValue(); |
110 | 28.1k | return absl::OkStatus(); |
111 | 28.1k | } |
112 | | |
113 | 9.94k | absl::Status operator()(uint64_t* out) const { |
114 | 9.94k | if (!input.IsUint()) { |
115 | 0 | return absl::InvalidArgumentError("expected uint value"); |
116 | 0 | } |
117 | 9.94k | *out = input.GetUint().NativeValue(); |
118 | 9.94k | return absl::OkStatus(); |
119 | 9.94k | } |
120 | | |
121 | 8.80k | absl::Status operator()(double* out) const { |
122 | 8.80k | if (!input.IsDouble()) { |
123 | 0 | return absl::InvalidArgumentError("expected double value"); |
124 | 0 | } |
125 | 8.80k | *out = input.GetDouble().NativeValue(); |
126 | 8.80k | return absl::OkStatus(); |
127 | 8.80k | } |
128 | | |
129 | 435 | absl::Status operator()(bool* out) const { |
130 | 435 | if (!input.IsBool()) { |
131 | 0 | return absl::InvalidArgumentError("expected bool value"); |
132 | 0 | } |
133 | 435 | *out = input.GetBool().NativeValue(); |
134 | 435 | return absl::OkStatus(); |
135 | 435 | } |
136 | | |
137 | 1 | absl::Status operator()(absl::Time* out) const { |
138 | 1 | if (!input.IsTimestamp()) { |
139 | 0 | return absl::InvalidArgumentError("expected timestamp value"); |
140 | 0 | } |
141 | 1 | *out = input.GetTimestamp().ToTime(); |
142 | 1 | return absl::OkStatus(); |
143 | 1 | } |
144 | | |
145 | 5 | absl::Status operator()(absl::Duration* out) const { |
146 | 5 | if (!input.IsDuration()) { |
147 | 0 | return absl::InvalidArgumentError("expected duration value"); |
148 | 0 | } |
149 | 5 | *out = input.GetDuration().ToDuration(); |
150 | 5 | return absl::OkStatus(); |
151 | 5 | } |
152 | | |
153 | 0 | absl::Status operator()(Value* out) const { |
154 | 0 | *out = input; |
155 | 0 | return absl::OkStatus(); |
156 | 0 | } |
157 | | |
158 | 145 | absl::Status operator()(const Value** out) const { |
159 | 145 | *out = &input; |
160 | 145 | return absl::OkStatus(); |
161 | 145 | } |
162 | | |
163 | | template <typename T> |
164 | 7.30k | absl::Status operator()(T* out) const { |
165 | 7.30k | if (!InstanceOf<std::remove_const_t<T>>(input)) { |
166 | 0 | return absl::InvalidArgumentError( |
167 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); |
168 | 0 | } |
169 | 7.30k | *out = Cast<std::remove_const_t<T>>(input); |
170 | 7.30k | return absl::OkStatus(); |
171 | 7.30k | } absl::lts_20260107::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::ListValue>(cel::ListValue*) const Line | Count | Source | 164 | 6.97k | absl::Status operator()(T* out) const { | 165 | 6.97k | if (!InstanceOf<std::remove_const_t<T>>(input)) { | 166 | 0 | return absl::InvalidArgumentError( | 167 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); | 168 | 0 | } | 169 | 6.97k | *out = Cast<std::remove_const_t<T>>(input); | 170 | 6.97k | return absl::OkStatus(); | 171 | 6.97k | } |
Unexecuted instantiation: absl::lts_20260107::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::MapValue>(cel::MapValue*) const Unexecuted instantiation: absl::lts_20260107::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::NullValue>(cel::NullValue*) const Unexecuted instantiation: absl::lts_20260107::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::TypeValue>(cel::TypeValue*) const Unexecuted instantiation: absl::lts_20260107::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::StructValue>(cel::StructValue*) const absl::lts_20260107::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::StringValue>(cel::StringValue*) const Line | Count | Source | 164 | 324 | absl::Status operator()(T* out) const { | 165 | 324 | if (!InstanceOf<std::remove_const_t<T>>(input)) { | 166 | 0 | return absl::InvalidArgumentError( | 167 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); | 168 | 0 | } | 169 | 324 | *out = Cast<std::remove_const_t<T>>(input); | 170 | 324 | return absl::OkStatus(); | 171 | 324 | } |
Unexecuted instantiation: absl::lts_20260107::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::BytesValue>(cel::BytesValue*) const |
172 | | |
173 | | template <typename T> |
174 | 10.8k | absl::Status operator()(T** out) const { |
175 | 10.8k | if (!InstanceOf<std::remove_const_t<T>>(input)) { |
176 | 0 | return absl::InvalidArgumentError( |
177 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); |
178 | 0 | } |
179 | 10.8k | static_assert(std::is_lvalue_reference_v< |
180 | 10.8k | decltype(Cast<std::remove_const_t<T>>(input))>, |
181 | 10.8k | "expected l-value reference return type for Cast."); |
182 | 10.8k | *out = &Cast<std::remove_const_t<T>>(input); |
183 | 10.8k | return absl::OkStatus(); |
184 | 10.8k | } absl::lts_20260107::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::StringValue const>(cel::StringValue const**) const Line | Count | Source | 174 | 8.92k | absl::Status operator()(T** out) const { | 175 | 8.92k | if (!InstanceOf<std::remove_const_t<T>>(input)) { | 176 | 0 | return absl::InvalidArgumentError( | 177 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); | 178 | 0 | } | 179 | 8.92k | static_assert(std::is_lvalue_reference_v< | 180 | 8.92k | decltype(Cast<std::remove_const_t<T>>(input))>, | 181 | 8.92k | "expected l-value reference return type for Cast."); | 182 | 8.92k | *out = &Cast<std::remove_const_t<T>>(input); | 183 | 8.92k | return absl::OkStatus(); | 184 | 8.92k | } |
absl::lts_20260107::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::BytesValue const>(cel::BytesValue const**) const Line | Count | Source | 174 | 1.92k | absl::Status operator()(T** out) const { | 175 | 1.92k | if (!InstanceOf<std::remove_const_t<T>>(input)) { | 176 | 0 | return absl::InvalidArgumentError( | 177 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); | 178 | 0 | } | 179 | 1.92k | static_assert(std::is_lvalue_reference_v< | 180 | 1.92k | decltype(Cast<std::remove_const_t<T>>(input))>, | 181 | 1.92k | "expected l-value reference return type for Cast."); | 182 | 1.92k | *out = &Cast<std::remove_const_t<T>>(input); | 183 | 1.92k | return absl::OkStatus(); | 184 | 1.92k | } |
|
185 | | |
186 | | const Value& input; |
187 | | }; |
188 | | |
189 | | // Adapts the return value of a wrapped C++ function to its corresponding |
190 | | // Value representation. |
191 | | struct AdaptedToValueVisitor { |
192 | 423 | absl::StatusOr<Value> operator()(int64_t in) { return IntValue(in); } |
193 | | |
194 | 2 | absl::StatusOr<Value> operator()(uint64_t in) { return UintValue(in); } |
195 | | |
196 | 191 | absl::StatusOr<Value> operator()(double in) { return DoubleValue(in); } |
197 | | |
198 | 12.1k | absl::StatusOr<Value> operator()(bool in) { return BoolValue(in); } |
199 | | |
200 | 0 | absl::StatusOr<Value> operator()(absl::Time in) { |
201 | 0 | // Type matching may have already occurred. It's too late to change up the |
202 | 0 | // type and return an error. |
203 | 0 | return TimestampValue(in); |
204 | 0 | } |
205 | | |
206 | 0 | absl::StatusOr<Value> operator()(absl::Duration in) { |
207 | 0 | // Type matching may have already occurred. It's too late to change up the |
208 | 0 | // type and return an error. |
209 | 0 | return DurationValue(in); |
210 | 0 | } |
211 | | |
212 | 0 | absl::StatusOr<Value> operator()(Value in) { return in; } |
213 | | |
214 | | template <typename T> |
215 | 2.73k | absl::StatusOr<Value> operator()(T in) { |
216 | 2.73k | return in; |
217 | 2.73k | } Unexecuted instantiation: absl::lts_20260107::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::ListValue>(cel::ListValue) absl::lts_20260107::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::StringValue>(cel::StringValue) Line | Count | Source | 215 | 2.17k | absl::StatusOr<Value> operator()(T in) { | 216 | 2.17k | return in; | 217 | 2.17k | } |
absl::lts_20260107::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::BytesValue>(cel::BytesValue) Line | Count | Source | 215 | 558 | absl::StatusOr<Value> operator()(T in) { | 216 | 558 | return in; | 217 | 558 | } |
|
218 | | |
219 | | // Special case for StatusOr<T> return value -- wrap the underlying value if |
220 | | // present, otherwise return the status. |
221 | | template <typename T> |
222 | 2.73k | absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) { |
223 | 2.73k | if (!wrapped.ok()) { |
224 | 0 | return std::move(wrapped).status(); |
225 | 0 | } |
226 | 2.73k | return this->operator()(std::move(wrapped).value()); |
227 | 2.73k | } absl::lts_20260107::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<long>(absl::lts_20260107::StatusOr<long>) Line | Count | Source | 222 | 1 | absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) { | 223 | 1 | if (!wrapped.ok()) { | 224 | 0 | return std::move(wrapped).status(); | 225 | 0 | } | 226 | 1 | return this->operator()(std::move(wrapped).value()); | 227 | 1 | } |
Unexecuted instantiation: absl::lts_20260107::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::ListValue>(absl::lts_20260107::StatusOr<cel::ListValue>) Unexecuted instantiation: absl::lts_20260107::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<bool>(absl::lts_20260107::StatusOr<bool>) absl::lts_20260107::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::StringValue>(absl::lts_20260107::StatusOr<cel::StringValue>) Line | Count | Source | 222 | 2.17k | absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) { | 223 | 2.17k | if (!wrapped.ok()) { | 224 | 0 | return std::move(wrapped).status(); | 225 | 0 | } | 226 | 2.17k | return this->operator()(std::move(wrapped).value()); | 227 | 2.17k | } |
absl::lts_20260107::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::BytesValue>(absl::lts_20260107::StatusOr<cel::BytesValue>) Line | Count | Source | 222 | 558 | absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) { | 223 | 558 | if (!wrapped.ok()) { | 224 | 0 | return std::move(wrapped).status(); | 225 | 0 | } | 226 | 558 | return this->operator()(std::move(wrapped).value()); | 227 | 558 | } |
|
228 | | }; |
229 | | |
230 | | } // namespace cel::runtime_internal |
231 | | |
232 | | #endif // THIRD_PARTY_CEL_CPP_RUNTIME_INTERNAL_FUNCTION_ADAPTER_H_ |