Coverage Report

Created: 2026-09-14 06:52

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/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
1.06M
constexpr Kind AdaptedKind<int64_t>() {
49
1.06M
  return Kind::kInt64;
50
1.06M
}
51
52
template <>
53
1.01M
constexpr Kind AdaptedKind<uint64_t>() {
54
1.01M
  return Kind::kUint64;
55
1.01M
}
56
57
template <>
58
992k
constexpr Kind AdaptedKind<double>() {
59
992k
  return Kind::kDouble;
60
992k
}
61
62
template <>
63
372k
constexpr Kind AdaptedKind<bool>() {
64
372k
  return Kind::kBool;
65
372k
}
66
67
template <>
68
893k
constexpr Kind AdaptedKind<absl::Time>() {
69
893k
  return Kind::kTimestamp;
70
893k
}
71
72
template <>
73
521k
constexpr Kind AdaptedKind<absl::Duration>() {
74
521k
  return Kind::kDuration;
75
521k
}
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
2.23M
  constexpr Kind AdaptedKind<const value_type&>() { \
82
2.23M
    return kind;                                    \
83
2.23M
  }                                                 \
cel::Kind cel::runtime_internal::AdaptedKind<cel::Value const&>()
Line
Count
Source
81
148k
  constexpr Kind AdaptedKind<const value_type&>() { \
82
148k
    return kind;                                    \
83
148k
  }                                                 \
cel::Kind cel::runtime_internal::AdaptedKind<cel::StringValue const&>()
Line
Count
Source
81
1.16M
  constexpr Kind AdaptedKind<const value_type&>() { \
82
1.16M
    return kind;                                    \
83
1.16M
  }                                                 \
cel::Kind cel::runtime_internal::AdaptedKind<cel::BytesValue const&>()
Line
Count
Source
81
322k
  constexpr Kind AdaptedKind<const value_type&>() { \
82
322k
    return kind;                                    \
83
322k
  }                                                 \
Unexecuted instantiation: cel::Kind cel::runtime_internal::AdaptedKind<cel::StructValue const&>()
cel::Kind cel::runtime_internal::AdaptedKind<cel::MapValue const&>()
Line
Count
Source
81
421k
  constexpr Kind AdaptedKind<const value_type&>() { \
82
421k
    return kind;                                    \
83
421k
  }                                                 \
cel::Kind cel::runtime_internal::AdaptedKind<cel::ListValue const&>()
Line
Count
Source
81
173k
  constexpr Kind AdaptedKind<const value_type&>() { \
82
173k
    return kind;                                    \
83
173k
  }                                                 \
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
148k
  constexpr Kind AdaptedKind<value_type>() {        \
87
148k
    return kind;                                    \
88
148k
  }
cel::Kind cel::runtime_internal::AdaptedKind<cel::Value>()
Line
Count
Source
86
49.6k
  constexpr Kind AdaptedKind<value_type>() {        \
87
49.6k
    return kind;                                    \
88
49.6k
  }
cel::Kind cel::runtime_internal::AdaptedKind<cel::StringValue>()
Line
Count
Source
86
49.6k
  constexpr Kind AdaptedKind<value_type>() {        \
87
49.6k
    return kind;                                    \
88
49.6k
  }
cel::Kind cel::runtime_internal::AdaptedKind<cel::BytesValue>()
Line
Count
Source
86
24.8k
  constexpr Kind AdaptedKind<value_type>() {        \
87
24.8k
    return kind;                                    \
88
24.8k
  }
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
24.8k
  constexpr Kind AdaptedKind<value_type>() {        \
87
24.8k
    return kind;                                    \
88
24.8k
  }
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
1.75M
  absl::Status operator()(int64_t* out) const {
106
1.75M
    if (!input.IsInt()) {
107
0
      return absl::InvalidArgumentError("expected int value");
108
0
    }
109
1.75M
    *out = input.GetInt().NativeValue();
110
1.75M
    return absl::OkStatus();
111
1.75M
  }
112
113
103k
  absl::Status operator()(uint64_t* out) const {
114
103k
    if (!input.IsUint()) {
115
0
      return absl::InvalidArgumentError("expected uint value");
116
0
    }
117
103k
    *out = input.GetUint().NativeValue();
118
103k
    return absl::OkStatus();
119
103k
  }
120
121
238k
  absl::Status operator()(double* out) const {
122
238k
    if (!input.IsDouble()) {
123
0
      return absl::InvalidArgumentError("expected double value");
124
0
    }
125
238k
    *out = input.GetDouble().NativeValue();
126
238k
    return absl::OkStatus();
127
238k
  }
128
129
3.41k
  absl::Status operator()(bool* out) const {
130
3.41k
    if (!input.IsBool()) {
131
0
      return absl::InvalidArgumentError("expected bool value");
132
0
    }
133
3.41k
    *out = input.GetBool().NativeValue();
134
3.41k
    return absl::OkStatus();
135
3.41k
  }
136
137
2.98k
  absl::Status operator()(absl::Time* out) const {
138
2.98k
    if (!input.IsTimestamp()) {
139
0
      return absl::InvalidArgumentError("expected timestamp value");
140
0
    }
141
2.98k
    *out = input.GetTimestamp().ToTime();
142
2.98k
    return absl::OkStatus();
143
2.98k
  }
144
145
12.0k
  absl::Status operator()(absl::Duration* out) const {
146
12.0k
    if (!input.IsDuration()) {
147
0
      return absl::InvalidArgumentError("expected duration value");
148
0
    }
149
12.0k
    *out = input.GetDuration().ToDuration();
150
12.0k
    return absl::OkStatus();
151
12.0k
  }
152
153
0
  absl::Status operator()(Value* out) const {
154
0
    *out = input;
155
0
    return absl::OkStatus();
156
0
  }
157
158
6.90k
  absl::Status operator()(const Value** out) const {
159
6.90k
    *out = &input;
160
6.90k
    return absl::OkStatus();
161
6.90k
  }
162
163
  template <typename T>
164
1.78M
  absl::Status operator()(T* out) const {
165
1.78M
    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
1.78M
    *out = Cast<std::remove_const_t<T>>(input);
170
1.78M
    return absl::OkStatus();
171
1.78M
  }
absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::ListValue>(cel::ListValue*) const
Line
Count
Source
164
1.76M
  absl::Status operator()(T* out) const {
165
1.76M
    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
1.76M
    *out = Cast<std::remove_const_t<T>>(input);
170
1.76M
    return absl::OkStatus();
171
1.76M
  }
absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::MapValue>(cel::MapValue*) const
Line
Count
Source
164
250
  absl::Status operator()(T* out) const {
165
250
    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
250
    *out = Cast<std::remove_const_t<T>>(input);
170
250
    return absl::OkStatus();
171
250
  }
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
164
11.1k
  absl::Status operator()(T* out) const {
165
11.1k
    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
11.1k
    *out = Cast<std::remove_const_t<T>>(input);
170
11.1k
    return absl::OkStatus();
171
11.1k
  }
absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::BytesValue>(cel::BytesValue*) const
Line
Count
Source
164
554
  absl::Status operator()(T* out) const {
165
554
    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
554
    *out = Cast<std::remove_const_t<T>>(input);
170
554
    return absl::OkStatus();
171
554
  }
172
173
  template <typename T>
174
319k
  absl::Status operator()(T** out) const {
175
319k
    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
319k
    static_assert(std::is_lvalue_reference_v<
180
319k
                      decltype(Cast<std::remove_const_t<T>>(input))>,
181
319k
                  "expected l-value reference return type for Cast.");
182
319k
    *out = &Cast<std::remove_const_t<T>>(input);
183
319k
    return absl::OkStatus();
184
319k
  }
absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::StringValue const>(cel::StringValue const**) const
Line
Count
Source
174
298k
  absl::Status operator()(T** out) const {
175
298k
    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
298k
    static_assert(std::is_lvalue_reference_v<
180
298k
                      decltype(Cast<std::remove_const_t<T>>(input))>,
181
298k
                  "expected l-value reference return type for Cast.");
182
298k
    *out = &Cast<std::remove_const_t<T>>(input);
183
298k
    return absl::OkStatus();
184
298k
  }
absl::lts_20260526::Status cel::runtime_internal::ValueToAdaptedVisitor::operator()<cel::BytesValue const>(cel::BytesValue const**) const
Line
Count
Source
174
21.1k
  absl::Status operator()(T** out) const {
175
21.1k
    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
21.1k
    static_assert(std::is_lvalue_reference_v<
180
21.1k
                      decltype(Cast<std::remove_const_t<T>>(input))>,
181
21.1k
                  "expected l-value reference return type for Cast.");
182
21.1k
    *out = &Cast<std::remove_const_t<T>>(input);
183
21.1k
    return absl::OkStatus();
184
21.1k
  }
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
1.87k
  absl::StatusOr<Value> operator()(int64_t in) { return IntValue(in); }
193
194
194
  absl::StatusOr<Value> operator()(uint64_t in) { return UintValue(in); }
195
196
4.40k
  absl::StatusOr<Value> operator()(double in) { return DoubleValue(in); }
197
198
288k
  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 UnsafeTimestampValue(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 UnsafeDurationValue(in);
210
0
  }
211
212
0
  absl::StatusOr<Value> operator()(Value in) { return in; }
213
214
  template <typename T>
215
11.4k
  absl::StatusOr<Value> operator()(T in) {
216
11.4k
    return in;
217
11.4k
  }
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
215
5.00k
  absl::StatusOr<Value> operator()(T in) {
216
5.00k
    return in;
217
5.00k
  }
absl::lts_20260526::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::BytesValue>(cel::BytesValue)
Line
Count
Source
215
6.40k
  absl::StatusOr<Value> operator()(T in) {
216
6.40k
    return in;
217
6.40k
  }
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
8.36k
  absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) {
223
8.36k
    if (!wrapped.ok()) {
224
0
      return std::move(wrapped).status();
225
0
    }
226
8.36k
    return this->operator()(std::move(wrapped).value());
227
8.36k
  }
absl::lts_20260526::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<long>(absl::lts_20260526::StatusOr<long>)
Line
Count
Source
222
324
  absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) {
223
324
    if (!wrapped.ok()) {
224
0
      return std::move(wrapped).status();
225
0
    }
226
324
    return this->operator()(std::move(wrapped).value());
227
324
  }
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
222
2.19k
  absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) {
223
2.19k
    if (!wrapped.ok()) {
224
0
      return std::move(wrapped).status();
225
0
    }
226
2.19k
    return this->operator()(std::move(wrapped).value());
227
2.19k
  }
absl::lts_20260526::StatusOr<cel::Value> cel::runtime_internal::AdaptedToValueVisitor::operator()<cel::BytesValue>(absl::lts_20260526::StatusOr<cel::BytesValue>)
Line
Count
Source
222
5.85k
  absl::StatusOr<Value> operator()(absl::StatusOr<T> wrapped) {
223
5.85k
    if (!wrapped.ok()) {
224
0
      return std::move(wrapped).status();
225
0
    }
226
5.85k
    return this->operator()(std::move(wrapped).value());
227
5.85k
  }
228
};
229
230
}  // namespace cel::runtime_internal
231
232
#endif  // THIRD_PARTY_CEL_CPP_RUNTIME_INTERNAL_FUNCTION_ADAPTER_H_