Skip to content

Commit

Permalink
Add constant folding
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 570460653
  • Loading branch information
l46kok authored and copybara-github committed Oct 3, 2023
1 parent 4cf0ad7 commit 00426f8
Show file tree
Hide file tree
Showing 13 changed files with 942 additions and 39 deletions.
43 changes: 43 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 @@ -16,6 +16,7 @@

import com.google.auto.value.AutoOneOf;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.UnsignedLong;
import com.google.errorprone.annotations.Immutable;
import com.google.protobuf.ByteString;
Expand All @@ -33,6 +34,16 @@
@Internal
@Immutable
public abstract class CelConstant {
private static final ImmutableSet<Class<?>> CONSTANT_CLASSES =
ImmutableSet.of(
NullValue.class,
Boolean.class,
Long.class,
UnsignedLong.class,
Double.class,
String.class,
ByteString.class);

/** Represents the type of the Constant */
public enum Kind {
NOT_SET,
Expand Down Expand Up @@ -127,6 +138,38 @@ public static CelConstant ofValue(ByteString value) {
return AutoOneOf_CelConstant.bytesValue(value);
}

/** Checks whether the provided Java object is a valid CelConstant value. */
public static boolean isConstantValue(Object value) {
return CONSTANT_CLASSES.contains(value.getClass());
}

/**
* Converts the given Java object into a CelConstant value. This is equivalent of calling {@link
* CelConstant#ofValue} with concrete types.
*
* @throws IllegalArgumentException If the value is not a supported CelConstant. This includes the
* deprecated duration and timestamp values.
*/
public static CelConstant ofObjectValue(Object value) {
if (value instanceof NullValue) {
return ofValue((NullValue) value);
} else if (value instanceof Boolean) {
return ofValue((boolean) value);
} else if (value instanceof Long) {
return ofValue((long) value);
} else if (value instanceof UnsignedLong) {
return ofValue((UnsignedLong) value);
} else if (value instanceof Double) {
return ofValue((double) value);
} else if (value instanceof String) {
return ofValue((String) value);
} else if (value instanceof ByteString) {
return ofValue((ByteString) value);
}

throw new IllegalArgumentException("Value is not a CelConstant: " + value);
}

/**
* @deprecated Do not use. Duration is no longer built-in CEL type.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,32 +59,49 @@ public enum TraversalOrder {
* Returns a stream of {@link CelNavigableExpr} collected from the current node down to the last
* leaf-level member using post-order traversal.
*/
public Stream<CelNavigableExpr> descendants() {
return descendants(TraversalOrder.POST_ORDER);
public Stream<CelNavigableExpr> allNodes() {
return allNodes(TraversalOrder.POST_ORDER);
}

/**
* Returns a stream of {@link CelNavigableExpr} collected from the current node down to the last
* leaf-level member using the specified traversal order.
*/
public Stream<CelNavigableExpr> descendants(TraversalOrder traversalOrder) {
public Stream<CelNavigableExpr> allNodes(TraversalOrder traversalOrder) {
return CelNavigableExprVisitor.collect(this, traversalOrder);
}

/**
* Returns a stream of {@link CelNavigableExpr} collected from the current node to its immediate
* children using post-order traversal.
* Returns a stream of {@link CelNavigableExpr} collected down to the last leaf-level member using
* post-order traversal.
*/
public Stream<CelNavigableExpr> descendants() {
return descendants(TraversalOrder.POST_ORDER);
}

/**
* Returns a stream of {@link CelNavigableExpr} collected down to the last leaf-level member using
* the specified traversal order.
*/
public Stream<CelNavigableExpr> descendants(TraversalOrder traversalOrder) {
return CelNavigableExprVisitor.collect(this, traversalOrder).filter(node -> !node.equals(this));
}

/**
* Returns a stream of {@link CelNavigableExpr} collected from its immediate children using
* post-order traversal.
*/
public Stream<CelNavigableExpr> children() {
return children(TraversalOrder.POST_ORDER);
}

/**
* Returns a stream of {@link CelNavigableExpr} collected from the current node to its immediate
* children using the specified traversal order.
* Returns a stream of {@link CelNavigableExpr} collected from its immediate children using the
* specified traversal order.
*/
public Stream<CelNavigableExpr> children(TraversalOrder traversalOrder) {
return CelNavigableExprVisitor.collect(this, 1, traversalOrder);
return CelNavigableExprVisitor.collect(this, this.depth() + 1, traversalOrder)
.filter(node -> !node.equals(this));
}

/** Returns the underlying kind of the {@link CelExpr}. */
Expand Down
24 changes: 24 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 @@ -196,4 +196,28 @@ public void getValueOnInvalidKindCase_throwsException(
assertThrows(UnsupportedOperationException.class, constant::timestampValue);
}
}

@Test
public void getObjectValue_success() {
assertThat(CelConstant.ofObjectValue(NullValue.NULL_VALUE))
.isEqualTo(CelConstant.ofValue(NullValue.NULL_VALUE));
assertThat(CelConstant.ofObjectValue(true)).isEqualTo(CelConstant.ofValue(true));
assertThat(CelConstant.ofObjectValue(2L)).isEqualTo(CelConstant.ofValue(2L));
assertThat(CelConstant.ofObjectValue(UnsignedLong.valueOf(3L)))
.isEqualTo(CelConstant.ofValue(UnsignedLong.valueOf(3L)));
assertThat(CelConstant.ofObjectValue(3.0d)).isEqualTo(CelConstant.ofValue(3.0d));
assertThat(CelConstant.ofObjectValue("test")).isEqualTo(CelConstant.ofValue("test"));
assertThat(CelConstant.ofObjectValue(ByteString.copyFromUtf8("hello")))
.isEqualTo(CelConstant.ofValue(ByteString.copyFromUtf8("hello")));
}

@Test
public void getObjectValue_invalidParameter_throws() {
assertThrows(
IllegalArgumentException.class,
() -> CelConstant.ofObjectValue(Duration.getDefaultInstance()));
assertThrows(
IllegalArgumentException.class,
() -> CelConstant.ofObjectValue(Timestamp.getDefaultInstance()));
}
}
Loading

0 comments on commit 00426f8

Please sign in to comment.