Coverage Report

Created: 2026-10-09 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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_