use of com.google.api.expr.v1alpha1.Expr in project cel-java by projectnessie.
the class CEL method astToString.
/**
* AstToString converts an Ast back to a string if possible.
*
* <p>Note, the conversion may not be an exact replica of the original expression, but will
* produce a string that is semantically equivalent and whose textual representation is stable.
*/
public static String astToString(Ast a) {
Expr expr = a.getExpr();
SourceInfo info = a.getSourceInfo();
return unparse(expr, info);
}
use of com.google.api.expr.v1alpha1.Expr in project cel-java by projectnessie.
the class Env method residualAst.
/**
* ResidualAst takes an Ast and its EvalDetails to produce a new Ast which only contains the
* attribute references which are unknown.
*
* <p>Residual expressions are beneficial in a few scenarios:
*
* <ul>
* <li>Optimizing constant expression evaluations away.
* <li>Indexing and pruning expressions based on known input arguments.
* <li>Surfacing additional requirements that are needed in order to complete an evaluation.
* <li>Sharing the evaluation of an expression across multiple machines/nodes.
* </ul>
*
* <p>For example, if an expression targets a 'resource' and 'request' attribute and the possible
* values for the resource are known, a PartialActivation could mark the 'request' as an unknown
* interpreter.AttributePattern and the resulting ResidualAst would be reduced to only the parts
* of the expression that reference the 'request'.
*
* <p>Note, the expression ids within the residual AST generated through this method have no
* correlation to the expression ids of the original AST.
*
* <p>See the PartialVars helper for how to construct a PartialActivation.
*
* <p>TODO: Consider adding an option to generate a Program.Residual to avoid round-tripping to an
* Ast format and then Program again.
*/
public Ast residualAst(Ast a, EvalDetails details) {
Expr pruned = pruneAst(a.getExpr(), details.getState());
String expr = astToString(parsedExprToAst(ParsedExpr.newBuilder().setExpr(pruned).build()));
AstIssuesTuple parsedIss = parse(expr);
if (parsedIss.hasIssues()) {
throw parsedIss.getIssues().err();
}
if (!a.isChecked()) {
return parsedIss.ast;
}
AstIssuesTuple checkedIss = check(parsedIss.ast);
if (checkedIss.hasIssues()) {
throw checkedIss.getIssues().err();
}
return checkedIss.ast;
}
use of com.google.api.expr.v1alpha1.Expr in project cel-java by projectnessie.
the class Container method toQualifiedName.
/**
* ToQualifiedName converts an expression AST into a qualified name if possible, with a boolean +
* 'found' value that indicates if the conversion is successful.
*/
public static String toQualifiedName(Expr e) {
switch(e.getExprKindCase()) {
case IDENT_EXPR:
return e.getIdentExpr().getName();
case SELECT_EXPR:
Select sel = e.getSelectExpr();
if (sel.getTestOnly()) {
return null;
}
String qual = toQualifiedName(sel.getOperand());
if (qual != null) {
return qual + "." + sel.getField();
}
break;
}
return null;
}
use of com.google.api.expr.v1alpha1.Expr in project cel-java by projectnessie.
the class CELTest method Abbrevs_Disambiguation.
@Test
void Abbrevs_Disambiguation() {
Env env = newEnv(abbrevs("external.Expr"), container("google.api.expr.v1alpha1"), types(Expr.getDefaultInstance()), declarations(Decls.newVar("test", Decls.Bool), Decls.newVar("external.Expr", Decls.String)));
// This expression will return either a string or a protobuf Expr value depending on the value
// of the 'test' argument. The fully qualified type name is used indicate that the protobuf
// typed 'Expr' should be used rather than the abbreviatation for 'external.Expr'.
AstIssuesTuple astIss = env.compile("test ? dyn(Expr) : google.api.expr.v1alpha1.Expr{id: 1}");
assertThat(astIss.hasIssues()).isFalse();
Program prg = env.program(astIss.getAst());
EvalResult out = prg.eval(mapOf("test", true, "external.Expr", "string expr"));
assertThat(out.getVal().value()).isEqualTo("string expr");
out = prg.eval(mapOf("test", false, "external.Expr", "wrong expr"));
Expr want = Expr.newBuilder().setId(1).build();
Expr got = out.getVal().convertToNative(Expr.class);
assertThat(got).isEqualTo(want);
}
use of com.google.api.expr.v1alpha1.Expr in project cel-java by projectnessie.
the class CELTest method ParseAndCheckConcurrently.
@SuppressWarnings("rawtypes")
@Test
void ParseAndCheckConcurrently() throws Exception {
Env e = newEnv(container("google.api.expr.v1alpha1"), types(Expr.getDefaultInstance()), declarations(Decls.newVar("expr", Decls.newObjectType("google.api.expr.v1alpha1.Expr"))));
Consumer<String> parseAndCheck = expr -> {
AstIssuesTuple xIss = e.compile(expr);
assertThat(xIss.hasIssues()).isFalse();
};
int concurrency = 10;
ExecutorService executor = Executors.newFixedThreadPool(concurrency);
try {
CompletableFuture[] futures = IntStream.range(0, concurrency).mapToObj(i -> CompletableFuture.runAsync(() -> parseAndCheck.accept(String.format("expr.id + %d", i)), executor)).toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futures).get(30, TimeUnit.SECONDS);
} finally {
executor.shutdown();
assertThat(executor.awaitTermination(30, TimeUnit.SECONDS)).isTrue();
}
}
Aggregations