1// Copyright 2018 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//     http://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
16syntax = "proto3";
17
18package google.api.expr.v1alpha1;
19
20import "google/protobuf/duration.proto";
21import "google/protobuf/struct.proto";
22import "google/protobuf/timestamp.proto";
23
24option cc_enable_arenas = true;
25option go_package = "google.golang.org/genproto/googleapis/api/expr/v1alpha1;expr";
26option java_multiple_files = true;
27option java_outer_classname = "SyntaxProto";
28option java_package = "com.google.api.expr.v1alpha1";
29
30// A representation of the abstract syntax of the Common Expression Language.
31
32// An expression together with source information as returned by the parser.
33message ParsedExpr {
34  // The parsed expression.
35  Expr expr = 2;
36
37  // The source info derived from input that generated the parsed `expr`.
38  SourceInfo source_info = 3;
39}
40
41// An abstract representation of a common expression.
42//
43// Expressions are abstractly represented as a collection of identifiers,
44// select statements, function calls, literals, and comprehensions. All
45// operators with the exception of the '.' operator are modelled as function
46// calls. This makes it easy to represent new operators into the existing AST.
47//
48// All references within expressions must resolve to a
49// [Decl][google.api.expr.v1alpha1.Decl] provided at type-check for an
50// expression to be valid. A reference may either be a bare identifier `name` or
51// a qualified identifier `google.api.name`. References may either refer to a
52// value or a function declaration.
53//
54// For example, the expression `google.api.name.startsWith('expr')` references
55// the declaration `google.api.name` within a
56// [Expr.Select][google.api.expr.v1alpha1.Expr.Select] expression, and the
57// function declaration `startsWith`.
58message Expr {
59  // An identifier expression. e.g. `request`.
60  message Ident {
61    // Required. Holds a single, unqualified identifier, possibly preceded by a
62    // '.'.
63    //
64    // Qualified names are represented by the
65    // [Expr.Select][google.api.expr.v1alpha1.Expr.Select] expression.
66    string name = 1;
67  }
68
69  // A field selection expression. e.g. `request.auth`.
70  message Select {
71    // Required. The target of the selection expression.
72    //
73    // For example, in the select expression `request.auth`, the `request`
74    // portion of the expression is the `operand`.
75    Expr operand = 1;
76
77    // Required. The name of the field to select.
78    //
79    // For example, in the select expression `request.auth`, the `auth` portion
80    // of the expression would be the `field`.
81    string field = 2;
82
83    // Whether the select is to be interpreted as a field presence test.
84    //
85    // This results from the macro `has(request.auth)`.
86    bool test_only = 3;
87  }
88
89  // A call expression, including calls to predefined functions and operators.
90  //
91  // For example, `value == 10`, `size(map_value)`.
92  message Call {
93    // The target of an method call-style expression. For example, `x` in
94    // `x.f()`.
95    Expr target = 1;
96
97    // Required. The name of the function or method being called.
98    string function = 2;
99
100    // The arguments.
101    repeated Expr args = 3;
102  }
103
104  // A list creation expression.
105  //
106  // Lists may either be homogenous, e.g. `[1, 2, 3]`, or heterogenous, e.g.
107  // `dyn([1, 'hello', 2.0])`
108  message CreateList {
109    // The elements part of the list.
110    repeated Expr elements = 1;
111  }
112
113  // A map or message creation expression.
114  //
115  // Maps are constructed as `{'key_name': 'value'}`. Message construction is
116  // similar, but prefixed with a type name and composed of field ids:
117  // `types.MyType{field_id: 'value'}`.
118  message CreateStruct {
119    // Represents an entry.
120    message Entry {
121      // Required. An id assigned to this node by the parser which is unique
122      // in a given expression tree. This is used to associate type
123      // information and other attributes to the node.
124      int64 id = 1;
125
126      // The `Entry` key kinds.
127      oneof key_kind {
128        // The field key for a message creator statement.
129        string field_key = 2;
130
131        // The key expression for a map creation statement.
132        Expr map_key = 3;
133      }
134
135      // Required. The value assigned to the key.
136      Expr value = 4;
137    }
138
139    // The type name of the message to be created, empty when creating map
140    // literals.
141    string message_name = 1;
142
143    // The entries in the creation expression.
144    repeated Entry entries = 2;
145  }
146
147  // A comprehension expression applied to a list or map.
148  //
149  // Comprehensions are not part of the core syntax, but enabled with macros.
150  // A macro matches a specific call signature within a parsed AST and replaces
151  // the call with an alternate AST block. Macro expansion happens at parse
152  // time.
153  //
154  // The following macros are supported within CEL:
155  //
156  // Aggregate type macros may be applied to all elements in a list or all keys
157  // in a map:
158  //
159  // *  `all`, `exists`, `exists_one` -  test a predicate expression against
160  //    the inputs and return `true` if the predicate is satisfied for all,
161  //    any, or only one value `list.all(x, x < 10)`.
162  // *  `filter` - test a predicate expression against the inputs and return
163  //    the subset of elements which satisfy the predicate:
164  //    `payments.filter(p, p > 1000)`.
165  // *  `map` - apply an expression to all elements in the input and return the
166  //    output aggregate type: `[1, 2, 3].map(i, i * i)`.
167  //
168  // The `has(m.x)` macro tests whether the property `x` is present in struct
169  // `m`. The semantics of this macro depend on the type of `m`. For proto2
170  // messages `has(m.x)` is defined as 'defined, but not set`. For proto3, the
171  // macro tests whether the property is set to its default. For map and struct
172  // types, the macro tests whether the property `x` is defined on `m`.
173  message Comprehension {
174    // The name of the iteration variable.
175    string iter_var = 1;
176
177    // The range over which var iterates.
178    Expr iter_range = 2;
179
180    // The name of the variable used for accumulation of the result.
181    string accu_var = 3;
182
183    // The initial value of the accumulator.
184    Expr accu_init = 4;
185
186    // An expression which can contain iter_var and accu_var.
187    //
188    // Returns false when the result has been computed and may be used as
189    // a hint to short-circuit the remainder of the comprehension.
190    Expr loop_condition = 5;
191
192    // An expression which can contain iter_var and accu_var.
193    //
194    // Computes the next value of accu_var.
195    Expr loop_step = 6;
196
197    // An expression which can contain accu_var.
198    //
199    // Computes the result.
200    Expr result = 7;
201  }
202
203  // Required. An id assigned to this node by the parser which is unique in a
204  // given expression tree. This is used to associate type information and other
205  // attributes to a node in the parse tree.
206  int64 id = 2;
207
208  // Required. Variants of expressions.
209  oneof expr_kind {
210    // A literal expression.
211    Constant const_expr = 3;
212
213    // An identifier expression.
214    Ident ident_expr = 4;
215
216    // A field selection expression, e.g. `request.auth`.
217    Select select_expr = 5;
218
219    // A call expression, including calls to predefined functions and operators.
220    Call call_expr = 6;
221
222    // A list creation expression.
223    CreateList list_expr = 7;
224
225    // A map or message creation expression.
226    CreateStruct struct_expr = 8;
227
228    // A comprehension expression.
229    Comprehension comprehension_expr = 9;
230  }
231}
232
233// Represents a primitive literal.
234//
235// Named 'Constant' here for backwards compatibility.
236//
237// This is similar as the primitives supported in the well-known type
238// `google.protobuf.Value`, but richer so it can represent CEL's full range of
239// primitives.
240//
241// Lists and structs are not included as constants as these aggregate types may
242// contain [Expr][google.api.expr.v1alpha1.Expr] elements which require
243// evaluation and are thus not constant.
244//
245// Examples of literals include: `"hello"`, `b'bytes'`, `1u`, `4.2`, `-2`,
246// `true`, `null`.
247message Constant {
248  // Required. The valid constant kinds.
249  oneof constant_kind {
250    // null value.
251    google.protobuf.NullValue null_value = 1;
252
253    // boolean value.
254    bool bool_value = 2;
255
256    // int64 value.
257    int64 int64_value = 3;
258
259    // uint64 value.
260    uint64 uint64_value = 4;
261
262    // double value.
263    double double_value = 5;
264
265    // string value.
266    string string_value = 6;
267
268    // bytes value.
269    bytes bytes_value = 7;
270
271    // protobuf.Duration value.
272    //
273    // Deprecated: duration is no longer considered a builtin cel type.
274    google.protobuf.Duration duration_value = 8 [deprecated = true];
275
276    // protobuf.Timestamp value.
277    //
278    // Deprecated: timestamp is no longer considered a builtin cel type.
279    google.protobuf.Timestamp timestamp_value = 9 [deprecated = true];
280  }
281}
282
283// Source information collected at parse time.
284message SourceInfo {
285  // The syntax version of the source, e.g. `cel1`.
286  string syntax_version = 1;
287
288  // The location name. All position information attached to an expression is
289  // relative to this location.
290  //
291  // The location could be a file, UI element, or similar. For example,
292  // `acme/app/AnvilPolicy.cel`.
293  string location = 2;
294
295  // Monotonically increasing list of character offsets where newlines appear.
296  //
297  // The line number of a given position is the index `i` where for a given
298  // `id` the `line_offsets[i] < id_positions[id] < line_offsets[i+1]`. The
299  // column may be derivd from `id_positions[id] - line_offsets[i]`.
300  repeated int32 line_offsets = 3;
301
302  // A map from the parse node id (e.g. `Expr.id`) to the character offset
303  // within source.
304  map<int64, int32> positions = 4;
305}
306
307// A specific position in source.
308message SourcePosition {
309  // The soucre location name (e.g. file name).
310  string location = 1;
311
312  // The character offset.
313  int32 offset = 2;
314
315  // The 1-based index of the starting line in the source text
316  // where the issue occurs, or 0 if unknown.
317  int32 line = 3;
318
319  // The 0-based index of the starting position within the line of source text
320  // where the issue occurs.  Only meaningful if line is nonzero.
321  int32 column = 4;
322}
323