Coverage Report

Created: 2023-05-25 06:18

/proc/self/cwd/parser/macro.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2021 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_PARSER_MACRO_H_
16
#define THIRD_PARTY_CEL_CPP_PARSER_MACRO_H_
17
18
#include <cstddef>
19
#include <cstdint>
20
#include <functional>
21
#include <memory>
22
#include <string>
23
#include <utility>
24
25
#include "google/api/expr/v1alpha1/syntax.pb.h"
26
#include "absl/base/attributes.h"
27
#include "absl/status/statusor.h"
28
#include "absl/strings/str_cat.h"
29
#include "absl/strings/string_view.h"
30
31
namespace google::api::expr::parser {
32
class SourceFactory;
33
}
34
35
namespace cel {
36
37
using SourceFactory = google::api::expr::parser::SourceFactory;
38
39
// MacroExpander converts the target and args of a function call that matches a
40
// Macro.
41
//
42
// Note: when the Macros.IsReceiverStyle() is true, the target argument will
43
// be Expr::default_instance().
44
using MacroExpander = std::function<google::api::expr::v1alpha1::Expr(
45
    const std::shared_ptr<SourceFactory>& sf, int64_t macro_id,
46
    const google::api::expr::v1alpha1::Expr&,
47
    // This should be absl::Span instead of std::vector.
48
    const std::vector<google::api::expr::v1alpha1::Expr>&)>;
49
50
// Macro interface for describing the function signature to match and the
51
// MacroExpander to apply.
52
//
53
// Note: when a Macro should apply to multiple overloads (based on arg count) of
54
// a given function, a Macro should be created per arg-count.
55
class Macro final {
56
 public:
57
  static absl::StatusOr<Macro> Global(absl::string_view name,
58
                                      size_t argument_count,
59
                                      MacroExpander expander);
60
61
  static absl::StatusOr<Macro> GlobalVarArg(absl::string_view name,
62
                                            MacroExpander expander);
63
64
  static absl::StatusOr<Macro> Receiver(absl::string_view name,
65
                                        size_t argument_count,
66
                                        MacroExpander expander);
67
68
  static absl::StatusOr<Macro> ReceiverVarArg(absl::string_view name,
69
                                              MacroExpander expander);
70
71
  // Create a Macro for a global function with the specified number of arguments
72
  ABSL_DEPRECATED("Use static factory methods instead.")
73
  Macro(absl::string_view function, size_t arg_count, MacroExpander expander,
74
        bool receiver_style = false)
75
      : key_(absl::StrCat(function, ":", arg_count, ":",
76
                          receiver_style ? "true" : "false")),
77
        arg_count_(arg_count),
78
        expander_(std::make_shared<MacroExpander>(std::move(expander))),
79
        receiver_style_(receiver_style),
80
67.3k
        var_arg_style_(false) {}
81
82
  ABSL_DEPRECATED("Use static factory methods instead.")
83
  Macro(absl::string_view function, MacroExpander expander,
84
        bool receiver_style = false)
85
      : key_(absl::StrCat(function, ":*:", receiver_style ? "true" : "false")),
86
        arg_count_(0),
87
        expander_(std::make_shared<MacroExpander>(std::move(expander))),
88
        receiver_style_(receiver_style),
89
0
        var_arg_style_(true) {}
90
91
  // Function name to match.
92
0
  absl::string_view function() const { return key().substr(0, key_.find(':')); }
93
94
  // argument_count() for the function call.
95
  //
96
  // When the macro is a var-arg style macro, the return value will be zero, but
97
  // the MacroKey will contain a `*` where the arg count would have been.
98
0
  size_t argument_count() const { return arg_count_; }
99
100
  // is_receiver_style returns true if the macro matches a receiver style call.
101
0
  bool is_receiver_style() const { return receiver_style_; }
102
103
0
  bool is_variadic() const { return var_arg_style_; }
104
105
  // key() returns the macro signatures accepted by this macro.
106
  //
107
  // Format: `<function>:<arg-count>:<is-receiver>`.
108
  //
109
  // When the macros is a var-arg style macro, the `arg-count` value is
110
  // represented as a `*`.
111
64.5k
  absl::string_view key() const { return key_; }
112
113
  // Expander returns the MacroExpander to apply when the macro key matches the
114
  // parsed call signature.
115
5.42k
  const MacroExpander& expander() const { return *expander_; }
116
117
  google::api::expr::v1alpha1::Expr Expand(
118
      const std::shared_ptr<SourceFactory>& sf, int64_t macro_id,
119
      const google::api::expr::v1alpha1::Expr& target,
120
5.42k
      const std::vector<google::api::expr::v1alpha1::Expr>& args) const {
121
5.42k
    return (expander())(sf, macro_id, target, args);
122
5.42k
  }
123
124
  static std::vector<Macro> AllMacros();
125
126
 private:
127
  std::string key_;
128
  size_t arg_count_;
129
  std::shared_ptr<MacroExpander> expander_;
130
  bool receiver_style_;
131
  bool var_arg_style_;
132
};
133
134
}  // namespace cel
135
136
namespace google {
137
namespace api {
138
namespace expr {
139
namespace parser {
140
141
using MacroExpander = cel::MacroExpander;
142
143
using Macro = cel::Macro;
144
145
}  // namespace parser
146
}  // namespace expr
147
}  // namespace api
148
}  // namespace google
149
150
#endif  // THIRD_PARTY_CEL_CPP_PARSER_MACRO_H_