syntax.proto 11 KB

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