use of com.google.api.expr.v1alpha1.Decl in project cel-java by projectnessie.
the class CheckerEnv method addFunction.
/**
* addFunction adds the function Decl to the Env. Adds a function decl if one doesn't already
* exist, then adds all overloads from the Decl. If overload overlaps with an existing overload,
* adds to the errors in the Env instead.
*/
void addFunction(Decl decl, List<String> errMsgs) {
Decl current = declarations.findFunction(decl.getName());
if (current == null) {
// Add the function declaration without overloads and check the overloads below.
current = Decls.newFunction(decl.getName(), Collections.emptyList());
declarations.addFunction(current);
}
for (Overload overload : decl.getFunction().getOverloadsList()) {
current = addOverload(current, overload, errMsgs);
}
declarations.updateFunction(decl.getName(), current);
}
use of com.google.api.expr.v1alpha1.Decl in project cel-java by projectnessie.
the class Env method extend.
/**
* Extend the current environment with additional options to produce a new Env.
*
* <p>Note, the extended Env value should not share memory with the original. It is possible,
* however, that a CustomTypeAdapter or CustomTypeProvider options could provide values which are
* mutable. To ensure separation of state between extended environments either make sure the
* TypeAdapter and TypeProvider are immutable, or that their underlying implementations are based
* on the ref.TypeRegistry which provides a Copy method which will be invoked by this method.
*/
public Env extend(List<EnvOption> opts) {
if (chkErr != null) {
throw chkErr;
}
// Copy slices.
List<Decl> decsCopy = new ArrayList<>(declarations);
List<Macro> macsCopy = new ArrayList<>(macros);
List<ProgramOption> progOptsCopy = new ArrayList<>(progOpts);
// Copy the adapter / provider if they appear to be mutable.
TypeAdapter adapter = this.adapter;
TypeProvider provider = this.provider;
// TypeRegistry as the base implementation are captured below.
if (this.adapter instanceof TypeRegistry && this.provider instanceof TypeRegistry) {
TypeRegistry adapterReg = (TypeRegistry) this.adapter;
TypeRegistry providerReg = (TypeRegistry) this.provider;
TypeRegistry reg = providerReg.copy();
provider = reg;
// to the same ref.TypeRegistry as the provider.
if (adapterReg.equals(providerReg)) {
adapter = reg;
} else {
// Otherwise, make a copy of the adapter.
adapter = adapterReg.copy();
}
} else if (this.provider instanceof TypeRegistry) {
provider = ((TypeRegistry) this.provider).copy();
} else if (this.adapter instanceof TypeRegistry) {
adapter = ((TypeRegistry) this.adapter).copy();
}
Set<EnvFeature> featuresCopy = EnumSet.copyOf(this.features);
Env ext = new Env(this.container, decsCopy, macsCopy, adapter, provider, featuresCopy, progOptsCopy);
return ext.configure(opts);
}
use of com.google.api.expr.v1alpha1.Decl 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.Decl in project cel-java by projectnessie.
the class Checker method checkCall.
void checkCall(Expr.Builder e) {
// Note: similar logic exists within the `interpreter/planner.go`. If making changes here
// please consider the impact on planner.go and consolidate implementations or mirror code
// as appropriate.
Call.Builder call = e.getCallExprBuilder();
List<Expr.Builder> args = call.getArgsBuilderList();
String fnName = call.getFunction();
// Traverse arguments.
for (Expr.Builder arg : args) {
check(arg);
}
// Regular static call with simple name.
if (call.getTarget() == Expr.getDefaultInstance()) {
// Check for the existence of the function.
Decl fn = env.lookupFunction(fnName);
if (fn == null) {
errors.undeclaredReference(location(e), env.container.name(), fnName);
setType(e, Decls.Error);
return;
}
// Overwrite the function name with its fully qualified resolved name.
call.setFunction(fn.getName());
// Check to see whether the overload resolves.
resolveOverloadOrError(location(e), e, fn, null, args);
return;
}
// If a receiver 'target' is present, it may either be a receiver function, or a namespaced
// function, but not both. Given a.b.c() either a.b.c is a function or c is a function with
// target a.b.
//
// Check whether the target is a namespaced function name.
Expr.Builder target = call.getTargetBuilder();
String qualifiedPrefix = Container.toQualifiedName(target.build());
if (qualifiedPrefix != null) {
String maybeQualifiedName = qualifiedPrefix + "." + fnName;
Decl fn = env.lookupFunction(maybeQualifiedName);
if (fn != null) {
// The function name is namespaced and so preserving the target operand would
// be an inaccurate representation of the desired evaluation behavior.
// Overwrite with fully-qualified resolved function name sans receiver target.
call.clearTarget().setFunction(fn.getName());
resolveOverloadOrError(location(e), e, fn, null, args);
return;
}
}
// Regular instance call.
check(target);
// Overwrite with fully-qualified resolved function name sans receiver target.
Decl fn = env.lookupFunction(fnName);
// Function found, attempt overload resolution.
if (fn != null) {
resolveOverloadOrError(location(e), e, fn, target, args);
return;
}
// Function name not declared, record error.
errors.undeclaredReference(location(e), env.container.name(), fnName);
}
use of com.google.api.expr.v1alpha1.Decl in project cel-java by projectnessie.
the class Checker method checkIdent.
void checkIdent(Expr.Builder e) {
Ident.Builder identExpr = e.getIdentExprBuilder();
// Check to see if the identifier is declared.
Decl ident = env.lookupIdent(identExpr.getName());
if (ident != null) {
setType(e, ident.getIdent().getType());
setReference(e, newIdentReference(ident.getName(), ident.getIdent().getValue()));
// Overwrite the identifier with its fully qualified name.
identExpr.setName(ident.getName());
return;
}
setType(e, Decls.Error);
errors.undeclaredReference(location(e), env.container.name(), identExpr.getName());
}
Aggregations