Search in sources :

Example 6 with Val

use of org.projectnessie.cel.common.types.ref.Val in project cel-java by projectnessie.

the class AstPruner method maybePruneConditional.

Expr maybePruneConditional(Expr node) {
    if (!existsWithUnknownValue(node.getId())) {
        return null;
    }
    Call call = node.getCallExpr();
    Val condVal = value(call.getArgs(0).getId());
    if (condVal == null || isUnknownOrError(condVal)) {
        return null;
    }
    if (condVal == True) {
        return call.getArgs(1);
    }
    return call.getArgs(2);
}
Also used : Val(org.projectnessie.cel.common.types.ref.Val) Call(com.google.api.expr.v1alpha1.Expr.Call)

Example 7 with Val

use of org.projectnessie.cel.common.types.ref.Val in project cel-java by projectnessie.

the class AstPruner method prune.

Expr prune(Expr node) {
    if (node == null) {
        return null;
    }
    Val val = value(node.getId());
    if (val != null && !isUnknownOrError(val)) {
        Expr newNode = maybeCreateLiteral(node.getId(), val);
        if (newNode != null) {
            return newNode;
        }
    }
    switch(node.getExprKindCase()) {
        case SELECT_EXPR:
            Select select = node.getSelectExpr();
            Expr operand = prune(select.getOperand());
            if (operand != null && operand != select.getOperand()) {
                return Expr.newBuilder().setId(node.getId()).setSelectExpr(Select.newBuilder().setOperand(operand).setField(select.getField()).setTestOnly(select.getTestOnly())).build();
            }
            break;
        case CALL_EXPR:
            Call call = node.getCallExpr();
            Expr newExpr = maybePruneFunction(node);
            if (newExpr != null) {
                newExpr = prune(newExpr);
                return newExpr;
            }
            boolean prunedCall = false;
            List<Expr> args = call.getArgsList();
            List<Expr> newArgs = new ArrayList<>(args.size());
            for (int i = 0; i < args.size(); i++) {
                Expr arg = args.get(i);
                newArgs.add(arg);
                Expr newArg = prune(arg);
                if (newArg != null && newArg != arg) {
                    prunedCall = true;
                    newArgs.set(i, newArg);
                }
            }
            Call newCall = Call.newBuilder().setFunction(call.getFunction()).setTarget(call.getTarget()).addAllArgs(newArgs).build();
            Expr newTarget = prune(call.getTarget());
            if (newTarget != null && newTarget != call.getTarget()) {
                prunedCall = true;
                newCall = Call.newBuilder().setFunction(call.getFunction()).setTarget(newTarget).addAllArgs(newArgs).build();
            }
            if (prunedCall) {
                return Expr.newBuilder().setId(node.getId()).setCallExpr(newCall).build();
            }
            break;
        case LIST_EXPR:
            CreateList list = node.getListExpr();
            List<Expr> elems = list.getElementsList();
            List<Expr> newElems = new ArrayList<>(elems.size());
            boolean prunedList = false;
            for (int i = 0; i < elems.size(); i++) {
                Expr elem = elems.get(i);
                newElems.add(elem);
                Expr newElem = prune(elem);
                if (newElem != null && newElem != elem) {
                    newElems.set(i, newElem);
                    prunedList = true;
                }
            }
            if (prunedList) {
                return Expr.newBuilder().setId(node.getId()).setListExpr(CreateList.newBuilder().addAllElements(newElems)).build();
            }
            break;
        case STRUCT_EXPR:
            boolean prunedStruct = false;
            CreateStruct struct = node.getStructExpr();
            List<Entry> entries = struct.getEntriesList();
            String messageType = struct.getMessageName();
            List<Entry> newEntries = new ArrayList<>(entries.size());
            for (int i = 0; i < entries.size(); i++) {
                Entry entry = entries.get(i);
                newEntries.add(entry);
                Expr mapKey = entry.getMapKey();
                Expr newKey = mapKey != Entry.getDefaultInstance().getMapKey() ? prune(mapKey) : null;
                Expr newValue = prune(entry.getValue());
                if ((newKey == null || newKey == mapKey) && (newValue == null || newValue == entry.getValue())) {
                    continue;
                }
                prunedStruct = true;
                Entry newEntry;
                if (!messageType.isEmpty()) {
                    newEntry = Entry.newBuilder().setFieldKey(entry.getFieldKey()).setValue(newValue).build();
                } else {
                    newEntry = Entry.newBuilder().setMapKey(newKey).setValue(newValue).build();
                }
                newEntries.set(i, newEntry);
            }
            if (prunedStruct) {
                return Expr.newBuilder().setId(node.getId()).setStructExpr(CreateStruct.newBuilder().setMessageName(messageType).addAllEntries(entries)).build();
            }
            break;
        case COMPREHENSION_EXPR:
            Comprehension compre = node.getComprehensionExpr();
            // Only the range of the comprehension is pruned since the state tracking only records
            // the last iteration of the comprehension and not each step in the evaluation which
            // means that the any residuals computed in between might be inaccurate.
            Expr newRange = prune(compre.getIterRange());
            if (newRange != null && newRange != compre.getIterRange()) {
                return Expr.newBuilder().setId(node.getId()).setComprehensionExpr(Comprehension.newBuilder().setIterVar(compre.getIterVar()).setIterRange(newRange).setAccuVar(compre.getAccuVar()).setAccuInit(compre.getAccuInit()).setLoopCondition(compre.getLoopCondition()).setLoopStep(compre.getLoopStep()).setResult(compre.getResult())).build();
            }
    }
    // allocation cost at another point. So go with the simple approach - at least for now.
    return node;
}
Also used : Val(org.projectnessie.cel.common.types.ref.Val) Call(com.google.api.expr.v1alpha1.Expr.Call) CreateStruct(com.google.api.expr.v1alpha1.Expr.CreateStruct) ArrayList(java.util.ArrayList) ByteString(com.google.protobuf.ByteString) Comprehension(com.google.api.expr.v1alpha1.Expr.Comprehension) CreateList(com.google.api.expr.v1alpha1.Expr.CreateList) Entry(com.google.api.expr.v1alpha1.Expr.CreateStruct.Entry) Expr(com.google.api.expr.v1alpha1.Expr) Select(com.google.api.expr.v1alpha1.Expr.Select)

Example 8 with Val

use of org.projectnessie.cel.common.types.ref.Val in project cel-java by projectnessie.

the class Util method deepEquals.

@SuppressWarnings("rawtypes")
public static void deepEquals(String context, Object a, Object b) {
    if (a == null && b == null) {
        return;
    }
    if (a == null) {
        fail(String.format("deepEquals(%s), a==null, b!=null", context));
    }
    if (b == null) {
        fail(String.format("deepEquals(%s), a!=null, b==null", context));
    }
    if (!a.getClass().isAssignableFrom(b.getClass())) {
        if (a instanceof Val && !(b instanceof Val)) {
            deepEquals(context, ((Val) a).value(), b);
            return;
        }
        if (!(a instanceof Val) && b instanceof Val) {
            deepEquals(context, a, ((Val) b).value());
            return;
        }
        fail(String.format("deepEquals(%s), a.class(%s) is not assignable from b.class(%s)", context, a.getClass().getName(), b.getClass().getName()));
    }
    if (a.getClass().isArray()) {
        int al = Array.getLength(a);
        int bl = Array.getLength(b);
        if (al != bl) {
            fail(String.format("deepEquals(%s), %s.length(%d) != %s.length(%d)", context, a.getClass().getName(), al, b.getClass().getName(), bl));
        }
        for (int i = 0; i < al; i++) {
            Object av = Array.get(a, i);
            Object bv = Array.get(b, i);
            deepEquals(context + '[' + i + ']', av, bv);
        }
    } else if (a instanceof List) {
        List al = (List) a;
        List bl = (List) b;
        int as = al.size();
        int bs = bl.size();
        if (as != bs) {
            fail(String.format("deepEquals(%s), %s.size(%d) != %s.size(%d)", context, a.getClass().getName(), as, b.getClass().getName(), bs));
        }
        for (int i = 0; i < as; i++) {
            deepEquals(context + '[' + i + ']', al.get(i), bl.get(i));
        }
    } else if (a instanceof Map) {
        Map am = (Map) a;
        Map bm = (Map) b;
        int as = am.size();
        int bs = bm.size();
        if (as != bs) {
            fail(String.format("deepEquals(%s), %s.size(%d) != %s.size(%d)", context, a.getClass().getName(), as, b.getClass().getName(), bs));
        }
        for (Object ak : am.keySet()) {
            Object av = am.get(ak);
            if (!bm.containsKey(ak)) {
                boolean f = true;
                if (ak instanceof Val) {
                    Object an = ((Val) ak).value();
                    if (bm.containsKey(an)) {
                        ak = an;
                        f = false;
                    }
                } else {
                    Val aval = DefaultTypeAdapter.Instance.nativeToValue(ak);
                    if (bm.containsKey(aval)) {
                        ak = aval;
                        f = false;
                    }
                }
                if (f) {
                    fail(String.format("deepEquals(%s), %s(%s) contains %s, but %s(%s) does not", context, a.getClass().getName(), as, ak, b.getClass().getName(), bs));
                }
            }
            Object bv = bm.get(ak);
            deepEquals(context + '[' + ak + ']', av, bv);
        }
    } else if (!a.equals(b)) {
        fail(String.format("deepEquals(%s), %s(%s) != %s(%s)", context, a.getClass().getName(), a, b.getClass().getName(), b));
    }
}
Also used : Val(org.projectnessie.cel.common.types.ref.Val) List(java.util.List) Map(java.util.Map) HashMap(java.util.HashMap)

Example 9 with Val

use of org.projectnessie.cel.common.types.ref.Val in project cel-java by projectnessie.

the class DurationTest method durationGetHours.

@Test
void durationGetHours() {
    DurationT d = durationOf(ofSeconds(7506, 0));
    Val hr = d.receive(Overloads.TimeGetHours, Overloads.DurationToHours);
    assertThat(hr.equal(intOf(2))).isSameAs(True);
}
Also used : Val(org.projectnessie.cel.common.types.ref.Val) Test(org.junit.jupiter.api.Test)

Example 10 with Val

use of org.projectnessie.cel.common.types.ref.Val in project cel-java by projectnessie.

the class DurationTest method durationGetMinutes.

@Test
void durationGetMinutes() {
    DurationT d = durationOf(ofSeconds(7506, 0));
    Val min = d.receive(Overloads.TimeGetMinutes, Overloads.DurationToMinutes);
    assertThat(min.equal(intOf(125))).isSameAs(True);
}
Also used : Val(org.projectnessie.cel.common.types.ref.Val) Test(org.junit.jupiter.api.Test)

Aggregations

Val (org.projectnessie.cel.common.types.ref.Val)67 Test (org.junit.jupiter.api.Test)42 TypeRegistry (org.projectnessie.cel.common.types.ref.TypeRegistry)22 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)16 ByteString (com.google.protobuf.ByteString)10 ParsedExpr (com.google.api.expr.v1alpha1.ParsedExpr)9 MethodSource (org.junit.jupiter.params.provider.MethodSource)9 Message (com.google.protobuf.Message)8 Err (org.projectnessie.cel.common.types.Err)8 ObjectT (org.projectnessie.cel.common.types.ObjectT)7 Activation.emptyActivation (org.projectnessie.cel.interpreter.Activation.emptyActivation)7 Expr (com.google.api.expr.v1alpha1.Expr)6 Source (org.projectnessie.cel.common.Source)6 Mapper (org.projectnessie.cel.common.types.traits.Mapper)6 HashMap (java.util.HashMap)5 EvalResult (org.projectnessie.cel.Program.EvalResult)5 True (org.projectnessie.cel.common.types.BoolT.True)5 StringT.stringOf (org.projectnessie.cel.common.types.StringT.stringOf)5 ProtoTypeRegistry (org.projectnessie.cel.common.types.pb.ProtoTypeRegistry)5 Call (com.google.api.expr.v1alpha1.Expr.Call)4