dev.cel.common.navigation.CelNavigableExpr Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of validators Show documentation
Show all versions of validators Show documentation
Common Expression Language Validators for Java
The newest version!
// Copyright 2023 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.navigation;
import com.google.auto.value.AutoValue;
import dev.cel.common.ast.CelExpr;
import dev.cel.common.ast.CelExpr.CelComprehension;
import dev.cel.common.ast.CelExpr.ExprKind;
import java.util.Optional;
import java.util.stream.Stream;
/**
* CelNavigableExpr represents the base navigable expression value with methods to inspect the
* parent and child expressions.
*/
@AutoValue
public abstract class CelNavigableExpr {
/**
* Specifies the traversal order of AST navigation.
*
* For call expressions, the target is visited before its arguments.
*
*
For comprehensions, the visiting order is as follows:
*
*
* - {@link CelComprehension#iterRange}
*
- {@link CelComprehension#accuInit}
*
- {@link CelComprehension#loopCondition}
*
- {@link CelComprehension#loopStep}
*
- {@link CelComprehension#result}
*
*/
public enum TraversalOrder {
PRE_ORDER,
POST_ORDER
}
public abstract CelExpr expr();
public long id() {
return expr().id();
}
public abstract Optional parent();
/** Represents the count of transitive parents. Depth of an AST's root is 0. */
public abstract int depth();
/**
* Represents the maximum count of children from any of its branches. Height of a leaf node is 0.
* For example, the height of the call node 'func' in expression `(1 + 2 + 3).func(4 + 5)` is 3.
*/
public abstract int height();
/** Constructs a new instance of {@link CelNavigableExpr} from {@link CelExpr}. */
public static CelNavigableExpr fromExpr(CelExpr expr) {
ExprHeightCalculator exprHeightCalculator = new ExprHeightCalculator(expr);
return CelNavigableExpr.builder()
.setExpr(expr)
.setHeight(exprHeightCalculator.getHeight(expr.id()))
.build();
}
/**
* Returns a stream of {@link CelNavigableExpr} collected from the current node down to the last
* leaf-level member using post-order traversal.
*/
public Stream allNodes() {
return allNodes(TraversalOrder.POST_ORDER);
}
/**
* Returns a stream of {@link CelNavigableExpr} collected from the current node down to the last
* leaf-level member using the specified traversal order.
*/
public Stream allNodes(TraversalOrder traversalOrder) {
return CelNavigableExprVisitor.collect(this, traversalOrder);
}
/**
* Returns a stream of {@link CelNavigableExpr} collected down to the last leaf-level member using
* post-order traversal.
*/
public Stream descendants() {
return descendants(TraversalOrder.POST_ORDER);
}
/**
* Returns a stream of {@link CelNavigableExpr} collected down to the last leaf-level member using
* the specified traversal order.
*/
public Stream descendants(TraversalOrder traversalOrder) {
return CelNavigableExprVisitor.collect(this, traversalOrder)
.filter(node -> node.depth() > this.depth());
}
/**
* Returns a stream of {@link CelNavigableExpr} collected from its immediate children using
* post-order traversal.
*/
public Stream children() {
return children(TraversalOrder.POST_ORDER);
}
/**
* Returns a stream of {@link CelNavigableExpr} collected from its immediate children using the
* specified traversal order.
*/
public Stream children(TraversalOrder traversalOrder) {
return CelNavigableExprVisitor.collect(this, this.depth() + 1, traversalOrder)
.filter(node -> node.depth() > this.depth());
}
/** Returns the underlying kind of the {@link CelExpr}. */
public ExprKind.Kind getKind() {
return expr().exprKind().getKind();
}
/** Create a new builder to construct a {@link CelNavigableExpr} instance. */
public static Builder builder() {
return new AutoValue_CelNavigableExpr.Builder().setDepth(0).setHeight(0);
}
/** Builder to configure {@link CelNavigableExpr}. */
@AutoValue.Builder
public abstract static class Builder {
public abstract CelExpr expr();
public abstract int depth();
public ExprKind.Kind getKind() {
return expr().exprKind().getKind();
}
public abstract Builder setExpr(CelExpr value);
abstract Builder setParent(CelNavigableExpr value);
public abstract Builder setDepth(int value);
public abstract Builder setHeight(int value);
public abstract CelNavigableExpr build();
}
public abstract Builder toBuilder();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy