Coverage Report

Created: 2026-05-27 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/eval/public/cel_function_registry.h
Line
Count
Source
1
#ifndef THIRD_PARTY_CEL_CPP_EVAL_PUBLIC_CEL_FUNCTION_REGISTRY_H_
2
#define THIRD_PARTY_CEL_CPP_EVAL_PUBLIC_CEL_FUNCTION_REGISTRY_H_
3
4
#include <initializer_list>
5
#include <memory>
6
#include <string>
7
#include <utility>
8
#include <vector>
9
10
#include "absl/base/thread_annotations.h"
11
#include "absl/container/flat_hash_map.h"
12
#include "absl/container/node_hash_map.h"
13
#include "absl/status/status.h"
14
#include "absl/strings/string_view.h"
15
#include "absl/synchronization/mutex.h"
16
#include "common/function_descriptor.h"
17
#include "common/kind.h"
18
#include "eval/public/cel_function.h"
19
#include "eval/public/cel_options.h"
20
#include "eval/public/cel_value.h"
21
#include "runtime/function.h"
22
#include "runtime/function_overload_reference.h"
23
#include "runtime/function_registry.h"
24
25
namespace google::api::expr::runtime {
26
27
// CelFunctionRegistry class allows to register builtin or custom
28
// CelFunction handlers with it and look them up when creating
29
// CelExpression objects from Expr ASTs.
30
class CelFunctionRegistry {
31
 public:
32
  // Represents a single overload for a lazily provided function.
33
  using LazyOverload = cel::FunctionRegistry::LazyOverload;
34
35
14.5k
  CelFunctionRegistry() = default;
36
37
14.5k
  ~CelFunctionRegistry() = default;
38
39
  using Registrar = absl::Status (*)(CelFunctionRegistry*,
40
                                     const InterpreterOptions&);
41
42
  // Register CelFunction object. Object ownership is
43
  // passed to registry.
44
  // Function registration should be performed prior to
45
  // CelExpression creation.
46
0
  absl::Status Register(std::unique_ptr<CelFunction> function) {
47
0
    // We need to copy the descriptor, otherwise there is no guarantee that the
48
0
    // lvalue reference to the descriptor is valid as function may be destroyed.
49
0
    auto descriptor = function->descriptor();
50
0
    return Register(descriptor, std::move(function));
51
0
  }
52
53
  absl::Status Register(const cel::FunctionDescriptor& descriptor,
54
0
                        std::unique_ptr<cel::Function> implementation) {
55
0
    return modern_registry_.Register(descriptor, std::move(implementation));
56
0
  }
57
58
  absl::Status RegisterAll(std::initializer_list<Registrar> registrars,
59
                           const InterpreterOptions& opts);
60
61
  // Register a lazily provided function. This overload uses a default provider
62
  // that delegates to the activation at evaluation time.
63
0
  absl::Status RegisterLazyFunction(const CelFunctionDescriptor& descriptor) {
64
0
    return modern_registry_.RegisterLazyFunction(descriptor);
65
0
  }
66
67
  // Find a subset of CelFunction that match overload conditions
68
  // As types may not be available during expression compilation,
69
  // further narrowing of this subset will happen at evaluation stage.
70
  // name - the name of CelFunction;
71
  // receiver_style - indicates whether function has receiver style;
72
  // types - argument types. If  type is not known during compilation,
73
  // DYN value should be passed.
74
  //
75
  // Results refer to underlying registry entries by pointer. Results are
76
  // invalid after the registry is deleted.
77
  std::vector<const CelFunction*> FindOverloads(
78
      absl::string_view name, bool receiver_style,
79
      const std::vector<CelValue::Type>& types) const;
80
81
  std::vector<cel::FunctionOverloadReference> FindStaticOverloads(
82
      absl::string_view name, bool receiver_style,
83
0
      const std::vector<cel::Kind>& types) const {
84
0
    return modern_registry_.FindStaticOverloads(name, receiver_style, types);
85
0
  }
86
87
  // Find subset of CelFunction providers that match overload conditions
88
  // As types may not be available during expression compilation,
89
  // further narrowing of this subset will happen at evaluation stage.
90
  // name - the name of CelFunction;
91
  // receiver_style - indicates whether function has receiver style;
92
  // types - argument types. If  type is not known during compilation,
93
  // DYN value should be passed.
94
  std::vector<const CelFunctionDescriptor*> FindLazyOverloads(
95
      absl::string_view name, bool receiver_style,
96
      const std::vector<CelValue::Type>& types) const;
97
98
  // Find subset of CelFunction providers that match overload conditions
99
  // As types may not be available during expression compilation,
100
  // further narrowing of this subset will happen at evaluation stage.
101
  // name - the name of CelFunction;
102
  // receiver_style - indicates whether function has receiver style;
103
  // types - argument types. If  type is not known during compilation,
104
  // DYN value should be passed.
105
  std::vector<LazyOverload> ModernFindLazyOverloads(
106
      absl::string_view name, bool receiver_style,
107
0
      const std::vector<CelValue::Type>& types) const {
108
0
    return modern_registry_.FindLazyOverloads(name, receiver_style, types);
109
0
  }
110
111
  // Retrieve list of registered function descriptors. This includes both
112
  // static and lazy functions.
113
  absl::node_hash_map<std::string, std::vector<const cel::FunctionDescriptor*>>
114
0
  ListFunctions() const {
115
0
    return modern_registry_.ListFunctions();
116
0
  }
117
118
  // cel internal accessor for returning backing modern registry.
119
  //
120
  // This is intended to allow migrating the CEL evaluator internals while
121
  // maintaining the existing CelRegistry API.
122
  //
123
  // CEL users should not use this.
124
0
  const cel::FunctionRegistry& InternalGetRegistry() const {
125
0
    return modern_registry_;
126
0
  }
127
128
29.0k
  cel::FunctionRegistry& InternalGetRegistry() { return modern_registry_; }
129
130
 private:
131
  cel::FunctionRegistry modern_registry_;
132
133
  // Maintain backwards compatibility for callers expecting CelFunction
134
  // interface.
135
  // This is not used internally, but some client tests check that a specific
136
  // CelFunction overload is used.
137
  // Lazily initialized.
138
  mutable absl::Mutex mu_;
139
  mutable absl::flat_hash_map<const cel::Function*,
140
                              std::unique_ptr<CelFunction>>
141
      functions_ ABSL_GUARDED_BY(mu_);
142
};
143
144
}  // namespace google::api::expr::runtime
145
146
#endif  // THIRD_PARTY_CEL_CPP_EVAL_PUBLIC_CEL_FUNCTION_REGISTRY_H_