Coverage Report

Created: 2026-05-27 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/runtime/activation.cc
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
#include "runtime/activation.h"
16
17
#include <memory>
18
#include <utility>
19
#include <vector>
20
21
#include "absl/base/macros.h"
22
#include "absl/base/nullability.h"
23
#include "absl/log/absl_check.h"
24
#include "absl/status/statusor.h"
25
#include "absl/strings/string_view.h"
26
#include "absl/synchronization/mutex.h"
27
#include "absl/types/optional.h"
28
#include "common/function_descriptor.h"
29
#include "common/value.h"
30
#include "internal/status_macros.h"
31
#include "runtime/function.h"
32
#include "runtime/function_overload_reference.h"
33
#include "google/protobuf/arena.h"
34
#include "google/protobuf/descriptor.h"
35
#include "google/protobuf/message.h"
36
37
namespace cel {
38
39
absl::StatusOr<bool> Activation::FindVariable(
40
    absl::string_view name,
41
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
42
    google::protobuf::MessageFactory* absl_nonnull message_factory,
43
0
    google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const {
44
0
  ABSL_DCHECK(descriptor_pool != nullptr);
45
0
  ABSL_DCHECK(message_factory != nullptr);
46
0
  ABSL_DCHECK(result != nullptr);
47
48
0
  auto iter = values_.find(name);
49
0
  if (iter == values_.end()) {
50
0
    return false;
51
0
  }
52
53
0
  const ValueEntry& entry = iter->second;
54
0
  if (entry.provider.has_value()) {
55
0
    return ProvideValue(name, descriptor_pool, message_factory, arena, result);
56
0
  }
57
0
  if (entry.value.has_value()) {
58
0
    *result = *entry.value;
59
0
    return true;
60
0
  }
61
0
  return false;
62
0
}
63
64
absl::StatusOr<bool> Activation::ProvideValue(
65
    absl::string_view name,
66
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
67
    google::protobuf::MessageFactory* absl_nonnull message_factory,
68
0
    google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const {
69
0
  absl::MutexLock lock(mutex_);
70
0
  auto iter = values_.find(name);
71
0
  ABSL_ASSERT(iter != values_.end());
72
0
  ValueEntry& entry = iter->second;
73
0
  if (entry.value.has_value()) {
74
0
    *result = *entry.value;
75
0
    return true;
76
0
  }
77
78
0
  CEL_ASSIGN_OR_RETURN(
79
0
      auto provided,
80
0
      (*entry.provider)(name, descriptor_pool, message_factory, arena));
81
0
  if (provided.has_value()) {
82
0
    entry.value = std::move(provided);
83
0
    *result = *entry.value;
84
0
    return true;
85
0
  }
86
0
  return false;
87
0
}
88
89
std::vector<FunctionOverloadReference> Activation::FindFunctionOverloads(
90
0
    absl::string_view name) const {
91
0
  std::vector<FunctionOverloadReference> result;
92
0
  auto iter = functions_.find(name);
93
0
  if (iter != functions_.end()) {
94
0
    const std::vector<FunctionEntry>& overloads = iter->second;
95
0
    result.reserve(overloads.size());
96
0
    for (const auto& overload : overloads) {
97
0
      result.push_back({*overload.descriptor, *overload.implementation});
98
0
    }
99
0
  }
100
0
  return result;
101
0
}
102
103
0
bool Activation::InsertOrAssignValue(absl::string_view name, Value value) {
104
0
  return values_
105
0
      .insert_or_assign(name, ValueEntry{std::move(value), absl::nullopt})
106
0
      .second;
107
0
}
108
109
bool Activation::InsertOrAssignValueProvider(absl::string_view name,
110
0
                                             ValueProvider provider) {
111
0
  return values_
112
0
      .insert_or_assign(name, ValueEntry{absl::nullopt, std::move(provider)})
113
0
      .second;
114
0
}
115
116
bool Activation::InsertFunction(const cel::FunctionDescriptor& descriptor,
117
0
                                std::unique_ptr<cel::Function> impl) {
118
0
  auto& overloads = functions_[descriptor.name()];
119
0
  for (auto& overload : overloads) {
120
0
    if (overload.descriptor->ShapeMatches(descriptor)) {
121
0
      return false;
122
0
    }
123
0
  }
124
0
  overloads.push_back(
125
0
      {std::make_unique<FunctionDescriptor>(descriptor), std::move(impl)});
126
0
  return true;
127
0
}
128
129
0
Activation::Activation(Activation&& other) {
130
0
  using std::swap;
131
0
  swap(*this, other);
132
0
}
133
134
0
Activation& Activation::operator=(Activation&& other) {
135
0
  using std::swap;
136
0
  Activation tmp(std::move(other));
137
0
  swap(*this, tmp);
138
0
  return *this;
139
0
}
140
141
}  // namespace cel