use of com.google.api.expr.v1alpha1.Type in project cel-java by projectnessie.
the class CEL method initInterpretable.
/**
* initIterpretable creates a checked or unchecked interpretable depending on whether the Ast has
* been run through the type-checker.
*/
private static Program initInterpretable(Prog p, Ast ast, List<InterpretableDecorator> decorators) {
InterpretableDecorator[] decs = decorators.toArray(new InterpretableDecorator[0]);
// slower to execute than their checked counterparts.
if (!ast.isChecked()) {
p.interpretable = p.interpreter.newUncheckedInterpretable(ast.getExpr(), decs);
return p;
}
// When the AST has been checked it contains metadata that can be used to speed up program
// execution.
CheckedExpr checked = astToCheckedExpr(ast);
p.interpretable = p.interpreter.newInterpretable(checked, decs);
return p;
}
use of com.google.api.expr.v1alpha1.Type in project cel-java by projectnessie.
the class CEL method newProgram.
/**
* newProgram creates a program instance with an environment, an ast, and an optional list of
* ProgramOption values.
*
* <p>If the program cannot be configured the prog will be nil, with a non-nil error response.
*/
public static Program newProgram(Env e, Ast ast, ProgramOption... opts) {
// Build the dispatcher, interpreter, and default program value.
Dispatcher disp = newDispatcher();
// Ensure the default attribute factory is set after the adapter and provider are
// configured.
Prog p = new Prog(e, disp);
// Configure the program via the ProgramOption values.
for (ProgramOption opt : opts) {
if (opt == null) {
throw new NullPointerException("program options should be non-nil");
}
p = opt.apply(p);
if (p == null) {
throw new NullPointerException(String.format("program option of type '%s' returned null", opt.getClass().getName()));
}
}
// Set the attribute factory after the options have been set.
if (p.evalOpts.contains(EvalOption.OptPartialEval)) {
p.attrFactory = newPartialAttributeFactory(e.getContainer(), e.getTypeAdapter(), e.getTypeProvider());
} else {
p.attrFactory = newAttributeFactory(e.getContainer(), e.getTypeAdapter(), e.getTypeProvider());
}
Interpreter interp = newInterpreter(disp, e.getContainer(), e.getTypeProvider(), e.getTypeAdapter(), p.attrFactory);
p.interpreter = interp;
// Translate the EvalOption flags into InterpretableDecorator instances.
List<InterpretableDecorator> decorators = new ArrayList<>(p.decorators);
// Enable constant folding first.
if (p.evalOpts.contains(EvalOption.OptOptimize)) {
decorators.add(optimize());
}
Prog pp = p;
// Enable exhaustive eval over state tracking since it offers a superset of features.
if (p.evalOpts.contains(EvalOption.OptExhaustiveEval)) {
// State tracking requires that each Eval() call operate on an isolated EvalState
// object; hence, the presence of the factory.
ProgFactory factory = state -> {
List<InterpretableDecorator> decs = new ArrayList<>(decorators);
decs.add(exhaustiveEval(state));
Prog clone = new Prog(e, pp.evalOpts, pp.defaultVars, disp, interp, state);
return initInterpretable(clone, ast, decs);
};
return initProgGen(factory);
} else if (p.evalOpts.contains(EvalOption.OptTrackState)) {
// Enable state tracking last since it too requires the factory approach but is less
// featured than the ExhaustiveEval decorator.
ProgFactory factory = state -> {
List<InterpretableDecorator> decs = new ArrayList<>(decorators);
decs.add(trackState(state));
Prog clone = new Prog(e, pp.evalOpts, pp.defaultVars, disp, interp, state);
return initInterpretable(clone, ast, decs);
};
return initProgGen(factory);
}
return initInterpretable(p, ast, decorators);
}
use of com.google.api.expr.v1alpha1.Type in project cel-java by projectnessie.
the class Env method check.
/**
* Check performs type-checking on the input Ast and yields a checked Ast and/or set of Issues.
*
* <p>Checking has failed if the returned Issues value and its Issues.Err() value are non-nil.
* Issues should be inspected if they are non-nil, but may not represent a fatal error.
*
* <p>It is possible to have both non-nil Ast and Issues values returned from this call: however,
* the mere presence of an Ast does not imply that it is valid for use.
*/
public AstIssuesTuple check(Ast ast) {
// Note, errors aren't currently possible on the Ast to ParsedExpr conversion.
ParsedExpr pe = astToParsedExpr(ast);
// Construct the internal checker env, erroring if there is an issue adding the declarations.
synchronized (once) {
if (chk == null && chkErr == null) {
CheckerEnv ce = CheckerEnv.newCheckerEnv(container, provider);
ce.enableDynamicAggregateLiterals(true);
if (hasFeature(FeatureDisableDynamicAggregateLiterals)) {
ce.enableDynamicAggregateLiterals(false);
}
try {
ce.add(declarations);
chk = ce;
} catch (RuntimeException e) {
chkErr = e;
} catch (Exception e) {
chkErr = new RuntimeException(e);
}
}
}
// The once call will ensure that this value is set or nil for all invocations.
if (chkErr != null) {
Errors errs = new Errors(ast.getSource());
errs.reportError(NoLocation, "%s", chkErr.toString());
return new AstIssuesTuple(null, newIssues(errs));
}
ParseResult pr = new ParseResult(pe.getExpr(), new Errors(ast.getSource()), pe.getSourceInfo());
CheckResult checkRes = Checker.Check(pr, ast.getSource(), chk);
if (checkRes.hasErrors()) {
return new AstIssuesTuple(null, newIssues(checkRes.getErrors()));
}
// Manually create the Ast to ensure that the Ast source information (which may be more
// detailed than the information provided by Check), is returned to the caller.
CheckedExpr ce = checkRes.getCheckedExpr();
ast = new Ast(ce.getExpr(), ce.getSourceInfo(), ast.getSource(), ce.getReferenceMapMap(), ce.getTypeMapMap());
return new AstIssuesTuple(ast, Issues.noIssues(ast.getSource()));
}
use of com.google.api.expr.v1alpha1.Type in project cel-java by projectnessie.
the class Checker method checkCreateMessage.
void checkCreateMessage(Expr.Builder e) {
CreateStruct.Builder msgVal = e.getStructExprBuilder();
// Determine the type of the message.
Type messageType = Decls.Error;
Decl decl = env.lookupIdent(msgVal.getMessageName());
if (decl == null) {
errors.undeclaredReference(location(e), env.container.name(), msgVal.getMessageName());
return;
}
// Ensure the type name is fully qualified in the AST.
msgVal.setMessageName(decl.getName());
setReference(e, newIdentReference(decl.getName(), null));
IdentDecl ident = decl.getIdent();
Types.Kind identKind = kindOf(ident.getType());
if (identKind != Kind.kindError) {
if (identKind != Kind.kindType) {
errors.notAType(location(e), ident.getType());
} else {
messageType = ident.getType().getType();
if (kindOf(messageType) != Kind.kindObject) {
errors.notAMessageType(location(e), messageType);
messageType = Decls.Error;
}
}
}
if (isObjectWellKnownType(messageType)) {
setType(e, getObjectWellKnownType(messageType));
} else {
setType(e, messageType);
}
// Check the field initializers.
for (Entry.Builder ent : msgVal.getEntriesBuilderList()) {
String field = ent.getFieldKey();
Expr.Builder value = ent.getValueBuilder();
check(value);
Type fieldType = Decls.Error;
FieldType t = lookupFieldType(locationByID(ent.getId()), messageType.getMessageType(), field);
if (t != null) {
fieldType = t.type;
}
if (!isAssignable(fieldType, getType(value))) {
errors.fieldTypeMismatch(locationByID(ent.getId()), field, fieldType, getType(value));
}
}
}
use of com.google.api.expr.v1alpha1.Type in project cel-java by projectnessie.
the class CheckerEnv method sanitizeIdent.
/**
* sanitizeIdent replaces the identifier's well-known types referenced by message name with
* references to CEL built-in type instances.
*/
Decl sanitizeIdent(Decl decl) {
IdentDecl id = decl.getIdent();
Type t = id.getType();
if (!isObjectWellKnownType(t)) {
return decl;
}
return Decls.newIdent(decl.getName(), getObjectWellKnownType(t), id.getValue());
}
Aggregations