Coverage Report

Created: 2026-10-09 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/runtime/activation.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
#ifndef THIRD_PARTY_CEL_CPP_RUNTIME_ACTIVATION_H_
16
#define THIRD_PARTY_CEL_CPP_RUNTIME_ACTIVATION_H_
17
18
#include <memory>
19
#include <string>
20
#include <utility>
21
#include <vector>
22
23
#include "absl/base/nullability.h"
24
#include "absl/container/flat_hash_map.h"
25
#include "absl/functional/any_invocable.h"
26
#include "absl/status/status.h"
27
#include "absl/status/statusor.h"
28
#include "absl/strings/string_view.h"
29
#include "absl/synchronization/mutex.h"
30
#include "absl/types/optional.h"
31
#include "absl/types/span.h"
32
#include "base/attribute.h"
33
#include "common/function_descriptor.h"
34
#include "common/value.h"
35
#include "runtime/activation_interface.h"
36
#include "runtime/function.h"
37
#include "runtime/function_overload_reference.h"
38
#include "runtime/internal/attribute_matcher.h"
39
#include "google/protobuf/arena.h"
40
#include "google/protobuf/descriptor.h"
41
#include "google/protobuf/message.h"
42
43
namespace cel {
44
45
namespace runtime_internal {
46
class ActivationAttributeMatcherAccess;
47
}
48
49
// Thread-compatible implementation of a CEL Activation.
50
//
51
// Values can either be provided eagerly or via a provider.
52
class Activation final : public ActivationInterface {
53
 public:
54
  // Definition for value providers.
55
  using ValueProvider =
56
      absl::AnyInvocable<absl::StatusOr<absl::optional<Value>>(
57
          absl::string_view, const google::protobuf::DescriptorPool* absl_nonnull,
58
          google::protobuf::MessageFactory* absl_nonnull, google::protobuf::Arena* absl_nonnull)>;
59
60
0
  Activation() = default;
61
62
  // Move only.
63
  Activation(Activation&& other);
64
65
  Activation& operator=(Activation&& other);
66
67
  // Implements ActivationInterface.
68
  absl::StatusOr<bool> FindVariable(
69
      absl::string_view name,
70
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
71
      google::protobuf::MessageFactory* absl_nonnull message_factory,
72
      google::protobuf::Arena* absl_nonnull arena,
73
      Value* absl_nonnull result) const override;
74
  using ActivationInterface::FindVariable;
75
76
  std::vector<FunctionOverloadReference> FindFunctionOverloads(
77
      absl::string_view name) const override;
78
79
  absl::Span<const cel::AttributePattern> GetUnknownAttributes()
80
0
      const override {
81
0
    return unknown_patterns_;
82
0
  }
83
84
  absl::Span<const cel::AttributePattern> GetMissingAttributes()
85
0
      const override {
86
0
    return missing_patterns_;
87
0
  }
88
89
  // Bind a value to a named variable.
90
  //
91
  // Returns false if the entry for name was overwritten.
92
  bool InsertOrAssignValue(absl::string_view name, Value value);
93
94
  // Bind a provider to a named variable. The result of the provider may be
95
  // memoized by the activation.
96
  //
97
  // Returns false if the entry for name was overwritten.
98
  bool InsertOrAssignValueProvider(absl::string_view name,
99
                                   ValueProvider provider);
100
101
0
  absl::Status AddUnknownPattern(cel::AttributePattern pattern) {
102
0
    unknown_patterns_.push_back(std::move(pattern));
103
0
    return absl::OkStatus();
104
0
  }
105
106
0
  absl::Status SetUnknownPatterns(std::vector<cel::AttributePattern> patterns) {
107
0
    unknown_patterns_ = std::move(patterns);
108
0
    return absl::OkStatus();
109
0
  }
110
111
0
  absl::Status AddMissingPattern(cel::AttributePattern pattern) {
112
0
    missing_patterns_.push_back(std::move(pattern));
113
0
    return absl::OkStatus();
114
0
  }
115
116
0
  absl::Status SetMissingPatterns(std::vector<cel::AttributePattern> patterns) {
117
0
    missing_patterns_ = std::move(patterns);
118
0
    return absl::OkStatus();
119
0
  }
120
121
  // Returns true if the function was inserted (no other registered function has
122
  // a matching descriptor).
123
  bool InsertFunction(const cel::FunctionDescriptor& descriptor,
124
                      std::unique_ptr<cel::Function> impl);
125
126
 private:
127
  struct ValueEntry {
128
    // If provider is present, then access must be synchronized to maintain
129
    // thread-compatible semantics for the lazily provided value.
130
    absl::optional<Value> value;
131
    absl::optional<ValueProvider> provider;
132
  };
133
134
  struct FunctionEntry {
135
    std::unique_ptr<cel::FunctionDescriptor> descriptor;
136
    std::unique_ptr<cel::Function> implementation;
137
  };
138
139
  friend class runtime_internal::ActivationAttributeMatcherAccess;
140
141
0
  void SetAttributeMatcher(const runtime_internal::AttributeMatcher* matcher) {
142
0
    attribute_matcher_ = matcher;
143
0
  }
144
145
  void SetAttributeMatcher(
146
0
      std::unique_ptr<const runtime_internal::AttributeMatcher> matcher) {
147
0
    owned_attribute_matcher_ = std::move(matcher);
148
0
    attribute_matcher_ = owned_attribute_matcher_.get();
149
0
  }
150
151
  const runtime_internal::AttributeMatcher* absl_nullable GetAttributeMatcher()
152
0
      const override {
153
0
    return attribute_matcher_;
154
0
  }
155
156
0
  friend void swap(Activation& a, Activation& b) {
157
0
    using std::swap;
158
0
    swap(a.values_, b.values_);
159
0
    swap(a.functions_, b.functions_);
160
0
    swap(a.unknown_patterns_, b.unknown_patterns_);
161
0
    swap(a.missing_patterns_, b.missing_patterns_);
162
0
  }
163
164
  // Internal getter for provided values.
165
  // Assumes entry for name is present and is a provided value.
166
  // Handles synchronization for caching the provided value.
167
  absl::StatusOr<bool> ProvideValue(
168
      absl::string_view name,
169
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
170
      google::protobuf::MessageFactory* absl_nonnull message_factory,
171
      google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const;
172
173
  // mutex_ used for safe caching of provided variables
174
  mutable absl::Mutex mutex_;
175
  mutable absl::flat_hash_map<std::string, ValueEntry> values_;
176
177
  std::vector<cel::AttributePattern> unknown_patterns_;
178
  std::vector<cel::AttributePattern> missing_patterns_;
179
180
  const runtime_internal::AttributeMatcher* attribute_matcher_ = nullptr;
181
  std::unique_ptr<const runtime_internal::AttributeMatcher>
182
      owned_attribute_matcher_;
183
184
  absl::flat_hash_map<std::string, std::vector<FunctionEntry>> functions_;
185
};
186
187
}  // namespace cel
188
189
#endif  // THIRD_PARTY_CEL_CPP_RUNTIME_ACTIVATION_H_