All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.cel.common.ast.Expression Maven / Gradle / Ivy

The newest version!
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dev.cel.common.ast;

import dev.cel.common.annotations.Internal;
import java.util.Optional;

/**
 * An abstract representation of a common expression.
 *
 * 

Expressions are abstractly represented as a collection of identifiers, select statements, * function calls, literals, and comprehensions. All operators with the exception of the '.' * operator are modelled as function calls. This makes it easy to represent new operators into the * existing AST. * *

All references within expressions must resolve to a [Decl][] provided at type-check for an * expression to be valid. A reference may either be a bare identifier `name` or a qualified * identifier `google.api.name`. References may either refer to a value or a function declaration. * *

For example, the expression `google.api.name.startsWith('expr')` references the declaration * `google.api.name` within a [Expr.Select][] expression, and the function declaration `startsWith`. */ @Internal public interface Expression { /** * Required. An id assigned to this node by the parser which is unique in a given expression tree. * This is used to associate type information and other attributes to a node in the parse tree. */ long id(); /** Represents the enumeration value for the underlying expression kind. */ CelExpr.ExprKind.Kind getKind(); /** Gets the underlying constant expression. */ CelConstant constant(); /** Gets the underlying identifier expression. */ Ident ident(); /** Gets the underlying call expression. */ Call call(); /** Gets the underlying identifier expression. */ List list(); /** Gets the underlying select expression. */ Select select(); /** Gets the underlying struct expression. */ Struct> struct(); /** Gets the underlying map expression. */ Map> map(); /** Gets the underlying comprehension expression. */ Comprehension comprehension(); /** An identifier expression. e.g. `request`. */ interface Ident { /** * Required. Holds a single, unqualified identifier, possibly preceded by a '.'. * *

Qualified names are represented by the [Expr.Select][] expression. */ String name(); } /** A call expression, including calls to predefined functions and operators. */ interface Call { /** * The target of a method call-style expression. * *

For example, `x` in `x.f()`. */ Optional target(); /** Required. The name of the function or method being called. */ String function(); /** * Arguments to the call. * *

For example, `foo` in `f(foo)` or `x.f(foo)`. */ java.util.List args(); } /** * A list creation expression. * *

Lists may either be homogenous, e.g. `[1, 2, 3]`, or heterogeneous, e.g. `dyn([1, 'hello', * 2.0])` */ interface List { /** The elements part of the list */ java.util.List elements(); /** * The indices within the elements list which are marked as optional elements. * *

When an optional-typed value is present, the value it contains is included in the list. If * the optional-typed value is absent, the list element is omitted from the list result. */ java.util.List optionalIndices(); } /** A field selection expression. e.g. `request.auth`. */ interface Select { /** * Required. The target of the selection expression. * *

For example, in the select expression `request.auth`, the `request` portion of the * expression is the `operand`. */ E operand(); /** * Required. The name of the field to select. * *

For example, in the select expression `request.auth`, the `auth` portion of the expression * would be the `field`. */ String field(); /** * Whether the select is to be interpreted as a field presence test. * *

This results from the macro `has(request.auth)`. */ boolean testOnly(); } /** * A message creation expression. * *

Messages are constructed with a type name and composed of field ids: `types.MyType{field_id: * 'value'}`. */ interface Struct> { /** The type name of the message to be created, empty when creating map literals. */ String messageName(); /** The entries in the creation expression. */ java.util.List entries(); /** Represents an entry of the struct */ interface Entry { /** * Required. An id assigned to this node by the parser which is unique in a given expression * tree. This is used to associate type information and other attributes to the node. */ long id(); /** Entry key kind. */ String fieldKey(); /** * Required. The value assigned to the key. * *

If the optional_entry field is true, the expression must resolve to an optional-typed * value. If the optional value is present, the key will be set; however, if the optional * value is absent, the key will be unset. */ T value(); /** Whether the key-value pair is optional. */ boolean optionalEntry(); } } /** * A map creation expression. * *

Maps are constructed as `{'key_name': 'value'}`. */ interface Map> { java.util.List entries(); /** Represents an entry of the map. */ interface Entry { /** * Required. An id assigned to this node by the parser which is unique in a given expression * tree. This is used to associate type information and other attributes to the node. */ long id(); /** Required. The key. */ T key(); /** * Required. The value assigned to the key. * *

If the optional_entry field is true, the expression must resolve to an optional-typed * value. If the optional value is present, the key will be set; however, if the optional * value is absent, the key will be unset. */ T value(); boolean optionalEntry(); } } /** * A comprehension expression applied to a list or map. * *

Comprehensions are not part of the core syntax, but enabled with macros. A macro matches a * specific call signature within a parsed AST and replaces the call with an alternate AST block. * Macro expansion happens at parse time. * *

The following macros are supported within CEL: * *

Aggregate type macros may be applied to all elements in a list or all keys in a map: * *

`all`, `exists`, `exists_one` - test a predicate expression against the inputs and return * `true` if the predicate is satisfied for all, any, or only one value `list.all(x, x < 10)`. * `filter` - test a predicate expression against the inputs and return the subset of elements * which satisfy the predicate: `payments.filter(p, p > 1000)`. `map` - apply an expression to all * elements in the input and return the output aggregate type: `[1, 2, 3].map(i, i * i)`. * *

The `has(m.x)` macro tests whether the property `x` is present in struct `m`. The semantics * of this macro depend on the type of `m`. For proto2 messages `has(m.x)` is defined as 'defined, * but not set`. For proto3, the macro tests whether the property is set to its default. For map * and struct types, the macro tests whether the property `x` is defined on `m`. * *

Comprehension evaluation can be best visualized as the following pseudocode: */ interface Comprehension { /** The name of the iteration variable. */ String iterVar(); /** The range over which var iterates. */ E iterRange(); /** The name of the variable used for accumulation of the result. */ String accuVar(); /** The initial value of the accumulator. */ E accuInit(); /** * An expression which can contain iter_var and accu_var. * *

Returns false when the result has been computed and may be used as a hint to short-circuit * the remainder of the comprehension. */ E loopCondition(); /** * An expression which can contain iter_var and accu_var. * *

Computes the next value of accu_var. */ E loopStep(); /** * An expression which can contain accu_var. * *

Computes the result. */ E result(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy