diff --git a/checker/src/test/java/dev/cel/checker/BUILD.bazel b/checker/src/test/java/dev/cel/checker/BUILD.bazel
index c4ee4fa7..468c0af9 100644
--- a/checker/src/test/java/dev/cel/checker/BUILD.bazel
+++ b/checker/src/test/java/dev/cel/checker/BUILD.bazel
@@ -31,6 +31,7 @@ java_library(
"//common/internal:errors",
"//common/resources/testdata/proto3:standalone_global_enum_java_proto",
"//common/types",
+ "//common/types:cel_proto_types",
"//common/types:cel_types",
"//common/types:json",
"//common/types:message_type_provider",
diff --git a/checker/src/test/java/dev/cel/checker/ExprCheckerTest.java b/checker/src/test/java/dev/cel/checker/ExprCheckerTest.java
index eaf4aa2c..529a735f 100644
--- a/checker/src/test/java/dev/cel/checker/ExprCheckerTest.java
+++ b/checker/src/test/java/dev/cel/checker/ExprCheckerTest.java
@@ -14,10 +14,10 @@
package dev.cel.checker;
+import static dev.cel.common.types.CelProtoTypes.createOptionalType;
import static dev.cel.common.types.CelTypes.createList;
import static dev.cel.common.types.CelTypes.createMap;
import static dev.cel.common.types.CelTypes.createMessage;
-import static dev.cel.common.types.CelTypes.createOptionalType;
import static dev.cel.common.types.CelTypes.createTypeParam;
import static dev.cel.common.types.CelTypes.createWrapper;
import static dev.cel.common.types.CelTypes.format;
diff --git a/common/src/main/java/dev/cel/common/types/BUILD.bazel b/common/src/main/java/dev/cel/common/types/BUILD.bazel
index 4f402941..3812755c 100644
--- a/common/src/main/java/dev/cel/common/types/BUILD.bazel
+++ b/common/src/main/java/dev/cel/common/types/BUILD.bazel
@@ -81,6 +81,22 @@ java_library(
],
)
+java_library(
+ name = "cel_proto_types",
+ srcs = ["CelProtoTypes.java"],
+ tags = [
+ ],
+ deps = [
+ ":cel_internal_types",
+ ":cel_types",
+ ":type_providers",
+ ":types",
+ "@cel_spec//proto/cel/expr:expr_java_proto",
+ "@maven//:com_google_guava_guava",
+ "@maven//:com_google_protobuf_protobuf_java",
+ ],
+)
+
java_library(
name = "cel_v1alpha1_types",
srcs = ["CelV1AlphaTypes.java"],
diff --git a/common/src/main/java/dev/cel/common/types/CelProtoTypes.java b/common/src/main/java/dev/cel/common/types/CelProtoTypes.java
new file mode 100644
index 00000000..1c240ca1
--- /dev/null
+++ b/common/src/main/java/dev/cel/common/types/CelProtoTypes.java
@@ -0,0 +1,281 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package dev.cel.common.types;
+
+import static com.google.common.collect.ImmutableList.toImmutableList;
+
+import dev.cel.expr.Type;
+import dev.cel.expr.Type.AbstractType;
+import dev.cel.expr.Type.PrimitiveType;
+import dev.cel.expr.Type.WellKnownType;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Empty;
+import com.google.protobuf.NullValue;
+
+/**
+ * Utility class for working with {@link Type}.
+ *
+ *
This is equivalent to {@link CelTypes}, except this works specifically with canonical CEL expr
+ * protos.
+ */
+public final class CelProtoTypes {
+
+ public static final Type ERROR = Type.newBuilder().setError(Empty.getDefaultInstance()).build();
+ public static final Type DYN = Type.newBuilder().setDyn(Empty.getDefaultInstance()).build();
+ public static final Type NULL_TYPE = Type.newBuilder().setNull(NullValue.NULL_VALUE).build();
+ public static final Type BOOL = create(PrimitiveType.BOOL);
+ public static final Type BYTES = create(PrimitiveType.BYTES);
+ public static final Type STRING = create(PrimitiveType.STRING);
+ public static final Type DOUBLE = create(PrimitiveType.DOUBLE);
+ public static final Type UINT64 = create(PrimitiveType.UINT64);
+ public static final Type INT64 = create(PrimitiveType.INT64);
+ public static final Type ANY = create(WellKnownType.ANY);
+ public static final Type TIMESTAMP = create(WellKnownType.TIMESTAMP);
+ public static final Type DURATION = create(WellKnownType.DURATION);
+
+ private static final ImmutableMap SIMPLE_CEL_KIND_TO_TYPE =
+ ImmutableMap.builder()
+ .put(CelKind.ERROR, ERROR)
+ .put(CelKind.DYN, DYN)
+ .put(CelKind.ANY, ANY)
+ .put(CelKind.BOOL, BOOL)
+ .put(CelKind.BYTES, BYTES)
+ .put(CelKind.DOUBLE, DOUBLE)
+ .put(CelKind.DURATION, DURATION)
+ .put(CelKind.INT, INT64)
+ .put(CelKind.NULL_TYPE, NULL_TYPE)
+ .put(CelKind.STRING, STRING)
+ .put(CelKind.TIMESTAMP, TIMESTAMP)
+ .put(CelKind.UINT, UINT64)
+ .buildOrThrow();
+
+ private static final ImmutableMap PROTOBUF_TYPE_TO_CEL_TYPE_MAP =
+ ImmutableMap.builder()
+ .put(BOOL, SimpleType.BOOL)
+ .put(BYTES, SimpleType.BYTES)
+ .put(DOUBLE, SimpleType.DOUBLE)
+ .put(INT64, SimpleType.INT)
+ .put(STRING, SimpleType.STRING)
+ .put(UINT64, SimpleType.UINT)
+ .put(ANY, SimpleType.ANY)
+ .put(DURATION, SimpleType.DURATION)
+ .put(TIMESTAMP, SimpleType.TIMESTAMP)
+ .put(DYN, SimpleType.DYN)
+ .put(NULL_TYPE, SimpleType.NULL_TYPE)
+ .put(ERROR, SimpleType.ERROR)
+ .buildOrThrow();
+
+ /** Create a primitive {@code Type}. */
+ public static Type create(PrimitiveType type) {
+ return Type.newBuilder().setPrimitive(type).build();
+ }
+
+ /** Create a well-known {@code Type}. */
+ public static Type create(WellKnownType type) {
+ return Type.newBuilder().setWellKnown(type).build();
+ }
+
+ /** Create a type {@code Type}. */
+ public static Type create(Type target) {
+ return Type.newBuilder().setType(target).build();
+ }
+
+ /** Create a list with {@code elemType}. */
+ public static Type createList(Type elemType) {
+ return Type.newBuilder().setListType(Type.ListType.newBuilder().setElemType(elemType)).build();
+ }
+
+ /** Create a map with {@code keyType} and {@code valueType}. */
+ public static Type createMap(Type keyType, Type valueType) {
+ return Type.newBuilder()
+ .setMapType(Type.MapType.newBuilder().setKeyType(keyType).setValueType(valueType))
+ .build();
+ }
+
+ /** Create a message {@code Type} for {@code messageName}. */
+ public static Type createMessage(String messageName) {
+ return Type.newBuilder().setMessageType(messageName).build();
+ }
+
+ /** Create a message {@code Type} for {@code Descriptor}. */
+ public static Type createMessage(Descriptor descriptor) {
+ return createMessage(descriptor.getFullName());
+ }
+
+ /** Create a type param {@code Type}. */
+ public static Type createTypeParam(String name) {
+ return Type.newBuilder().setTypeParam(name).build();
+ }
+
+ /** Create a wrapper type for the {@code primitive}. */
+ public static Type createWrapper(PrimitiveType primitive) {
+ return Type.newBuilder().setWrapper(primitive).build();
+ }
+
+ /** Create a wrapper type where the input is a {@code Type} of primitive types. */
+ public static Type createWrapper(Type type) {
+ Preconditions.checkArgument(type.getTypeKindCase() == Type.TypeKindCase.PRIMITIVE);
+ return createWrapper(type.getPrimitive());
+ }
+
+ /**
+ * Create an abstract type indicating that the parameterized type may be contained within the
+ * object.
+ */
+ public static Type createOptionalType(Type paramType) {
+ return Type.newBuilder()
+ .setAbstractType(
+ AbstractType.newBuilder()
+ .setName(OptionalType.NAME)
+ .addParameterTypes(paramType)
+ .build())
+ .build();
+ }
+
+ /** Checks if the provided parameter is an optional type */
+ public static boolean isOptionalType(Type type) {
+ return type.hasAbstractType() && type.getAbstractType().getName().equals(OptionalType.NAME);
+ }
+
+ /**
+ * Method to adapt a simple {@code Type} into a {@code String} representation.
+ *
+ * This method can also format global functions. See the {@link CelTypes#formatFunction}
+ * methods for richer control over function formatting.
+ */
+ public static String format(Type type) {
+ return CelTypes.format(typeToCelType(type), /* typeParamToDyn= */ false);
+ }
+
+ /** Converts a Protobuf type into CEL native type. */
+ public static Type celTypeToType(CelType celType) {
+ Type type = SIMPLE_CEL_KIND_TO_TYPE.get(celType.kind());
+ if (type != null) {
+ if (celType instanceof NullableType) {
+ return createWrapper(type);
+ }
+ return type;
+ }
+
+ switch (celType.kind()) {
+ case UNSPECIFIED:
+ return Type.getDefaultInstance();
+ case LIST:
+ ListType listType = (ListType) celType;
+ if (listType.hasElemType()) {
+ return createList(celTypeToType(listType.elemType()));
+ } else {
+ // TODO: Exists for compatibility reason only. Remove after callers have been
+ // migrated.
+ return Type.newBuilder().setListType(Type.ListType.getDefaultInstance()).build();
+ }
+ case MAP:
+ MapType mapType = (MapType) celType;
+ return createMap(celTypeToType(mapType.keyType()), celTypeToType(mapType.valueType()));
+ case OPAQUE:
+ if (celType.name().equals("function")) {
+ Type.FunctionType.Builder functionBuilder = Type.FunctionType.newBuilder();
+ if (!celType.parameters().isEmpty()) {
+ functionBuilder
+ .setResultType(celTypeToType(celType.parameters().get(0)))
+ .addAllArgTypes(
+ celType.parameters().stream()
+ .skip(1)
+ .map(CelProtoTypes::celTypeToType)
+ .collect(toImmutableList()));
+ }
+ return Type.newBuilder().setFunction(functionBuilder).build();
+ } else {
+ return Type.newBuilder()
+ .setAbstractType(
+ Type.AbstractType.newBuilder()
+ .setName(celType.name())
+ .addAllParameterTypes(
+ celType.parameters().stream()
+ .map(CelProtoTypes::celTypeToType)
+ .collect(toImmutableList())))
+ .build();
+ }
+ case STRUCT:
+ return createMessage(celType.name());
+ case TYPE:
+ TypeType typeType = (TypeType) celType;
+ return create(celTypeToType(typeType.type()));
+ case TYPE_PARAM:
+ return createTypeParam(celType.name());
+ default:
+ throw new IllegalArgumentException(String.format("Unsupported type: %s", celType));
+ }
+ }
+
+ /** Converts a Protobuf type to CEL native type. */
+ public static CelType typeToCelType(Type type) {
+ CelType celType = PROTOBUF_TYPE_TO_CEL_TYPE_MAP.get(type);
+ if (celType != null) {
+ return celType;
+ }
+
+ switch (type.getTypeKindCase()) {
+ case TYPEKIND_NOT_SET:
+ return UnspecifiedType.create();
+ case WRAPPER:
+ return NullableType.create(typeToCelType(create(type.getWrapper())));
+ case MESSAGE_TYPE:
+ return StructTypeReference.create(type.getMessageType());
+ case LIST_TYPE:
+ Type.ListType listType = type.getListType();
+ if (listType.hasElemType()) {
+ return ListType.create(typeToCelType(listType.getElemType()));
+ } else {
+ // TODO: Exists for compatibility reason only. Remove after callers have been
+ // migrated.
+ return ListType.create();
+ }
+ case MAP_TYPE:
+ Type.MapType mapType = type.getMapType();
+ return MapType.create(
+ typeToCelType(mapType.getKeyType()), typeToCelType(mapType.getValueType()));
+ case TYPE_PARAM:
+ return TypeParamType.create(type.getTypeParam());
+ case ABSTRACT_TYPE:
+ Type.AbstractType abstractType = type.getAbstractType();
+ ImmutableList params =
+ abstractType.getParameterTypesList().stream()
+ .map(CelProtoTypes::typeToCelType)
+ .collect(toImmutableList());
+ if (abstractType.getName().equals(OptionalType.NAME)) {
+ return OptionalType.create(params.get(0));
+ }
+ return OpaqueType.create(abstractType.getName(), params);
+ case TYPE:
+ return TypeType.create(typeToCelType(type.getType()));
+ case FUNCTION:
+ Type.FunctionType functionType = type.getFunction();
+ return CelTypes.createFunctionType(
+ typeToCelType(functionType.getResultType()),
+ functionType.getArgTypesList().stream()
+ .map(CelProtoTypes::typeToCelType)
+ .collect(toImmutableList()));
+ default:
+ // Add more cases as needed.
+ throw new IllegalArgumentException(String.format("Unsupported type: %s", type));
+ }
+ }
+
+ private CelProtoTypes() {}
+}
diff --git a/common/src/main/java/dev/cel/common/types/CelTypes.java b/common/src/main/java/dev/cel/common/types/CelTypes.java
index 1d178214..f4d220bc 100644
--- a/common/src/main/java/dev/cel/common/types/CelTypes.java
+++ b/common/src/main/java/dev/cel/common/types/CelTypes.java
@@ -17,10 +17,8 @@
import static com.google.common.collect.ImmutableList.toImmutableList;
import dev.cel.expr.Type;
-import dev.cel.expr.Type.AbstractType;
import dev.cel.expr.Type.PrimitiveType;
import dev.cel.expr.Type.WellKnownType;
-import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -54,22 +52,77 @@ public final class CelTypes {
public static final String UINT32_WRAPPER_MESSAGE = "google.protobuf.UInt32Value";
public static final String UINT64_WRAPPER_MESSAGE = "google.protobuf.UInt64Value";
- // Static types.
+ /**
+ * TODO: Remove once clients have been migrated.
+ *
+ * @deprecated Use {@link CelProtoTypes#ERROR} instead.
+ */
+ @Deprecated
public static final Type ERROR = Type.newBuilder().setError(Empty.getDefaultInstance()).build();
+
+ /**
+ * @deprecated Use {@link CelProtoTypes#DYN} instead.
+ */
+ @Deprecated
public static final Type DYN = Type.newBuilder().setDyn(Empty.getDefaultInstance()).build();
+
+ /**
+ * @deprecated Use {@link CelProtoTypes#NULL_TYPE} instead.
+ */
+ @Deprecated
public static final Type NULL_TYPE = Type.newBuilder().setNull(NullValue.NULL_VALUE).build();
- public static final Type BOOL = create(PrimitiveType.BOOL);
- public static final Type BYTES = create(PrimitiveType.BYTES);
- public static final Type STRING = create(PrimitiveType.STRING);
- public static final Type DOUBLE = create(PrimitiveType.DOUBLE);
- public static final Type UINT64 = create(PrimitiveType.UINT64);
- public static final Type INT64 = create(PrimitiveType.INT64);
- public static final Type ANY = create(WellKnownType.ANY);
- public static final Type TIMESTAMP = create(WellKnownType.TIMESTAMP);
- public static final Type DURATION = create(WellKnownType.DURATION);
-
- /** Map of well-known proto messages and their CEL {@code Type} equivalents. */
- static final ImmutableMap WELL_KNOWN_TYPE_MAP =
+
+ /**
+ * @deprecated Use {@link CelProtoTypes#BOOL} instead.
+ */
+ @Deprecated public static final Type BOOL = create(PrimitiveType.BOOL);
+
+ /**
+ * @deprecated Use {@link CelProtoTypes#BYTES} instead.
+ */
+ @Deprecated public static final Type BYTES = create(PrimitiveType.BYTES);
+
+ /**
+ * @deprecated Use {@link CelProtoTypes#STRING} instead.
+ */
+ @Deprecated public static final Type STRING = create(PrimitiveType.STRING);
+
+ /**
+ * @deprecated Use {@link CelProtoTypes#DOUBLE} instead.
+ */
+ @Deprecated public static final Type DOUBLE = create(PrimitiveType.DOUBLE);
+
+ /**
+ * @deprecated Use {@link CelProtoTypes#UINT64} instead.
+ */
+ @Deprecated public static final Type UINT64 = create(PrimitiveType.UINT64);
+
+ /**
+ * @deprecated Use {@link CelProtoTypes#INT64} instead.
+ */
+ @Deprecated public static final Type INT64 = create(PrimitiveType.INT64);
+
+ /**
+ * @deprecated Use {@link CelProtoTypes#ANY} instead.
+ */
+ @Deprecated public static final Type ANY = create(WellKnownType.ANY);
+
+ /**
+ * @deprecated Use {@link CelProtoTypes#TIMESTAMP} instead.
+ */
+ @Deprecated public static final Type TIMESTAMP = create(WellKnownType.TIMESTAMP);
+
+ /**
+ * @deprecated Use {@link CelProtoTypes#DURATION} instead.
+ */
+ @Deprecated public static final Type DURATION = create(WellKnownType.DURATION);
+
+ /**
+ * TODO: Remove once clients have been migrated.
+ *
+ * Map of well-known proto messages and their CEL {@code Type} equivalents.
+ */
+ private static final ImmutableMap WELL_KNOWN_TYPE_MAP =
ImmutableMap.builder()
.put(DOUBLE_WRAPPER_MESSAGE, CelTypes.createWrapper(CelTypes.DOUBLE))
.put(FLOAT_WRAPPER_MESSAGE, CelTypes.createWrapper(CelTypes.DOUBLE))
@@ -107,7 +160,8 @@ public final class CelTypes {
.put(VALUE_MESSAGE, SimpleType.DYN)
.buildOrThrow();
- static final ImmutableMap SIMPLE_CEL_KIND_TO_TYPE =
+ /** TODO: Remove once clients have been migrated. */
+ private static final ImmutableMap SIMPLE_CEL_KIND_TO_TYPE =
ImmutableMap.builder()
.put(CelKind.ERROR, CelTypes.ERROR)
.put(CelKind.DYN, CelTypes.DYN)
@@ -123,6 +177,7 @@ public final class CelTypes {
.put(CelKind.UINT, CelTypes.UINT64)
.buildOrThrow();
+ /** TODO: Remove once clients have been migrated. */
private static final ImmutableMap PROTOBUF_TYPE_TO_CEL_TYPE_MAP =
ImmutableMap.builder()
.put(CelTypes.BOOL, SimpleType.BOOL)
@@ -139,27 +194,40 @@ public final class CelTypes {
.put(CelTypes.ERROR, SimpleType.ERROR)
.buildOrThrow();
- /** Create a primitive {@code Type}. */
+ /**
+ * Create a primitive {@code Type}.
+ *
+ * @deprecated Use {@link CelProtoTypes#create(PrimitiveType)} instead.
+ */
+ @Deprecated
public static Type create(PrimitiveType type) {
return Type.newBuilder().setPrimitive(type).build();
}
- /** Create a well-known {@code Type}. */
+ /**
+ * Create a well-known {@code Type}.
+ *
+ * @deprecated Use {@link CelProtoTypes#create(WellKnownType)} instead.
+ */
+ @Deprecated
public static Type create(WellKnownType type) {
return Type.newBuilder().setWellKnown(type).build();
}
/** Create a type {@code Type}. */
+ @Deprecated
public static Type create(Type target) {
return Type.newBuilder().setType(target).build();
}
/** Create a list with {@code elemType}. */
+ @Deprecated
public static Type createList(Type elemType) {
return Type.newBuilder().setListType(Type.ListType.newBuilder().setElemType(elemType)).build();
}
/** Create a map with {@code keyType} and {@code valueType}. */
+ @Deprecated
public static Type createMap(Type keyType, Type valueType) {
return Type.newBuilder()
.setMapType(Type.MapType.newBuilder().setKeyType(keyType).setValueType(valueType))
@@ -167,26 +235,31 @@ public static Type createMap(Type keyType, Type valueType) {
}
/** Create a message {@code Type} for {@code messageName}. */
+ @Deprecated
public static Type createMessage(String messageName) {
return Type.newBuilder().setMessageType(messageName).build();
}
/** Create a message {@code Type} for {@code Descriptor}. */
+ @Deprecated
public static Type createMessage(Descriptor descriptor) {
return createMessage(descriptor.getFullName());
}
/** Create a type param {@code Type}. */
+ @Deprecated
public static Type createTypeParam(String name) {
return Type.newBuilder().setTypeParam(name).build();
}
/** Create a wrapper type for the {@code primitive}. */
+ @Deprecated
public static Type createWrapper(PrimitiveType primitive) {
return Type.newBuilder().setWrapper(primitive).build();
}
/** Create a wrapper type where the input is a {@code Type} of primitive types. */
+ @Deprecated
public static Type createWrapper(Type type) {
Preconditions.checkArgument(type.getTypeKindCase() == Type.TypeKindCase.PRIMITIVE);
return createWrapper(type.getPrimitive());
@@ -210,26 +283,6 @@ public static boolean isWrapperType(String typeName) {
}
}
- /**
- * Create an abstract type indicating that the parameterized type may be contained within the
- * object.
- */
- @VisibleForTesting
- public static Type createOptionalType(Type paramType) {
- return Type.newBuilder()
- .setAbstractType(
- AbstractType.newBuilder()
- .setName(OptionalType.NAME)
- .addParameterTypes(paramType)
- .build())
- .build();
- }
-
- /** Checks if the provided parameter is an optional type */
- public static boolean isOptionalType(Type type) {
- return type.hasAbstractType() && type.getAbstractType().getName().equals(OptionalType.NAME);
- }
-
/**
* Create an abstract type with an expected result type (first argument in the parameter) and the
* argument types.
@@ -267,7 +320,7 @@ public static String format(CelType type) {
return format(type, /* typeParamToDyn= */ false);
}
- private static String format(CelType type, boolean typeParamToDyn) {
+ static String format(CelType type, boolean typeParamToDyn) {
if (type instanceof NullableType) {
return String.format(
"wrapper(%s)", format(((NullableType) type).targetType(), typeParamToDyn));
@@ -370,8 +423,12 @@ public static Optional getWellKnownCelType(String typeName) {
return Optional.ofNullable(WELL_KNOWN_CEL_TYPE_MAP.getOrDefault(typeName, null));
}
- /** Converts a Protobuf type into CEL native type. */
- @Internal
+ /**
+ * Converts a Protobuf type into CEL native type.
+ *
+ * @deprecated Use {@link CelProtoTypes#celTypeToType(CelType)} instead}.
+ */
+ @Deprecated
public static Type celTypeToType(CelType celType) {
Type type = SIMPLE_CEL_KIND_TO_TYPE.get(celType.kind());
if (type != null) {
@@ -432,8 +489,12 @@ public static Type celTypeToType(CelType celType) {
}
}
- /** Converts a Protobuf type to CEL native type. */
- @Internal
+ /**
+ * Converts a Protobuf type to CEL native type.
+ *
+ * @deprecated Use {@link CelProtoTypes#typeToCelType(Type)} instead}.
+ */
+ @Deprecated
public static CelType typeToCelType(Type type) {
CelType celType = PROTOBUF_TYPE_TO_CEL_TYPE_MAP.get(type);
if (celType != null) {
diff --git a/common/src/test/java/dev/cel/common/types/BUILD.bazel b/common/src/test/java/dev/cel/common/types/BUILD.bazel
index 42da475c..541a77ec 100644
--- a/common/src/test/java/dev/cel/common/types/BUILD.bazel
+++ b/common/src/test/java/dev/cel/common/types/BUILD.bazel
@@ -11,6 +11,7 @@ java_library(
"//:java_truth",
"//common/types",
"//common/types:cel_internal_types",
+ "//common/types:cel_proto_types",
"//common/types:cel_types",
"//common/types:message_type_provider",
"//common/types:type_providers",
diff --git a/common/src/test/java/dev/cel/common/types/CelProtoTypesTest.java b/common/src/test/java/dev/cel/common/types/CelProtoTypesTest.java
new file mode 100644
index 00000000..bcddd03f
--- /dev/null
+++ b/common/src/test/java/dev/cel/common/types/CelProtoTypesTest.java
@@ -0,0 +1,122 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package dev.cel.common.types;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+
+import dev.cel.expr.Type;
+import dev.cel.expr.Type.AbstractType;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.testing.junit.testparameterinjector.TestParameter;
+import com.google.testing.junit.testparameterinjector.TestParameterInjector;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(TestParameterInjector.class)
+public final class CelProtoTypesTest {
+
+ @Test
+ public void isOptionalType_true() {
+ Type optionalType = CelProtoTypes.createOptionalType(CelProtoTypes.INT64);
+
+ assertThat(CelProtoTypes.isOptionalType(optionalType)).isTrue();
+ }
+
+ @Test
+ public void isOptionalType_false() {
+ Type notOptionalType =
+ Type.newBuilder()
+ .setAbstractType(AbstractType.newBuilder().setName("notOptional").build())
+ .build();
+
+ assertThat(CelProtoTypes.isOptionalType(notOptionalType)).isFalse();
+ }
+
+ @Test
+ public void createOptionalType() {
+ Type optionalType = CelProtoTypes.createOptionalType(CelProtoTypes.INT64);
+
+ assertThat(optionalType.hasAbstractType()).isTrue();
+ assertThat(optionalType.getAbstractType().getName()).isEqualTo("optional_type");
+ assertThat(optionalType.getAbstractType().getParameterTypesCount()).isEqualTo(1);
+ assertThat(optionalType.getAbstractType().getParameterTypes(0)).isEqualTo(CelProtoTypes.INT64);
+ }
+
+ private enum TestCases {
+ UNSPECIFIED(UnspecifiedType.create(), Type.getDefaultInstance()),
+ STRING(SimpleType.STRING, CelProtoTypes.STRING),
+ INT(NullableType.create(SimpleType.INT), CelProtoTypes.createWrapper(CelProtoTypes.INT64)),
+ UINT(NullableType.create(SimpleType.UINT), CelProtoTypes.createWrapper(CelProtoTypes.UINT64)),
+ DOUBLE(
+ NullableType.create(SimpleType.DOUBLE), CelProtoTypes.createWrapper(CelProtoTypes.DOUBLE)),
+ BOOL(NullableType.create(SimpleType.BOOL), CelProtoTypes.createWrapper(CelProtoTypes.BOOL)),
+ BYTES(SimpleType.BYTES, CelProtoTypes.BYTES),
+ ANY(SimpleType.ANY, CelProtoTypes.ANY),
+ LIST(
+ ListType.create(),
+ Type.newBuilder().setListType(Type.ListType.getDefaultInstance()).build()),
+ DYN(ListType.create(SimpleType.DYN), CelProtoTypes.createList(CelProtoTypes.DYN)),
+ ENUM(EnumType.create("CustomEnum", ImmutableMap.of()), CelProtoTypes.INT64),
+ STRUCT_TYPE_REF(
+ StructTypeReference.create("MyCustomStruct"),
+ CelProtoTypes.createMessage("MyCustomStruct")),
+ OPAQUE(
+ OpaqueType.create("vector", SimpleType.UINT),
+ Type.newBuilder()
+ .setAbstractType(
+ AbstractType.newBuilder().setName("vector").addParameterTypes(CelProtoTypes.UINT64))
+ .build()),
+ TYPE_PARAM(TypeParamType.create("T"), CelProtoTypes.createTypeParam("T")),
+ FUNCTION(
+ CelTypes.createFunctionType(
+ SimpleType.INT, ImmutableList.of(SimpleType.STRING, SimpleType.UINT)),
+ Type.newBuilder()
+ .setFunction(
+ Type.FunctionType.newBuilder()
+ .setResultType(CelProtoTypes.INT64)
+ .addAllArgTypes(ImmutableList.of(CelProtoTypes.STRING, CelProtoTypes.UINT64)))
+ .build()),
+ OPTIONAL(
+ OptionalType.create(SimpleType.INT), CelProtoTypes.createOptionalType(CelProtoTypes.INT64)),
+ TYPE(
+ TypeType.create(MapType.create(SimpleType.STRING, SimpleType.STRING)),
+ CelProtoTypes.create(CelProtoTypes.createMap(CelProtoTypes.STRING, CelProtoTypes.STRING)));
+
+ private final CelType celType;
+ private final Type type;
+
+ TestCases(CelType celType, Type type) {
+ this.celType = celType;
+ this.type = type;
+ }
+ }
+
+ @Test
+ public void celTypeToType(@TestParameter TestCases testCase) {
+ assertThat(CelProtoTypes.celTypeToType(testCase.celType)).isEqualTo(testCase.type);
+ }
+
+ @Test
+ public void typeToCelType(@TestParameter TestCases testCase) {
+ if (testCase.celType instanceof EnumType) {
+ // (b/178627883) Strongly typed enum is not supported yet
+ return;
+ }
+
+ assertThat(CelProtoTypes.typeToCelType(testCase.type)).isEqualTo(testCase.celType);
+ }
+}
diff --git a/common/src/test/java/dev/cel/common/types/CelTypesTest.java b/common/src/test/java/dev/cel/common/types/CelTypesTest.java
index da5c556c..ae6e0808 100644
--- a/common/src/test/java/dev/cel/common/types/CelTypesTest.java
+++ b/common/src/test/java/dev/cel/common/types/CelTypesTest.java
@@ -15,10 +15,8 @@
package dev.cel.common.types;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
import dev.cel.expr.Type;
-import dev.cel.expr.Type.AbstractType;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.testing.junit.testparameterinjector.TestParameter;
@@ -29,52 +27,6 @@
@RunWith(TestParameterInjector.class)
public final class CelTypesTest {
- private enum TestCases {
- UNSPECIFIED(UnspecifiedType.create(), Type.getDefaultInstance()),
- STRING(SimpleType.STRING, CelTypes.STRING),
- INT(NullableType.create(SimpleType.INT), CelTypes.createWrapper(CelTypes.INT64)),
- UINT(NullableType.create(SimpleType.UINT), CelTypes.createWrapper(CelTypes.UINT64)),
- DOUBLE(NullableType.create(SimpleType.DOUBLE), CelTypes.createWrapper(CelTypes.DOUBLE)),
- BOOL(NullableType.create(SimpleType.BOOL), CelTypes.createWrapper(CelTypes.BOOL)),
- BYTES(SimpleType.BYTES, CelTypes.BYTES),
- ANY(SimpleType.ANY, CelTypes.ANY),
- LIST(
- ListType.create(),
- Type.newBuilder().setListType(Type.ListType.getDefaultInstance()).build()),
- DYN(ListType.create(SimpleType.DYN), CelTypes.createList(CelTypes.DYN)),
- ENUM(EnumType.create("CustomEnum", ImmutableMap.of()), CelTypes.INT64),
- STRUCT_TYPE_REF(
- StructTypeReference.create("MyCustomStruct"), CelTypes.createMessage("MyCustomStruct")),
- OPAQUE(
- OpaqueType.create("vector", SimpleType.UINT),
- Type.newBuilder()
- .setAbstractType(
- AbstractType.newBuilder().setName("vector").addParameterTypes(CelTypes.UINT64))
- .build()),
- TYPE_PARAM(TypeParamType.create("T"), CelTypes.createTypeParam("T")),
- FUNCTION(
- CelTypes.createFunctionType(
- SimpleType.INT, ImmutableList.of(SimpleType.STRING, SimpleType.UINT)),
- Type.newBuilder()
- .setFunction(
- Type.FunctionType.newBuilder()
- .setResultType(CelTypes.INT64)
- .addAllArgTypes(ImmutableList.of(CelTypes.STRING, CelTypes.UINT64)))
- .build()),
- OPTIONAL(OptionalType.create(SimpleType.INT), CelTypes.createOptionalType(CelTypes.INT64)),
- TYPE(
- TypeType.create(MapType.create(SimpleType.STRING, SimpleType.STRING)),
- CelTypes.create(CelTypes.createMap(CelTypes.STRING, CelTypes.STRING)));
-
- private final CelType celType;
- private final Type type;
-
- TestCases(CelType celType, Type type) {
- this.celType = celType;
- this.type = type;
- }
- }
-
@Test
public void isWellKnownType_true() {
assertThat(CelTypes.isWellKnownType(CelTypes.ANY_MESSAGE)).isTrue();
@@ -85,48 +37,6 @@ public void isWellKnownType_false() {
assertThat(CelTypes.isWellKnownType("CustomType")).isFalse();
}
- @Test
- public void createOptionalType() {
- Type optionalType = CelTypes.createOptionalType(CelTypes.INT64);
-
- assertThat(optionalType.hasAbstractType()).isTrue();
- assertThat(optionalType.getAbstractType().getName()).isEqualTo("optional_type");
- assertThat(optionalType.getAbstractType().getParameterTypesCount()).isEqualTo(1);
- assertThat(optionalType.getAbstractType().getParameterTypes(0)).isEqualTo(CelTypes.INT64);
- }
-
- @Test
- public void isOptionalType_true() {
- Type optionalType = CelTypes.createOptionalType(CelTypes.INT64);
-
- assertThat(CelTypes.isOptionalType(optionalType)).isTrue();
- }
-
- @Test
- public void isOptionalType_false() {
- Type notOptionalType =
- Type.newBuilder()
- .setAbstractType(AbstractType.newBuilder().setName("notOptional").build())
- .build();
-
- assertThat(CelTypes.isOptionalType(notOptionalType)).isFalse();
- }
-
- @Test
- public void celTypeToType(@TestParameter TestCases testCase) {
- assertThat(CelTypes.celTypeToType(testCase.celType)).isEqualTo(testCase.type);
- }
-
- @Test
- public void typeToCelType(@TestParameter TestCases testCase) {
- if (testCase.celType instanceof EnumType) {
- // (b/178627883) Strongly typed enum is not supported yet
- return;
- }
-
- assertThat(CelTypes.typeToCelType(testCase.type)).isEqualTo(testCase.celType);
- }
-
private enum FormatTestCases {
UNSPECIFIED(UnspecifiedType.create(), ""),
STRING(SimpleType.STRING, "string"),
@@ -171,9 +81,9 @@ public void format_withCelType(@TestParameter FormatTestCases testCase) {
@Test
public void format_withType(@TestParameter FormatTestCases testCase) {
- Type type = CelTypes.celTypeToType(testCase.celType);
+ Type type = CelProtoTypes.celTypeToType(testCase.celType);
- assertThat(CelTypes.format(type)).isEqualTo(testCase.formattedString);
+ assertThat(CelProtoTypes.format(type)).isEqualTo(testCase.formattedString);
}
@Test
diff --git a/common/types/BUILD.bazel b/common/types/BUILD.bazel
index 76904d76..1802b054 100644
--- a/common/types/BUILD.bazel
+++ b/common/types/BUILD.bazel
@@ -39,6 +39,11 @@ java_library(
exports = ["//common/src/main/java/dev/cel/common/types:cel_types"],
)
+java_library(
+ name = "cel_proto_types",
+ exports = ["//common/src/main/java/dev/cel/common/types:cel_proto_types"],
+)
+
java_library(
name = "cel_v1alpha1_types",
visibility = ["//visibility:public"],