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