Coverage Report

Created: 2026-05-27 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/function_descriptor.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_COMMON_FUNCTION_DESCRIPTOR_H_
16
#define THIRD_PARTY_CEL_CPP_COMMON_FUNCTION_DESCRIPTOR_H_
17
18
#include <memory>
19
#include <string>
20
#include <utility>
21
#include <vector>
22
23
#include "absl/strings/string_view.h"
24
#include "absl/types/span.h"
25
#include "common/kind.h"
26
27
namespace cel {
28
29
struct FunctionDescriptorOptions {
30
  // If true (strict, default), error or unknown arguments are propagated
31
  // instead of calling the function. if false (non-strict), the function may
32
  // receive error or unknown values as arguments.
33
  bool is_strict = true;
34
35
  // Whether the function is impure or context-sensitive.
36
  //
37
  // Impure functions depend on state other than the arguments received during
38
  // the CEL expression evaluation or have visible side effects. This breaks
39
  // some of the assumptions of the CEL evaluation model. This flag is used as a
40
  // hint to the planner that some optimizations are not safe or not effective.
41
  bool is_contextual = false;
42
};
43
44
// Coarsely describes a function for the purpose of runtime resolution of
45
// overloads.
46
class FunctionDescriptor final {
47
 public:
48
  FunctionDescriptor(absl::string_view name, bool receiver_style,
49
                     std::vector<Kind> types, bool is_strict)
50
      : impl_(std::make_shared<Impl>(
51
            name, std::move(types), receiver_style,
52
            FunctionDescriptorOptions{is_strict,
53
0
                                      /*is_contextual=*/false})) {}
54
55
  FunctionDescriptor(absl::string_view name, bool receiver_style,
56
                     std::vector<Kind> types, bool is_strict,
57
                     bool is_contextual)
58
      : impl_(std::make_shared<Impl>(
59
            name, std::move(types), receiver_style,
60
0
            FunctionDescriptorOptions{is_strict, is_contextual})) {}
61
62
  FunctionDescriptor(absl::string_view name, bool is_receiver_style,
63
                     std::vector<Kind> types,
64
                     FunctionDescriptorOptions options = {})
65
2.55M
      : impl_(std::make_shared<Impl>(name, std::move(types), is_receiver_style,
66
2.55M
                                     options)) {}
67
68
  // Function name.
69
7.66M
  const std::string& name() const { return impl_->name; }
70
71
  // Whether function is receiver style i.e. true means arg0.name(args[1:]...).
72
17.8M
  bool receiver_style() const { return impl_->is_receiver_style; }
73
74
  // The argument types the function accepts.
75
  //
76
  // TODO(uncreated-issue/17): make this kinds
77
37.0M
  const std::vector<Kind>& types() const { return impl_->types; }
78
79
  // if true (strict, default), error or unknown arguments are propagated
80
  // instead of calling the function. if false (non-strict), the function may
81
  // receive error or unknown values as arguments.
82
3.89M
  bool is_strict() const { return impl_->options.is_strict; }
83
84
  // Whether the function is contextual (impure).
85
  //
86
  // Contextual functions depend on state other than the arguments received in
87
  // the CEL expression evaluation or have visible side effects. This breaks
88
  // some of the assumptions of CEL. This flag is used as a hint to the planner
89
  // that some optimizations are not safe or not effective.
90
35.3k
  bool is_contextual() const { return impl_->options.is_contextual; }
91
92
  // Helper for matching a descriptor. This tests that the shape is the same --
93
  // |other| accepts the same number and types of arguments and is the same call
94
  // style).
95
8.40M
  bool ShapeMatches(const FunctionDescriptor& other) const {
96
8.40M
    return ShapeMatches(other.receiver_style(), other.types());
97
8.40M
  }
98
  bool ShapeMatches(bool receiver_style, absl::Span<const Kind> types) const;
99
100
  bool operator==(const FunctionDescriptor& other) const;
101
102
  bool operator<(const FunctionDescriptor& other) const;
103
104
 private:
105
  struct Impl final {
106
    Impl(absl::string_view name, std::vector<Kind> types,
107
         bool is_receiver_style, FunctionDescriptorOptions options)
108
2.55M
        : name(name),
109
2.55M
          types(std::move(types)),
110
2.55M
          is_receiver_style(is_receiver_style),
111
2.55M
          options(options) {}
112
113
    std::string name;
114
    std::vector<Kind> types;
115
    bool is_receiver_style;
116
    FunctionDescriptorOptions options;
117
  };
118
119
  std::shared_ptr<const Impl> impl_;
120
};
121
122
}  // namespace cel
123
124
#endif  // THIRD_PARTY_CEL_CPP_COMMON_FUNCTION_DESCRIPTOR_H_