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);
}
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;
}
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));
}
}
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);
}
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);
}
Aggregations