Skip to content

Commit b412d76

Browse files
l46kokcopybara-github
authored andcommitted
Add CelMutableComprehension
PiperOrigin-RevId: 623883065
1 parent 66a3763 commit b412d76

2 files changed

Lines changed: 295 additions & 6 deletions

File tree

common/src/main/java/dev/cel/common/ast/CelMutableExpr.java

Lines changed: 163 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ public CelMutableCreateMap createMap() {
9393
return (CelMutableCreateMap) exprValue;
9494
}
9595

96+
public CelMutableComprehension comprehension() {
97+
checkExprKind(Kind.COMPREHENSION);
98+
return (CelMutableComprehension) exprValue;
99+
}
100+
96101
public void setConstant(CelConstant constant) {
97102
this.exprKind = ExprKind.Kind.CONSTANT;
98103
this.exprValue = checkNotNull(constant);
@@ -128,6 +133,11 @@ public void setCreateMap(CelMutableCreateMap createMap) {
128133
this.exprValue = checkNotNull(createMap);
129134
}
130135

136+
public void setComprehension(CelMutableComprehension comprehension) {
137+
this.exprKind = ExprKind.Kind.COMPREHENSION;
138+
this.exprValue = checkNotNull(comprehension);
139+
}
140+
131141
/** A mutable identifier expression. */
132142
public static final class CelMutableIdent {
133143
private String name = "";
@@ -698,6 +708,147 @@ private CelMutableCreateMap(List<CelMutableCreateMap.Entry> entries) {
698708
}
699709
}
700710

711+
/** A mutable comprehension expression applied to a list or map. */
712+
public static final class CelMutableComprehension {
713+
714+
private String iterVar;
715+
716+
private CelMutableExpr iterRange;
717+
718+
private String accuVar;
719+
720+
private CelMutableExpr accuInit;
721+
722+
private CelMutableExpr loopCondition;
723+
724+
private CelMutableExpr loopStep;
725+
726+
private CelMutableExpr result;
727+
728+
public String iterVar() {
729+
return iterVar;
730+
}
731+
732+
public void setIterVar(String iterVar) {
733+
this.iterVar = checkNotNull(iterVar);
734+
}
735+
736+
public CelMutableExpr iterRange() {
737+
return iterRange;
738+
}
739+
740+
public void setIterRange(CelMutableExpr iterRange) {
741+
this.iterRange = checkNotNull(iterRange);
742+
}
743+
744+
public String accuVar() {
745+
return accuVar;
746+
}
747+
748+
public void setAccuVar(String accuVar) {
749+
this.accuVar = checkNotNull(accuVar);
750+
}
751+
752+
public CelMutableExpr accuInit() {
753+
return accuInit;
754+
}
755+
756+
public void setAccuInit(CelMutableExpr accuInit) {
757+
this.accuInit = checkNotNull(accuInit);
758+
}
759+
760+
public CelMutableExpr loopCondition() {
761+
return loopCondition;
762+
}
763+
764+
public void setLoopCondition(CelMutableExpr loopCondition) {
765+
this.loopCondition = checkNotNull(loopCondition);
766+
}
767+
768+
public CelMutableExpr loopStep() {
769+
return loopStep;
770+
}
771+
772+
public void setLoopStep(CelMutableExpr loopStep) {
773+
this.loopStep = checkNotNull(loopStep);
774+
}
775+
776+
public CelMutableExpr result() {
777+
return result;
778+
}
779+
780+
public void setResult(CelMutableExpr result) {
781+
this.result = checkNotNull(result);
782+
}
783+
784+
@Override
785+
public boolean equals(Object obj) {
786+
if (obj == this) {
787+
return true;
788+
}
789+
if (obj instanceof CelMutableComprehension) {
790+
CelMutableComprehension that = (CelMutableComprehension) obj;
791+
return this.iterVar.equals(that.iterVar())
792+
&& this.accuVar.equals(that.accuVar())
793+
&& this.iterRange.equals(that.iterRange())
794+
&& this.accuInit.equals(that.accuInit())
795+
&& this.loopCondition.equals(that.loopCondition())
796+
&& this.loopStep.equals(that.loopStep())
797+
&& this.result.equals(that.result());
798+
}
799+
return false;
800+
}
801+
802+
@Override
803+
public int hashCode() {
804+
int h = 1;
805+
h *= 1000003;
806+
h ^= iterVar.hashCode();
807+
h *= 1000003;
808+
h ^= iterRange.hashCode();
809+
h *= 1000003;
810+
h ^= accuVar.hashCode();
811+
h *= 1000003;
812+
h ^= accuInit.hashCode();
813+
h *= 1000003;
814+
h ^= loopCondition.hashCode();
815+
h *= 1000003;
816+
h ^= loopStep.hashCode();
817+
h *= 1000003;
818+
h ^= result.hashCode();
819+
return h;
820+
}
821+
822+
public static CelMutableComprehension create(
823+
String iterVar,
824+
CelMutableExpr iterRange,
825+
String accuVar,
826+
CelMutableExpr accuInit,
827+
CelMutableExpr loopCondition,
828+
CelMutableExpr loopStep,
829+
CelMutableExpr result) {
830+
return new CelMutableComprehension(
831+
iterVar, iterRange, accuVar, accuInit, loopCondition, loopStep, result);
832+
}
833+
834+
private CelMutableComprehension(
835+
String iterVar,
836+
CelMutableExpr iterRange,
837+
String accuVar,
838+
CelMutableExpr accuInit,
839+
CelMutableExpr loopCondition,
840+
CelMutableExpr loopStep,
841+
CelMutableExpr result) {
842+
this.iterVar = checkNotNull(iterVar);
843+
this.iterRange = checkNotNull(iterRange);
844+
this.accuVar = checkNotNull(accuVar);
845+
this.accuInit = checkNotNull(accuInit);
846+
this.loopCondition = checkNotNull(loopCondition);
847+
this.loopStep = checkNotNull(loopStep);
848+
this.result = checkNotNull(result);
849+
}
850+
}
851+
701852
public static CelMutableExpr ofNotSet() {
702853
return ofNotSet(0L);
703854
}
@@ -762,6 +913,11 @@ public static CelMutableExpr ofCreateMap(long id, CelMutableCreateMap mutableCre
762913
return new CelMutableExpr(id, mutableCreateMap);
763914
}
764915

916+
public static CelMutableExpr ofComprehension(
917+
long id, CelMutableComprehension mutableComprehension) {
918+
return new CelMutableExpr(id, mutableComprehension);
919+
}
920+
765921
private CelMutableExpr(long id, CelConstant mutableConstant) {
766922
this.id = id;
767923
setConstant(mutableConstant);
@@ -797,6 +953,11 @@ private CelMutableExpr(long id, CelMutableCreateMap mutableCreateMap) {
797953
setCreateMap(mutableCreateMap);
798954
}
799955

956+
private CelMutableExpr(long id, CelMutableComprehension mutableComprehension) {
957+
this.id = id;
958+
setComprehension(mutableComprehension);
959+
}
960+
800961
private CelMutableExpr(long id) {
801962
this();
802963
this.id = id;
@@ -826,7 +987,7 @@ private Object exprValue() {
826987
case CREATE_MAP:
827988
return createMap();
828989
case COMPREHENSION:
829-
// fall-through (not implemented yet)
990+
return comprehension();
830991
}
831992

832993
throw new IllegalStateException("Unexpected expr kind: " + this.exprKind);
@@ -846,10 +1007,7 @@ public boolean equals(Object obj) {
8461007
if (this.id != that.id() || !this.exprKind.equals(that.getKind())) {
8471008
return false;
8481009
}
849-
// When both objects' hashes are cached and they do not match, they can never be equal.
850-
if (this.hash != 0 && that.hash != 0 && this.hash != that.hash) {
851-
return false;
852-
}
1010+
8531011
return this.exprValue().equals(that.exprValue());
8541012
}
8551013

common/src/test/java/dev/cel/common/ast/CelMutableExprTest.java

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
2424
import dev.cel.common.ast.CelExpr.ExprKind.Kind;
2525
import dev.cel.common.ast.CelMutableExpr.CelMutableCall;
26+
import dev.cel.common.ast.CelMutableExpr.CelMutableComprehension;
2627
import dev.cel.common.ast.CelMutableExpr.CelMutableCreateList;
2728
import dev.cel.common.ast.CelMutableExpr.CelMutableCreateMap;
2829
import dev.cel.common.ast.CelMutableExpr.CelMutableCreateStruct;
@@ -449,6 +450,73 @@ public void mutableCreateMapEntry_setters() {
449450
true));
450451
}
451452

453+
@Test
454+
public void ofComprehension_withId() {
455+
CelMutableExpr mutableExpr =
456+
CelMutableExpr.ofComprehension(
457+
10L,
458+
CelMutableComprehension.create(
459+
"iterVar",
460+
CelMutableExpr.ofCreateList(
461+
CelMutableCreateList.create(
462+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)))),
463+
"accuVar",
464+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
465+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
466+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
467+
CelMutableExpr.ofIdent("__result__")));
468+
469+
assertThat(mutableExpr.id()).isEqualTo(10L);
470+
assertThat(mutableExpr.comprehension())
471+
.isEqualTo(
472+
CelMutableComprehension.create(
473+
"iterVar",
474+
CelMutableExpr.ofCreateList(
475+
CelMutableCreateList.create(
476+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)))),
477+
"accuVar",
478+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
479+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
480+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
481+
CelMutableExpr.ofIdent("__result__")));
482+
}
483+
484+
@Test
485+
public void mutableComprehension_setters() {
486+
CelMutableComprehension mutableComprehension =
487+
CelMutableComprehension.create(
488+
"iterVar",
489+
CelMutableExpr.ofNotSet(),
490+
"accuVar",
491+
CelMutableExpr.ofNotSet(),
492+
CelMutableExpr.ofNotSet(),
493+
CelMutableExpr.ofNotSet(),
494+
CelMutableExpr.ofNotSet());
495+
496+
mutableComprehension.setIterVar("iterVar2");
497+
mutableComprehension.setAccuVar("accuVar2");
498+
mutableComprehension.setIterRange(
499+
CelMutableExpr.ofCreateList(
500+
CelMutableCreateList.create(CelMutableExpr.ofConstant(CelConstant.ofValue(true)))));
501+
mutableComprehension.setAccuInit(CelMutableExpr.ofConstant(CelConstant.ofValue(true)));
502+
mutableComprehension.setLoopCondition(CelMutableExpr.ofConstant(CelConstant.ofValue(true)));
503+
mutableComprehension.setLoopStep(CelMutableExpr.ofConstant(CelConstant.ofValue(true)));
504+
mutableComprehension.setResult(CelMutableExpr.ofIdent("__result__"));
505+
506+
assertThat(mutableComprehension)
507+
.isEqualTo(
508+
CelMutableComprehension.create(
509+
"iterVar2",
510+
CelMutableExpr.ofCreateList(
511+
CelMutableCreateList.create(
512+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)))),
513+
"accuVar2",
514+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
515+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
516+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
517+
CelMutableExpr.ofIdent("__result__")));
518+
}
519+
452520
@Test
453521
public void equalityTest() {
454522
new EqualsTester()
@@ -534,6 +602,42 @@ public void equalityTest() {
534602
CelMutableExpr.ofConstant(CelConstant.ofValue("key")),
535603
CelMutableExpr.ofConstant(CelConstant.ofValue("value")),
536604
/* optionalEntry= */ true))))
605+
.addEqualityGroup(
606+
CelMutableExpr.ofComprehension(
607+
10L,
608+
CelMutableComprehension.create(
609+
"iterVar",
610+
CelMutableExpr.ofNotSet(),
611+
"accuVar",
612+
CelMutableExpr.ofNotSet(),
613+
CelMutableExpr.ofNotSet(),
614+
CelMutableExpr.ofNotSet(),
615+
CelMutableExpr.ofNotSet())))
616+
.addEqualityGroup(
617+
CelMutableExpr.ofComprehension(
618+
11L,
619+
CelMutableComprehension.create(
620+
"iterVar",
621+
CelMutableExpr.ofCreateList(
622+
CelMutableCreateList.create(
623+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)))),
624+
"accuVar",
625+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
626+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
627+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
628+
CelMutableExpr.ofIdent("__result__"))),
629+
CelMutableExpr.ofComprehension(
630+
11L,
631+
CelMutableComprehension.create(
632+
"iterVar",
633+
CelMutableExpr.ofCreateList(
634+
CelMutableCreateList.create(
635+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)))),
636+
"accuVar",
637+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
638+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
639+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
640+
CelMutableExpr.ofIdent("__result__"))))
537641
.testEquals();
538642
}
539643

@@ -549,6 +653,17 @@ private enum MutableExprKindTestCase {
549653
CelMutableExpr.ofCreateStruct(
550654
CelMutableCreateStruct.create("message", ImmutableList.of()))),
551655
CREATE_MAP(CelMutableExpr.ofCreateMap(CelMutableCreateMap.create(ImmutableList.of()))),
656+
COMPREHENSION(
657+
CelMutableExpr.ofComprehension(
658+
10L,
659+
CelMutableComprehension.create(
660+
"iterVar",
661+
CelMutableExpr.ofNotSet(),
662+
"accuVar",
663+
CelMutableExpr.ofNotSet(),
664+
CelMutableExpr.ofNotSet(),
665+
CelMutableExpr.ofNotSet(),
666+
CelMutableExpr.ofNotSet()))),
552667
;
553668

554669
private final CelMutableExpr mutableExpr;
@@ -585,6 +700,9 @@ public void getExprValue_invalidKind_throws(@TestParameter MutableExprKindTestCa
585700
if (!testCaseKind.equals(Kind.CREATE_MAP)) {
586701
assertThrows(IllegalArgumentException.class, testCase.mutableExpr::createMap);
587702
}
703+
if (!testCaseKind.equals(Kind.COMPREHENSION)) {
704+
assertThrows(IllegalArgumentException.class, testCase.mutableExpr::comprehension);
705+
}
588706
}
589707

590708
@SuppressWarnings("Immutable") // Mutable by design
@@ -635,7 +753,20 @@ private enum HashCodeTestCase {
635753
CelMutableExpr.ofConstant(CelConstant.ofValue("value")),
636754
/* optionalEntry= */ true)))),
637755
1260717292),
638-
;
756+
COMPREHENSION(
757+
CelMutableExpr.ofComprehension(
758+
10L,
759+
CelMutableComprehension.create(
760+
"iterVar",
761+
CelMutableExpr.ofCreateList(
762+
CelMutableCreateList.create(
763+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)))),
764+
"accuVar",
765+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
766+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
767+
CelMutableExpr.ofConstant(CelConstant.ofValue(true)),
768+
CelMutableExpr.ofIdent("__result__"))),
769+
-1006359408);
639770

640771
private final CelMutableExpr mutableExpr;
641772
private final int expectedHashCode;

0 commit comments

Comments
 (0)