Search in sources :

Example 6 with Decl

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);
}
Also used : Overload(com.google.api.expr.v1alpha1.Decl.FunctionDecl.Overload) FunctionDecl(com.google.api.expr.v1alpha1.Decl.FunctionDecl) Decl(com.google.api.expr.v1alpha1.Decl) IdentDecl(com.google.api.expr.v1alpha1.Decl.IdentDecl)

Example 7 with Decl

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);
}
Also used : Macro(org.projectnessie.cel.parser.Macro) ArrayList(java.util.ArrayList) TypeProvider(org.projectnessie.cel.common.types.ref.TypeProvider) Decl(com.google.api.expr.v1alpha1.Decl) CheckerEnv(org.projectnessie.cel.checker.CheckerEnv) TypeRegistry(org.projectnessie.cel.common.types.ref.TypeRegistry) EnvFeature(org.projectnessie.cel.EnvOption.EnvFeature) TypeAdapter(org.projectnessie.cel.common.types.ref.TypeAdapter)

Example 8 with Decl

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));
        }
    }
}
Also used : CreateStruct(com.google.api.expr.v1alpha1.Expr.CreateStruct) IdentDecl(com.google.api.expr.v1alpha1.Decl.IdentDecl) Decl(com.google.api.expr.v1alpha1.Decl) FieldType(org.projectnessie.cel.common.types.ref.FieldType) CheckerEnv.getObjectWellKnownType(org.projectnessie.cel.checker.CheckerEnv.getObjectWellKnownType) CheckerEnv.isObjectWellKnownType(org.projectnessie.cel.checker.CheckerEnv.isObjectWellKnownType) CheckerEnv.dynElementType(org.projectnessie.cel.checker.CheckerEnv.dynElementType) Type(com.google.api.expr.v1alpha1.Type) MapType(com.google.api.expr.v1alpha1.Type.MapType) FieldType(org.projectnessie.cel.common.types.ref.FieldType) Entry(com.google.api.expr.v1alpha1.Expr.CreateStruct.Entry) Expr(com.google.api.expr.v1alpha1.Expr) CheckedExpr(com.google.api.expr.v1alpha1.CheckedExpr) Kind(org.projectnessie.cel.checker.Types.Kind) IdentDecl(com.google.api.expr.v1alpha1.Decl.IdentDecl)

Example 9 with Decl

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);
}
Also used : Call(com.google.api.expr.v1alpha1.Expr.Call) Expr(com.google.api.expr.v1alpha1.Expr) CheckedExpr(com.google.api.expr.v1alpha1.CheckedExpr) IdentDecl(com.google.api.expr.v1alpha1.Decl.IdentDecl) Decl(com.google.api.expr.v1alpha1.Decl)

Example 10 with Decl

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());
}
Also used : Ident(com.google.api.expr.v1alpha1.Expr.Ident) IdentDecl(com.google.api.expr.v1alpha1.Decl.IdentDecl) Decl(com.google.api.expr.v1alpha1.Decl)

Aggregations

Decl (com.google.api.expr.v1alpha1.Decl)10 Type (com.google.api.expr.v1alpha1.Type)9 IdentDecl (com.google.api.expr.v1alpha1.Decl.IdentDecl)8 FunctionDecl (com.google.api.expr.v1alpha1.Decl.FunctionDecl)5 Types.formatCheckedType (org.projectnessie.cel.checker.Types.formatCheckedType)5 Overload (com.google.api.expr.v1alpha1.Decl.FunctionDecl.Overload)4 ArrayList (java.util.ArrayList)4 ErrType (org.projectnessie.cel.common.types.Err.ErrType)4 CheckedExpr (com.google.api.expr.v1alpha1.CheckedExpr)3 Expr (com.google.api.expr.v1alpha1.Expr)3 MapType (com.google.api.expr.v1alpha1.Type.MapType)3 CheckerEnv.dynElementType (org.projectnessie.cel.checker.CheckerEnv.dynElementType)3 CheckerEnv.getObjectWellKnownType (org.projectnessie.cel.checker.CheckerEnv.getObjectWellKnownType)3 CheckerEnv.isObjectWellKnownType (org.projectnessie.cel.checker.CheckerEnv.isObjectWellKnownType)3 FieldType (org.projectnessie.cel.common.types.ref.FieldType)3 Mapping.newMapping (org.projectnessie.cel.checker.Mapping.newMapping)2 TypeRegistry (org.projectnessie.cel.common.types.ref.TypeRegistry)2 Macro (org.projectnessie.cel.parser.Macro)2 Call (com.google.api.expr.v1alpha1.Expr.Call)1 CreateStruct (com.google.api.expr.v1alpha1.Expr.CreateStruct)1