Skip to content

Commit

Permalink
Add shorthands for retrieving CelExpr variants or its default instance.
Browse files Browse the repository at this point in the history
This is useful to avoid having to check for the underlying kind before accessing its properties.

Example:

expr.getKind().equals(Kind.CALL) && expr.call().function().equals("foo")

We can instead write:

expr.callOrDefault().function().equals("foo")

PiperOrigin-RevId: 559821213
  • Loading branch information
l46kok authored and copybara-github committed Aug 24, 2023
1 parent 5567748 commit 1fa54c9
Show file tree
Hide file tree
Showing 8 changed files with 282 additions and 4 deletions.
18 changes: 18 additions & 0 deletions common/src/main/java/dev/cel/common/ast/CelConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package dev.cel.common.ast;

import com.google.auto.value.AutoOneOf;
import com.google.auto.value.AutoValue;
import com.google.common.primitives.UnsignedLong;
import com.google.errorprone.annotations.Immutable;
import com.google.protobuf.ByteString;
Expand All @@ -34,6 +35,7 @@
public abstract class CelConstant {
/** Represents the type of the Constant */
public enum Kind {
NOT_SET,
NULL_VALUE,
BOOLEAN_VALUE,
INT64_VALUE,
Expand All @@ -55,6 +57,18 @@ public enum Kind {

public abstract Kind getKind();

/**
* An unset constant.
*
* <p>As the name implies, this constant does nothing. This is used to represent a default
* instance of CelConstant.
*/
@AutoValue
@Immutable
public abstract static class CelConstantNotSet {}

public abstract CelConstantNotSet notSet();

public abstract NullValue nullValue();

public abstract boolean booleanValue();
Expand All @@ -81,6 +95,10 @@ public enum Kind {
@Deprecated
public abstract Duration durationValue();

public static CelConstant ofNotSet() {
return AutoOneOf_CelConstant.notSet(new AutoValue_CelConstant_CelConstantNotSet());
}

public static CelConstant ofValue(NullValue value) {
return AutoOneOf_CelConstant.nullValue(value);
}
Expand Down
144 changes: 140 additions & 4 deletions common/src/main/java/dev/cel/common/ast/CelExpr.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.errorprone.annotations.Immutable;
import dev.cel.common.annotations.Internal;
import dev.cel.common.ast.CelExpr.ExprKind.Kind;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -50,42 +51,167 @@
@Immutable
public abstract class CelExpr {

/**
* Required. An id assigned to this node by the parser which is unique in a given expression tree.
* This is used to associate type information and other attributes to a node in the parse tree.
*/
public abstract long id();

/** Represents the variant of the expression. */
public abstract ExprKind exprKind();

/**
* Gets the underlying constant expression.
*
* @throws UnsupportedOperationException if expression is not {@link Kind#CONSTANT}.
*/
public CelConstant constant() {
return exprKind().constant();
}

/**
* Gets the underlying identifier expression.
*
* @throws UnsupportedOperationException if expression is not {@link Kind#IDENT}.
*/
public CelIdent ident() {
return exprKind().ident();
}

/**
* Gets the underlying select expression.
*
* @throws UnsupportedOperationException if expression is not {@link Kind#SELECT}.
*/
public CelSelect select() {
return exprKind().select();
}

/**
* Gets the underlying call expression.
*
* @throws UnsupportedOperationException if expression is not {@link Kind#CALL}.
*/
public CelCall call() {
return exprKind().call();
}

/**
* Gets the underlying createList expression.
*
* @throws UnsupportedOperationException if expression is not {@link Kind#CREATE_LIST}.
*/
public CelCreateList createList() {
return exprKind().createList();
}

/**
* Gets the underlying createStruct expression.
*
* @throws UnsupportedOperationException if expression is not {@link Kind#CREATE_STRUCT}.
*/
public CelCreateStruct createStruct() {
return exprKind().createStruct();
}

/**
* Gets the underlying createMap expression.
*
* @throws UnsupportedOperationException if expression is not {@link Kind#createMap}.
*/
public CelCreateMap createMap() {
return exprKind().createMap();
}

/**
* Gets the underlying comprehension expression.
*
* @throws UnsupportedOperationException if expression is not {@link Kind#COMPREHENSION}.
*/
public CelComprehension comprehension() {
return exprKind().comprehension();
}

/**
* Gets the underlying constant expression or a default instance of one if expression is not
* {@link Kind#CONSTANT}.
*/
public CelConstant constantOrDefault() {
return exprKind().getKind().equals(ExprKind.Kind.CONSTANT)
? exprKind().constant()
: CelConstant.ofNotSet();
}

/**
* Gets the underlying identifier expression or a default instance of one if expression is not
* {@link Kind#IDENT}.
*/
public CelIdent identOrDefault() {
return exprKind().getKind().equals(ExprKind.Kind.IDENT)
? exprKind().ident()
: CelIdent.newBuilder().build();
}

/**
* Gets the underlying select expression or a default instance of one if expression is not {@link
* Kind#SELECT}.
*/
public CelSelect selectOrDefault() {
return exprKind().getKind().equals(ExprKind.Kind.SELECT)
? exprKind().select()
: CelSelect.newBuilder().build();
}

/**
* Gets the underlying call expression or a default instance of one if expression is not {@link
* Kind#CALL}.
*/
public CelCall callOrDefault() {
return exprKind().getKind().equals(ExprKind.Kind.CALL)
? exprKind().call()
: CelCall.newBuilder().build();
}

/**
* Gets the underlying createList expression or a default instance of one if expression is not
* {@link Kind#CREATE_LIST}.
*/
public CelCreateList createListOrDefault() {
return exprKind().getKind().equals(ExprKind.Kind.CREATE_LIST)
? exprKind().createList()
: CelCreateList.newBuilder().build();
}

/**
* Gets the underlying createStruct expression or a default instance of one if expression is not
* {@link Kind#CREATE_STRUCT}.
*/
public CelCreateStruct createStructOrDefault() {
return exprKind().getKind().equals(ExprKind.Kind.CREATE_STRUCT)
? exprKind().createStruct()
: CelCreateStruct.newBuilder().build();
}

/**
* Gets the underlying createMap expression or a default instance of one if expression is not
* {@link Kind#CREATE_MAP}.
*/
public CelCreateMap createMapOrDefault() {
return exprKind().getKind().equals(ExprKind.Kind.CREATE_MAP)
? exprKind().createMap()
: CelCreateMap.newBuilder().build();
}

/**
* Gets the underlying comprehension expression or a default instance of one if expression is not
* {@link Kind#COMPREHENSION}.
*/
public CelComprehension comprehensionOrDefault() {
return exprKind().getKind().equals(ExprKind.Kind.COMPREHENSION)
? exprKind().comprehension()
: CelComprehension.newBuilder().build();
}

/** Builder for CelExpr. */
@AutoValue.Builder
public abstract static class Builder {
Expand Down Expand Up @@ -212,7 +338,7 @@ public abstract static class Builder {
public abstract Builder toBuilder();

public static Builder newBuilder() {
return new AutoValue_CelExpr_CelIdent.Builder();
return new AutoValue_CelExpr_CelIdent.Builder().setName("");
}
}

Expand Down Expand Up @@ -261,7 +387,10 @@ public abstract static class Builder {
public abstract Builder toBuilder();

public static Builder newBuilder() {
return new AutoValue_CelExpr_CelSelect.Builder().setTestOnly(false);
return new AutoValue_CelExpr_CelSelect.Builder()
.setField("")
.setOperand(CelExpr.newBuilder().build())
.setTestOnly(false);
}
}

Expand Down Expand Up @@ -345,7 +474,7 @@ public Builder toBuilder() {
}

public static Builder newBuilder() {
return new AutoValue_CelExpr_CelCall.Builder();
return new AutoValue_CelExpr_CelCall.Builder().setFunction("");
}
}

Expand Down Expand Up @@ -761,7 +890,14 @@ public abstract static class Builder {
public abstract Builder toBuilder();

public static Builder newBuilder() {
return new AutoValue_CelExpr_CelComprehension.Builder();
return new AutoValue_CelExpr_CelComprehension.Builder()
.setIterVar("")
.setIterRange(CelExpr.newBuilder().build())
.setAccuVar("")
.setAccuInit(CelExpr.newBuilder().build())
.setLoopCondition(CelExpr.newBuilder().build())
.setLoopStep(CelExpr.newBuilder().build())
.setResult(CelExpr.newBuilder().build());
}
}

Expand Down
4 changes: 4 additions & 0 deletions common/src/main/java/dev/cel/common/ast/CelExprConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ public static CelReference exprReferenceToCelReference(Reference reference) {
*/
public static CelConstant exprConstantToCelConstant(Constant constExpr) {
switch (constExpr.getConstantKindCase()) {
case CONSTANTKIND_NOT_SET:
return CelConstant.ofNotSet();
case NULL_VALUE:
return CelConstant.ofValue(constExpr.getNullValue());
case BOOL_VALUE:
Expand Down Expand Up @@ -243,6 +245,8 @@ private static Expr.Builder newExprBuilder(CelExpr expr) {
*/
public static Constant celConstantToExprConstant(CelConstant celConstant) {
switch (celConstant.getKind()) {
case NOT_SET:
return Constant.getDefaultInstance();
case NULL_VALUE:
return Constant.newBuilder().setNullValue(celConstant.nullValue()).build();
case BOOLEAN_VALUE:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ public static CelReference exprReferenceToCelReference(Reference reference) {
*/
public static CelConstant exprConstantToCelConstant(Constant constExpr) {
switch (constExpr.getConstantKindCase()) {
case CONSTANTKIND_NOT_SET:
return CelConstant.ofNotSet();
case NULL_VALUE:
return CelConstant.ofValue(constExpr.getNullValue());
case BOOL_VALUE:
Expand Down Expand Up @@ -243,6 +245,8 @@ private static Expr.Builder newExprBuilder(CelExpr expr) {
*/
public static Constant celConstantToExprConstant(CelConstant celConstant) {
switch (celConstant.getKind()) {
case NOT_SET:
return Constant.getDefaultInstance();
case NULL_VALUE:
return Constant.newBuilder().setNullValue(celConstant.nullValue()).build();
case BOOLEAN_VALUE:
Expand Down
8 changes: 8 additions & 0 deletions common/src/test/java/dev/cel/common/ast/CelConstantTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ public void constructTimestampValue() {
.isEqualTo(Timestamp.newBuilder().setSeconds(100L).build());
}

@Test
public void constructNotSetConstant() {
CelConstant constant = CelConstant.ofNotSet();

assertThat(constant).isNotNull();
assertThat(constant.getKind()).isEqualTo(Kind.NOT_SET);
}

private enum CelConstantTestCase {
NULL(CelConstant.ofValue(NullValue.NULL_VALUE)),
BOOLEAN(CelConstant.ofValue(true)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
@RunWith(TestParameterInjector.class)
public class CelExprConverterTest {
private enum ConstantTestCase {
NOT_SET(
Expr.newBuilder().setId(1).setConstExpr(Constant.getDefaultInstance()).build(),
CelExpr.ofConstantExpr(1, CelConstant.ofNotSet())),
NULL(
Expr.newBuilder()
.setId(1)
Expand Down
Loading

0 comments on commit 1fa54c9

Please sign in to comment.