/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/kind.h" |
28 | | #include "common/value.h" |
29 | | |
30 | | namespace cel::runtime_internal { |
31 | | |
32 | | // Helper for triggering static asserts in an unspecialized template overload. |
33 | | template <typename T> |
34 | | struct UnhandledType : std::false_type {}; |
35 | | |
36 | | // Adapts the type param Type to the appropriate Kind. |
37 | | // A static assertion fails if the provided type does not map to a cel::Value |
38 | | // kind. |
39 | | template <typename Type> |
40 | | constexpr Kind AdaptedKind() { |
41 | | static_assert(UnhandledType<Type>::value, |
42 | | "Unsupported primitive type to cel::Kind conversion"); |
43 | | return Kind::kNotForUseWithExhaustiveSwitchStatements; |
44 | | } |
45 | | |
46 | | template <> |
47 | 976k | constexpr Kind AdaptedKind<int64_t>() { |
48 | 976k | return Kind::kInt64; |
49 | 976k | } |
50 | | |
51 | | template <> |
52 | 931k | constexpr Kind AdaptedKind<uint64_t>() { |
53 | 931k | return Kind::kUint64; |
54 | 931k | } |
55 | | |
56 | | template <> |
57 | 908k | constexpr Kind AdaptedKind<double>() { |
58 | 908k | return Kind::kDouble; |
59 | 908k | } |
60 | | |
61 | | template <> |
62 | 340k | constexpr Kind AdaptedKind<bool>() { |
63 | 340k | return Kind::kBool; |
64 | 340k | } |
65 | | |
66 | | template <> |
67 | 817k | constexpr Kind AdaptedKind<absl::Time>() { |
68 | 817k | return Kind::kTimestamp; |
69 | 817k | } |
70 | | |
71 | | template <> |
72 | 476k | constexpr Kind AdaptedKind<absl::Duration>() { |
73 | 476k | return Kind::kDuration; |
74 | 476k | } |
75 | | |
76 | | // Value types without a generic C++ type representation can be referenced by |
77 | | // cref or value of the cel::*Value type. |
78 | | #define VALUE_ADAPTED_KIND_OVL(value_type, kind) \ |
79 | | template <> \ |
80 | 2.04M | constexpr Kind AdaptedKind<const value_type&>() { \ |
81 | 2.04M | return kind; \ |
82 | 2.04M | } \ cel::Kind cel::runtime_internal::AdaptedKind<cel::Value const&>() Line | Count | Source | 80 | 136k | constexpr Kind AdaptedKind<const value_type&>() { \ | 81 | 136k | return kind; \ | 82 | 136k | } \ |
cel::Kind cel::runtime_internal::AdaptedKind<cel::StringValue const&>() Line | Count | Source | 80 | 1.06M | constexpr Kind AdaptedKind<const value_type&>() { \ | 81 | 1.06M | return kind; \ | 82 | 1.06M | } \ |
cel::Kind cel::runtime_internal::AdaptedKind<cel::BytesValue const&>() Line | Count | Source | 80 | 295k | constexpr Kind AdaptedKind<const value_type&>() { \ | 81 | 295k | return kind; \ | 82 | 295k | } \ |
Unexecuted instantiation: cel::Kind cel::runtime_internal::AdaptedKind<cel::StructValue const&>() cel::Kind cel::runtime_internal::AdaptedKind<cel::MapValue const&>() Line | Count | Source | 80 | 386k | constexpr Kind AdaptedKind<const value_type&>() { \ | 81 | 386k | return kind; \ | 82 | 386k | } \ |
cel::Kind cel::runtime_internal::AdaptedKind<cel::ListValue const&>() Line | Count | Source | 80 | 158k | constexpr Kind AdaptedKind<const value_type&>() { \ | 81 | 158k | return kind; \ | 82 | 158k | } \ |
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&>() |
83 | | \ |
84 | | template <> \ |
85 | 136k | constexpr Kind AdaptedKind<value_type>() { \ |
86 | 136k | return kind; \ |
87 | 136k | } cel::Kind cel::runtime_internal::AdaptedKind<cel::Value>() Line | Count | Source | 85 | 45.4k | constexpr Kind AdaptedKind<value_type>() { \ | 86 | 45.4k | return kind; \ | 87 | 45.4k | } |
cel::Kind cel::runtime_internal::AdaptedKind<cel::StringValue>() Line | Count | Source | 85 | 45.4k | constexpr Kind AdaptedKind<value_type>() { \ | 86 | 45.4k | return kind; \ | 87 | 45.4k | } |
cel::Kind cel::runtime_internal::AdaptedKind<cel::BytesValue>() Line | Count | Source | 85 | 22.7k | constexpr Kind AdaptedKind<value_type>() { \ | 86 | 22.7k | return kind; \ | 87 | 22.7k | } |
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 | 85 | 22.7k | constexpr Kind AdaptedKind<value_type>() { \ | 86 | 22.7k | return kind; \ | 87 | 22.7k | } |
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>() |
88 | | |
89 | | VALUE_ADAPTED_KIND_OVL(Value, Kind::kAny); |
90 | | VALUE_ADAPTED_KIND_OVL(StringValue, Kind::kString); |
91 | | VALUE_ADAPTED_KIND_OVL(BytesValue, Kind::kBytes); |
92 | | VALUE_ADAPTED_KIND_OVL(StructValue, Kind::kStruct); |
93 | | VALUE_ADAPTED_KIND_OVL(MapValue, Kind::kMap); |
94 | | VALUE_ADAPTED_KIND_OVL(ListValue, Kind::kList); |
95 | | VALUE_ADAPTED_KIND_OVL(NullValue, Kind::kNullType); |
96 | | VALUE_ADAPTED_KIND_OVL(OpaqueValue, Kind::kOpaque); |
97 | | VALUE_ADAPTED_KIND_OVL(TypeValue, Kind::kType); |
98 | | |
99 | | #undef VALUE_ADAPTED_KIND_OVL |
100 | | |
101 | | // Adapt a Value to its corresponding argument type in a wrapped c++ |
102 | | // function. |
103 | | struct ValueToAdaptedVisitor { |
104 | 2.19M | absl::Status operator()(int64_t* out) const { |
105 | 2.19M | if (!input.IsInt()) { |
106 | 0 | return absl::InvalidArgumentError("expected int value"); |
107 | 0 | } |
108 | 2.19M | *out = input.GetInt().NativeValue(); |
109 | 2.19M | return absl::OkStatus(); |
110 | 2.19M | } |
111 | | |
112 | 3.48M | absl::Status operator()(uint64_t* out) const { |
113 | 3.48M | if (!input.IsUint()) { |
114 | 0 | return absl::InvalidArgumentError("expected uint value"); |
115 | 0 | } |
116 | 3.48M | *out = input.GetUint().NativeValue(); |
117 | 3.48M | return absl::OkStatus(); |
118 | 3.48M | } |
119 | | |
120 | 375k | absl::Status operator()(double* out) const { |
121 | 375k | if (!input.IsDouble()) { |
122 | 0 | return absl::InvalidArgumentError("expected double value"); |
123 | 0 | } |
124 | 375k | *out = input.GetDouble().NativeValue(); |
125 | 375k | return absl::OkStatus(); |
126 | 375k | } |
127 | | |
128 | 3.39k | absl::Status operator()(bool* out) const { |
129 | 3.39k | if (!input.IsBool()) { |
130 | 0 | return absl::InvalidArgumentError("expected bool value"); |
131 | 0 | } |
132 | 3.39k | *out = input.GetBool().NativeValue(); |
133 | 3.39k | return absl::OkStatus(); |
134 | 3.39k | } |
135 | | |
136 | 6.30k | absl::Status operator()(absl::Time* out) const { |
137 | 6.30k | if (!input.IsTimestamp()) { |
138 | 0 | return absl::InvalidArgumentError("expected timestamp value"); |
139 | 0 | } |
140 | 6.30k | *out = input.GetTimestamp().ToTime(); |
141 | 6.30k | return absl::OkStatus(); |
142 | 6.30k | } |
143 | | |
144 | 11.1k | absl::Status operator()(absl::Duration* out) const { |
145 | 11.1k | if (!input.IsDuration()) { |
146 | 0 | return absl::InvalidArgumentError("expected duration value"); |
147 | 0 | } |
148 | 11.1k | *out = input.GetDuration().ToDuration(); |
149 | 11.1k | return absl::OkStatus(); |
150 | 11.1k | } |
151 | | |
152 | 0 | absl::Status operator()(Value* out) const { |
153 | 0 | *out = input; |
154 | 0 | return absl::OkStatus(); |
155 | 0 | } |
156 | | |
157 | 4.07k | absl::Status operator()(const Value** out) const { |
158 | 4.07k | *out = &input; |
159 | 4.07k | return absl::OkStatus(); |
160 | 4.07k | } |
161 | | |
162 | | template <typename T> |
163 | 1.01M | absl::Status operator()(T* out) const { |
164 | 1.01M | if (!input.Is<std::remove_const_t<T>>()) { |
165 | 0 | return absl::InvalidArgumentError( |
166 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); |
167 | 0 | } |
168 | 1.01M | *out = input.Get<std::remove_const_t<T>>(); |
169 | 1.01M | return absl::OkStatus(); |
170 | 1.01M | } absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::ListValue>(cel::ListValue*) const Line | Count | Source | 163 | 995k | absl::Status operator()(T* out) const { | 164 | 995k | if (!input.Is<std::remove_const_t<T>>()) { | 165 | 0 | return absl::InvalidArgumentError( | 166 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); | 167 | 0 | } | 168 | 995k | *out = input.Get<std::remove_const_t<T>>(); | 169 | 995k | return absl::OkStatus(); | 170 | 995k | } |
absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::MapValue>(cel::MapValue*) const Line | Count | Source | 163 | 711 | absl::Status operator()(T* out) const { | 164 | 711 | if (!input.Is<std::remove_const_t<T>>()) { | 165 | 0 | return absl::InvalidArgumentError( | 166 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); | 167 | 0 | } | 168 | 711 | *out = input.Get<std::remove_const_t<T>>(); | 169 | 711 | return absl::OkStatus(); | 170 | 711 | } |
Unexecuted instantiation: absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::NullValue>(cel::NullValue*) const Unexecuted instantiation: absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::TypeValue>(cel::TypeValue*) const Unexecuted instantiation: absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::StructValue>(cel::StructValue*) const absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::StringValue>(cel::StringValue*) const Line | Count | Source | 163 | 20.4k | absl::Status operator()(T* out) const { | 164 | 20.4k | if (!input.Is<std::remove_const_t<T>>()) { | 165 | 0 | return absl::InvalidArgumentError( | 166 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); | 167 | 0 | } | 168 | 20.4k | *out = input.Get<std::remove_const_t<T>>(); | 169 | 20.4k | return absl::OkStatus(); | 170 | 20.4k | } |
absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::BytesValue>(cel::BytesValue*) const Line | Count | Source | 163 | 147 | absl::Status operator()(T* out) const { | 164 | 147 | if (!input.Is<std::remove_const_t<T>>()) { | 165 | 0 | return absl::InvalidArgumentError( | 166 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); | 167 | 0 | } | 168 | 147 | *out = input.Get<std::remove_const_t<T>>(); | 169 | 147 | return absl::OkStatus(); | 170 | 147 | } |
|
171 | | |
172 | | template <typename T> |
173 | 183k | absl::Status operator()(T** out) const { |
174 | 183k | if (!input.Is<std::remove_const_t<T>>()) { |
175 | 0 | return absl::InvalidArgumentError( |
176 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); |
177 | 0 | } |
178 | 183k | static_assert(std::is_lvalue_reference_v< |
179 | 183k | decltype(input.Get<std::remove_const_t<T>>())>, |
180 | 183k | "expected l-value reference return type for Cast."); |
181 | 183k | *out = &input.Get<std::remove_const_t<T>>(); |
182 | 183k | return absl::OkStatus(); |
183 | 183k | } absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::StringValue const>(cel::StringValue const**) const Line | Count | Source | 173 | 172k | absl::Status operator()(T** out) const { | 174 | 172k | if (!input.Is<std::remove_const_t<T>>()) { | 175 | 0 | return absl::InvalidArgumentError( | 176 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); | 177 | 0 | } | 178 | 172k | static_assert(std::is_lvalue_reference_v< | 179 | 172k | decltype(input.Get<std::remove_const_t<T>>())>, | 180 | 172k | "expected l-value reference return type for Cast."); | 181 | 172k | *out = &input.Get<std::remove_const_t<T>>(); | 182 | 172k | return absl::OkStatus(); | 183 | 172k | } |
absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::BytesValue const>(cel::BytesValue const**) const Line | Count | Source | 173 | 10.6k | absl::Status operator()(T** out) const { | 174 | 10.6k | if (!input.Is<std::remove_const_t<T>>()) { | 175 | 0 | return absl::InvalidArgumentError( | 176 | 0 | absl::StrCat("expected ", ValueKindToString(T::kKind), " value")); | 177 | 0 | } | 178 | 10.6k | static_assert(std::is_lvalue_reference_v< | 179 | 10.6k | decltype(input.Get<std::remove_const_t<T>>())>, | 180 | 10.6k | "expected l-value reference return type for Cast."); | 181 | 10.6k | *out = &input.Get<std::remove_const_t<T>>(); | 182 | 10.6k | return absl::OkStatus(); | 183 | 10.6k | } |
|
184 | | |
185 | | const Value& input; |
186 | | }; |
187 | | |
188 | | // Adapts the return value of a wrapped C++ function to its corresponding |
189 | | // Value representation. |
190 | | struct AdaptedToValueVisitor { |
191 | 2.25k | absl::StatusOr<Value> operator()(int64_t in) { return IntValue(in); } |
192 | | |
193 | 197 | absl::StatusOr<Value> operator()(uint64_t in) { return UintValue(in); } |
194 | | |
195 | 41.2k | absl::StatusOr<Value> operator()(double in) { return DoubleValue(in); } |
196 | | |
197 | 286k | absl::StatusOr<Value> operator()(bool in) { return BoolValue(in); } |
198 | | |
199 | 0 | absl::StatusOr<Value> operator()(absl::Time in) { |
200 | 0 | // Type matching may have already occurred. It's too late to change up the |
201 | 0 | // type and return an error. |
202 | 0 | return UnsafeTimestampValue(in); |
203 | 0 | } |
204 | | |
205 | 0 | absl::StatusOr<Value> operator()(absl::Duration in) { |
206 | 0 | // Type matching may have already occurred. It's too late to change up the |
207 | 0 | // type and return an error. |
208 | 0 | return UnsafeDurationValue(in); |
209 | 0 | } |
210 | | |
211 | 0 | absl::StatusOr<Value> operator()(Value in) { return in; } |
212 | | |
213 | | template <typename T> |
214 | 6.74k | absl::StatusOr<Value> operator()(T in) { |
215 | 6.74k | return in; |
216 | 6.74k | } Unexecuted instantiation: absl::lts_20260526::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::ListValue>(cel::ListValue) absl::lts_20260526::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::StringValue>(cel::StringValue) Line | Count | Source | 214 | 5.11k | absl::StatusOr<Value> operator()(T in) { | 215 | 5.11k | return in; | 216 | 5.11k | } |
absl::lts_20260526::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::BytesValue>(cel::BytesValue) Line | Count | Source | 214 | 1.62k | absl::StatusOr<Value> operator()(T in) { | 215 | 1.62k | return in; | 216 | 1.62k | } |
|
217 | | |
218 | | // Special case for StatusOr<T> return value -- wrap the underlying value if |
219 | | // present, otherwise return the status. |
220 | | template <typename T> |
221 | 5.66k | absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) { |
222 | 5.66k | if (!wrapped.ok()) { |
223 | 0 | return std::move(wrapped).status(); |
224 | 0 | } |
225 | 5.66k | return this->operator()(std::move(wrapped).value()); |
226 | 5.66k | } absl::lts_20260526::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<long>(absl::lts_20260526::StatusOr<long>) Line | Count | Source | 221 | 784 | absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) { | 222 | 784 | if (!wrapped.ok()) { | 223 | 0 | return std::move(wrapped).status(); | 224 | 0 | } | 225 | 784 | return this->operator()(std::move(wrapped).value()); | 226 | 784 | } |
Unexecuted instantiation: absl::lts_20260526::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::ListValue>(absl::lts_20260526::StatusOr<cel::ListValue>) Unexecuted instantiation: absl::lts_20260526::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<bool>(absl::lts_20260526::StatusOr<bool>) absl::lts_20260526::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::StringValue>(absl::lts_20260526::StatusOr<cel::StringValue>) Line | Count | Source | 221 | 3.40k | absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) { | 222 | 3.40k | if (!wrapped.ok()) { | 223 | 0 | return std::move(wrapped).status(); | 224 | 0 | } | 225 | 3.40k | return this->operator()(std::move(wrapped).value()); | 226 | 3.40k | } |
absl::lts_20260526::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::BytesValue>(absl::lts_20260526::StatusOr<cel::BytesValue>) Line | Count | Source | 221 | 1.47k | absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) { | 222 | 1.47k | if (!wrapped.ok()) { | 223 | 0 | return std::move(wrapped).status(); | 224 | 0 | } | 225 | 1.47k | return this->operator()(std::move(wrapped).value()); | 226 | 1.47k | } |
|
227 | | }; |
228 | | |
229 | | } // namespace cel::runtime_internal |
230 | | |
231 | | #endif // THIRD_PARTY_CEL_CPP_RUNTIME_INTERNAL_FUNCTION_ADAPTER_H_ |