Search in sources :

Example 1 with FunctionDecl

use of com.google.api.expr.v1alpha1.Decl.FunctionDecl in project cel-java by projectnessie.

the class CheckerEnv method sanitizeFunction.

// sanitizeFunction replaces well-known types referenced by message name with their equivalent
// CEL built-in type instances.
Decl sanitizeFunction(Decl decl) {
    FunctionDecl fn = decl.getFunction();
    // Determine whether the declaration requires replacements from proto-based message type
    // references to well-known CEL type references.
    boolean needsSanitizing = false;
    for (Overload o : fn.getOverloadsList()) {
        if (isObjectWellKnownType(o.getResultType())) {
            needsSanitizing = true;
            break;
        }
        for (Type p : o.getParamsList()) {
            if (isObjectWellKnownType(p)) {
                needsSanitizing = true;
                break;
            }
        }
    }
    // Early return if the declaration requires no modification.
    if (!needsSanitizing) {
        return decl;
    }
    // Sanitize all of the overloads if any overload requires an update to its type references.
    List<Overload> overloads = new ArrayList<>(fn.getOverloadsCount());
    for (Overload o : fn.getOverloadsList()) {
        boolean sanitized = false;
        Type rt = o.getResultType();
        if (isObjectWellKnownType(rt)) {
            rt = getObjectWellKnownType(rt);
            sanitized = true;
        }
        List<Type> params = new ArrayList<>(o.getParamsCount());
        for (Type p : o.getParamsList()) {
            if (isObjectWellKnownType(p)) {
                params.add(getObjectWellKnownType(p));
                sanitized = true;
            } else {
                params.add(p);
            }
        }
        // If sanitized, replace the overload definition.
        Overload ov;
        if (sanitized) {
            if (o.getIsInstanceFunction()) {
                ov = Decls.newInstanceOverload(o.getOverloadId(), params, rt);
            } else {
                ov = Decls.newOverload(o.getOverloadId(), params, rt);
            }
        } else {
            // Otherwise, preserve the original overload.
            ov = o;
        }
        overloads.add(ov);
    }
    return Decls.newFunction(decl.getName(), overloads);
}
Also used : Types.formatCheckedType(org.projectnessie.cel.checker.Types.formatCheckedType) Type(com.google.api.expr.v1alpha1.Type) ErrType(org.projectnessie.cel.common.types.Err.ErrType) Overload(com.google.api.expr.v1alpha1.Decl.FunctionDecl.Overload) ArrayList(java.util.ArrayList) FunctionDecl(com.google.api.expr.v1alpha1.Decl.FunctionDecl)

Example 2 with FunctionDecl

use of com.google.api.expr.v1alpha1.Decl.FunctionDecl in project cel-java by projectnessie.

the class CheckerEnv method addOverload.

/**
 * addOverload adds overload to function declaration f. Returns one or more errorMsg values if the
 * overload overlaps with an existing overload or macro.
 */
Decl addOverload(Decl f, Overload overload, List<String> errMsgs) {
    FunctionDecl function = f.getFunction();
    Mapping emptyMappings = newMapping();
    Type overloadFunction = Decls.newFunctionType(overload.getResultType(), overload.getParamsList());
    Type overloadErased = substitute(emptyMappings, overloadFunction, true);
    boolean hasErr = false;
    for (Overload existing : function.getOverloadsList()) {
        Type existingFunction = Decls.newFunctionType(existing.getResultType(), existing.getParamsList());
        Type existingErased = substitute(emptyMappings, existingFunction, true);
        boolean overlap = isAssignable(emptyMappings, overloadErased, existingErased) != null || isAssignable(emptyMappings, existingErased, overloadErased) != null;
        if (overlap && overload.getIsInstanceFunction() == existing.getIsInstanceFunction()) {
            errMsgs.add(overlappingOverloadError(f.getName(), overload.getOverloadId(), overloadFunction, existing.getOverloadId(), existingFunction));
            hasErr = true;
        }
    }
    for (Macro macro : Macro.AllMacros) {
        if (macro.function().equals(f.getName()) && macro.isReceiverStyle() == overload.getIsInstanceFunction() && macro.argCount() == overload.getParamsCount()) {
            errMsgs.add(overlappingMacroError(f.getName(), macro.argCount()));
            hasErr = true;
        }
    }
    if (hasErr) {
        return f;
    }
    function = function.toBuilder().addOverloads(overload).build();
    f = f.toBuilder().setFunction(function).build();
    return f;
}
Also used : Types.formatCheckedType(org.projectnessie.cel.checker.Types.formatCheckedType) Type(com.google.api.expr.v1alpha1.Type) ErrType(org.projectnessie.cel.common.types.Err.ErrType) Overload(com.google.api.expr.v1alpha1.Decl.FunctionDecl.Overload) Macro(org.projectnessie.cel.parser.Macro) Mapping.newMapping(org.projectnessie.cel.checker.Mapping.newMapping) FunctionDecl(com.google.api.expr.v1alpha1.Decl.FunctionDecl)

Aggregations

FunctionDecl (com.google.api.expr.v1alpha1.Decl.FunctionDecl)2 Overload (com.google.api.expr.v1alpha1.Decl.FunctionDecl.Overload)2 Type (com.google.api.expr.v1alpha1.Type)2 Types.formatCheckedType (org.projectnessie.cel.checker.Types.formatCheckedType)2 ErrType (org.projectnessie.cel.common.types.Err.ErrType)2 ArrayList (java.util.ArrayList)1 Mapping.newMapping (org.projectnessie.cel.checker.Mapping.newMapping)1 Macro (org.projectnessie.cel.parser.Macro)1