diff --git a/checker/BUILD.bazel b/checker/BUILD.bazel index 25fc8d73..de632327 100644 --- a/checker/BUILD.bazel +++ b/checker/BUILD.bazel @@ -51,3 +51,8 @@ java_library( name = "proto_expr_visitor", exports = ["//checker/src/main/java/dev/cel/checker:proto_expr_visitor"], ) + +java_library( + name = "standard_decl", + exports = ["//checker/src/main/java/dev/cel/checker:standard_decl"], +) diff --git a/checker/src/main/java/dev/cel/checker/BUILD.bazel b/checker/src/main/java/dev/cel/checker/BUILD.bazel index 96cbd598..0c385cc4 100644 --- a/checker/src/main/java/dev/cel/checker/BUILD.bazel +++ b/checker/src/main/java/dev/cel/checker/BUILD.bazel @@ -28,7 +28,6 @@ CHECKER_LEGACY_ENV_SOURCES = [ "ExprChecker.java", "ExprVisitor.java", "InferenceContext.java", - "Standard.java", "TypeFormatter.java", "TypeProvider.java", "Types.java", @@ -166,6 +165,7 @@ java_library( ], deps = [ ":cel_ident_decl", + ":standard_decl", "//:auto_value", "//common", "//common:compiler_common", @@ -217,3 +217,22 @@ java_library( "//common:proto_ast", ], ) + +java_library( + name = "standard_decl", + srcs = [ + "CelStandardDeclaration.java", + ], + tags = [ + ], + deps = [ + ":cel_ident_decl", + "//common:compiler_common", + "//common/types", + "//common/types:cel_types", + "//common/types:type_providers", + "//parser:operator", + "@maven//:com_google_errorprone_error_prone_annotations", + "@maven//:com_google_guava_guava", + ], +) diff --git a/checker/src/main/java/dev/cel/checker/CelStandardDeclaration.java b/checker/src/main/java/dev/cel/checker/CelStandardDeclaration.java new file mode 100644 index 00000000..845976d4 --- /dev/null +++ b/checker/src/main/java/dev/cel/checker/CelStandardDeclaration.java @@ -0,0 +1,1446 @@ +package dev.cel.checker; + +import static com.google.common.collect.ImmutableSet.toImmutableSet; +import static java.util.Arrays.stream; + +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.Immutable; +import dev.cel.common.CelFunctionDecl; +import dev.cel.common.CelOverloadDecl; +import dev.cel.common.types.CelType; +import dev.cel.common.types.CelTypes; +import dev.cel.common.types.ListType; +import dev.cel.common.types.MapType; +import dev.cel.common.types.SimpleType; +import dev.cel.common.types.TypeParamType; +import dev.cel.common.types.TypeType; +import dev.cel.parser.Operator; + +/** + * Standard declarations for CEL. + * + *

Refer to CEL + * Specification for comprehensive listing of functions and identifiers included in the standard + * environment. + */ +@Immutable +public class CelStandardDeclaration { + // Some shortcuts we use when building declarations. + private static final TypeParamType TYPE_PARAM_A = TypeParamType.create("A"); + private static final ListType LIST_OF_A = ListType.create(TYPE_PARAM_A); + private static final TypeParamType TYPE_PARAM_B = TypeParamType.create("B"); + private static final MapType MAP_OF_AB = MapType.create(TYPE_PARAM_A, TYPE_PARAM_B); + + private static final ImmutableSet STANDARD_FUNCTIONS = + stream(Function.values()).map(f -> f.celFunctionDecl).collect(toImmutableSet()); + + private static final ImmutableSet DEPRECATED_STANDARD_FUNCTIONS = + ImmutableSet.of( + CelFunctionDecl.newFunctionDeclaration( + Operator.OLD_NOT_STRICTLY_FALSE.getFunction(), + CelOverloadDecl.newGlobalOverload( + "not_strictly_false", + "false if argument is false, true otherwise (including errors and unknowns)", + SimpleType.BOOL, + SimpleType.BOOL)), + CelFunctionDecl.newFunctionDeclaration( + Operator.OLD_IN.getFunction(), + CelOverloadDecl.newGlobalOverload( + "in_list", "list membership", SimpleType.BOOL, TYPE_PARAM_A, LIST_OF_A), + CelOverloadDecl.newGlobalOverload( + "in_map", "map key membership", SimpleType.BOOL, TYPE_PARAM_A, MAP_OF_AB))); + + private static final ImmutableSet STANDARD_IDENTIFIERS = + stream(Identifier.values()).map(i -> i.identDecl).collect(toImmutableSet()); + + /** Enumeration of Standard Functions. */ + public enum Function { + // Internal (rewritten by macro) + IN(Operator.IN, Overload.Internal.IN_LIST, Overload.Internal.IN_MAP), + NOT_STRICTLY_FALSE(Operator.NOT_STRICTLY_FALSE, Overload.Internal.NOT_STRICTLY_FALSE), + + // Booleans + CONDITIONAL(Operator.CONDITIONAL, Overload.BooleanOperators.CONDITIONAL), + LOGICAL_NOT(Operator.LOGICAL_NOT, Overload.BooleanOperators.LOGICAL_NOT), + LOGICAL_OR(Operator.LOGICAL_OR, Overload.BooleanOperators.LOGICAL_OR), + LOGICAL_AND(Operator.LOGICAL_AND, Overload.BooleanOperators.LOGICAL_AND), + + EQUALS(Operator.EQUALS, Overload.Relation.EQUALS), + NOT_EQUALS(Operator.NOT_EQUALS, Overload.Relation.NOT_EQUALS), + ADD( + Operator.ADD, + Overload.Arithmetic.ADD_INT64, + Overload.Arithmetic.ADD_UINT64, + Overload.Arithmetic.ADD_DOUBLE, + Overload.Arithmetic.ADD_STRING, + Overload.Arithmetic.ADD_BYTES, + Overload.Arithmetic.ADD_LIST, + Overload.Arithmetic.ADD_TIMESTAMP_DURATION, + Overload.Arithmetic.ADD_DURATION_TIMESTAMP, + Overload.Arithmetic.ADD_DURATION_DURATION), + SUBTRACT( + Operator.SUBTRACT, + Overload.Arithmetic.SUBTRACT_INT64, + Overload.Arithmetic.SUBTRACT_UINT64, + Overload.Arithmetic.SUBTRACT_DOUBLE, + Overload.Arithmetic.SUBTRACT_TIMESTAMP_TIMESTAMP, + Overload.Arithmetic.SUBTRACT_TIMESTAMP_DURATION, + Overload.Arithmetic.SUBTRACT_DURATION_DURATION), + MULTIPLY( + Operator.MULTIPLY, + Overload.Arithmetic.MULTIPLY_INT64, + Overload.Arithmetic.MULTIPLY_UINT64, + Overload.Arithmetic.MULTIPLY_DOUBLE), + DIVIDE( + Operator.DIVIDE, + Overload.Arithmetic.DIVIDE_INT64, + Overload.Arithmetic.DIVIDE_UINT64, + Overload.Arithmetic.DIVIDE_DOUBLE), + MODULO(Operator.MODULO, Overload.Arithmetic.MODULO_INT64, Overload.Arithmetic.MODULO_UINT64), + + NEGATE(Operator.NEGATE, Overload.Arithmetic.NEGATE_INT64, Overload.Arithmetic.NEGATE_DOUBLE), + + INDEX(Operator.INDEX, Overload.Index.INDEX_LIST, Overload.Index.INDEX_MAP), + SIZE( + "size", + Overload.Size.SIZE_STRING, + Overload.Size.SIZE_BYTES, + Overload.Size.SIZE_LIST, + Overload.Size.SIZE_MAP, + Overload.Size.STRING_SIZE, + Overload.Size.BYTES_SIZE, + Overload.Size.LIST_SIZE, + Overload.Size.MAP_SIZE), + TYPE("type", Overload.Internal.TYPE), + INT( + "int", + Overload.Conversions.INT64_TO_INT64, + Overload.Conversions.UINT64_TO_INT64, + Overload.Conversions.DOUBLE_TO_INT64, + Overload.Conversions.STRING_TO_INT64, + Overload.Conversions.TIMESTAMP_TO_INT64), + UINT( + "uint", + Overload.Conversions.UINT64_TO_UINT64, + Overload.Conversions.INT64_TO_UINT64, + Overload.Conversions.DOUBLE_TO_UINT64, + Overload.Conversions.STRING_TO_UINT64), + DOUBLE( + "double", + Overload.Conversions.DOUBLE_TO_DOUBLE, + Overload.Conversions.INT64_TO_DOUBLE, + Overload.Conversions.UINT64_TO_DOUBLE, + Overload.Conversions.STRING_TO_DOUBLE), + STRING( + "string", + Overload.Conversions.STRING_TO_STRING, + Overload.Conversions.INT64_TO_STRING, + Overload.Conversions.UINT64_TO_STRING, + Overload.Conversions.DOUBLE_TO_STRING, + Overload.Conversions.BYTES_TO_STRING, + Overload.Conversions.TIMESTAMP_TO_STRING, + Overload.Conversions.DURATION_TO_STRING), + BYTES("bytes", Overload.Conversions.BYTES_TO_BYTES, Overload.Conversions.STRING_TO_BYTES), + DYN("dyn", Overload.Conversions.TO_DYN), + DURATION( + "duration", + Overload.Conversions.DURATION_TO_DURATION, + Overload.Conversions.STRING_TO_DURATION), + BOOL("bool", Overload.Conversions.BOOL_TO_BOOL, Overload.Conversions.STRING_TO_BOOL), + MATCHES("matches", Overload.StringMatchers.MATCHES, Overload.StringMatchers.MATCHES_STRING), + CONTAINS("contains", Overload.StringMatchers.CONTAINS_STRING), + ENDS_WITH("endsWith", Overload.StringMatchers.ENDS_WITH_STRING), + STARTS_WITH("startsWith", Overload.StringMatchers.STARTS_WITH_STRING), + TIMESTAMP( + "timestamp", + Overload.DateTime.STRING_TO_TIMESTAMP, + Overload.DateTime.TIMESTAMP_TO_TIMESTAMP, + Overload.DateTime.INT64_TO_TIMESTAMP), + GET_FULL_YEAR( + "getFullYear", + Overload.DateTime.TIMESTAMP_TO_YEAR, + Overload.DateTime.TIMESTAMP_TO_YEAR_WITH_TZ), + GET_MONTH( + "getMonth", + Overload.DateTime.TIMESTAMP_TO_MONTH, + Overload.DateTime.TIMESTAMP_TO_MONTH_WITH_TZ), + GET_DAY_OF_YEAR( + "getDayOfYear", + Overload.DateTime.TIMESTAMP_TO_DAY_OF_YEAR, + Overload.DateTime.TIMESTAMP_TO_DAY_OF_YEAR_WITH_TZ), + GET_DAY_OF_MONTH( + "getDayOfMonth", + Overload.DateTime.TIMESTAMP_TO_DAY_OF_MONTH, + Overload.DateTime.TIMESTAMP_TO_DAY_OF_MONTH_WITH_TZ), + GET_DATE( + "getDate", + Overload.DateTime.TIMESTAMP_TO_DAY_OF_MONTH_1_BASED, + Overload.DateTime.TIMESTAMP_TO_DAY_OF_MONTH_1_BASED_WITH_TZ), + GET_DAY_OF_WEEK( + "getDayOfWeek", + Overload.DateTime.TIMESTAMP_TO_DAY_OF_WEEK, + Overload.DateTime.TIMESTAMP_TO_DAY_OF_WEEK_WITH_TZ), + GET_HOURS( + "getHours", + Overload.DateTime.TIMESTAMP_TO_HOURS, + Overload.DateTime.TIMESTAMP_TO_HOURS_WITH_TZ, + Overload.DateTime.DURATION_TO_HOURS), + GET_MINUTES( + "getMinutes", + Overload.DateTime.TIMESTAMP_TO_MINUTES, + Overload.DateTime.TIMESTAMP_TO_MINUTES_WITH_TZ, + Overload.DateTime.DURATION_TO_MINUTES), + GET_SECONDS( + "getSeconds", + Overload.DateTime.TIMESTAMP_TO_SECONDS, + Overload.DateTime.TIMESTAMP_TO_SECONDS_WITH_TZ, + Overload.DateTime.DURATION_TO_SECONDS), + GET_MILLISECONDS( + "getMilliseconds", + Overload.DateTime.TIMESTAMP_TO_MILLISECONDS, + Overload.DateTime.TIMESTAMP_TO_MILLISECONDS_WITH_TZ, + Overload.DateTime.DURATION_TO_MILLISECONDS), + LESS( + Operator.LESS, + Overload.Comparison.LESS_BOOL, + Overload.Comparison.LESS_INT64, + Overload.Comparison.LESS_UINT64, + Overload.Comparison.LESS_DOUBLE, + Overload.Comparison.LESS_STRING, + Overload.Comparison.LESS_BYTES, + Overload.Comparison.LESS_TIMESTAMP, + Overload.Comparison.LESS_DURATION, + Overload.Comparison.LESS_INT64_UINT64, + Overload.Comparison.LESS_UINT64_INT64, + Overload.Comparison.LESS_INT64_DOUBLE, + Overload.Comparison.LESS_DOUBLE_INT64, + Overload.Comparison.LESS_UINT64_DOUBLE, + Overload.Comparison.LESS_DOUBLE_UINT64), + LESS_EQUALS( + Operator.LESS_EQUALS, + Overload.Comparison.LESS_EQUALS_BOOL, + Overload.Comparison.LESS_EQUALS_INT64, + Overload.Comparison.LESS_EQUALS_UINT64, + Overload.Comparison.LESS_EQUALS_DOUBLE, + Overload.Comparison.LESS_EQUALS_STRING, + Overload.Comparison.LESS_EQUALS_BYTES, + Overload.Comparison.LESS_EQUALS_TIMESTAMP, + Overload.Comparison.LESS_EQUALS_DURATION, + Overload.Comparison.LESS_EQUALS_INT64_UINT64, + Overload.Comparison.LESS_EQUALS_UINT64_INT64, + Overload.Comparison.LESS_EQUALS_INT64_DOUBLE, + Overload.Comparison.LESS_EQUALS_DOUBLE_INT64, + Overload.Comparison.LESS_EQUALS_UINT64_DOUBLE, + Overload.Comparison.LESS_EQUALS_DOUBLE_UINT64), + GREATER( + Operator.GREATER, + Overload.Comparison.GREATER_BOOL, + Overload.Comparison.GREATER_INT64, + Overload.Comparison.GREATER_UINT64, + Overload.Comparison.GREATER_DOUBLE, + Overload.Comparison.GREATER_STRING, + Overload.Comparison.GREATER_BYTES, + Overload.Comparison.GREATER_TIMESTAMP, + Overload.Comparison.GREATER_DURATION, + Overload.Comparison.GREATER_INT64_UINT64, + Overload.Comparison.GREATER_UINT64_INT64, + Overload.Comparison.GREATER_INT64_DOUBLE, + Overload.Comparison.GREATER_DOUBLE_INT64, + Overload.Comparison.GREATER_UINT64_DOUBLE, + Overload.Comparison.GREATER_DOUBLE_UINT64), + GREATER_EQUALS( + Operator.GREATER_EQUALS, + Overload.Comparison.GREATER_EQUALS_BOOL, + Overload.Comparison.GREATER_EQUALS_INT64, + Overload.Comparison.GREATER_EQUALS_UINT64, + Overload.Comparison.GREATER_EQUALS_DOUBLE, + Overload.Comparison.GREATER_EQUALS_STRING, + Overload.Comparison.GREATER_EQUALS_BYTES, + Overload.Comparison.GREATER_EQUALS_TIMESTAMP, + Overload.Comparison.GREATER_EQUALS_DURATION, + Overload.Comparison.GREATER_EQUALS_INT64_UINT64, + Overload.Comparison.GREATER_EQUALS_UINT64_INT64, + Overload.Comparison.GREATER_EQUALS_INT64_DOUBLE, + Overload.Comparison.GREATER_EQUALS_DOUBLE_INT64, + Overload.Comparison.GREATER_EQUALS_UINT64_DOUBLE, + Overload.Comparison.GREATER_EQUALS_DOUBLE_UINT64), + ; + + private final String functionName; + private final CelFunctionDecl celFunctionDecl; + + private static class Overload { + + enum Internal implements OverloadInterface { + IN_LIST( + CelOverloadDecl.newGlobalOverload( + "in_list", "list membership", SimpleType.BOOL, TYPE_PARAM_A, LIST_OF_A)), + IN_MAP( + CelOverloadDecl.newGlobalOverload( + "in_map", "map key membership", SimpleType.BOOL, TYPE_PARAM_A, MAP_OF_AB)), + NOT_STRICTLY_FALSE( + CelOverloadDecl.newGlobalOverload( + "not_strictly_false", + "false if argument is false, true otherwise (including errors and unknowns)", + SimpleType.BOOL, + SimpleType.BOOL)), + TYPE( + CelOverloadDecl.newGlobalOverload( + "type", "returns type of value", TypeType.create(TYPE_PARAM_A), TYPE_PARAM_A)), + ; + + private final CelOverloadDecl celOverloadDecl; + + Internal(CelOverloadDecl overloadDecl) { + this.celOverloadDecl = overloadDecl; + } + + @Override + public CelOverloadDecl celOverloadDecl() { + return this.celOverloadDecl; + } + } + + enum BooleanOperators implements OverloadInterface { + CONDITIONAL( + CelOverloadDecl.newGlobalOverload( + "conditional", + "conditional", + TYPE_PARAM_A, + SimpleType.BOOL, + TYPE_PARAM_A, + TYPE_PARAM_A)), + LOGICAL_NOT( + CelOverloadDecl.newGlobalOverload( + "logical_not", "logical not", SimpleType.BOOL, SimpleType.BOOL)), + LOGICAL_OR( + CelOverloadDecl.newGlobalOverload( + "logical_or", "logical or", SimpleType.BOOL, SimpleType.BOOL, SimpleType.BOOL)), + LOGICAL_AND( + CelOverloadDecl.newGlobalOverload( + "logical_and", "logical_and", SimpleType.BOOL, SimpleType.BOOL, SimpleType.BOOL)), + ; + + private final CelOverloadDecl celOverloadDecl; + + BooleanOperators(CelOverloadDecl overloadDecl) { + this.celOverloadDecl = overloadDecl; + } + + @Override + public CelOverloadDecl celOverloadDecl() { + return this.celOverloadDecl; + } + } + + enum Relation implements OverloadInterface { + EQUALS( + CelOverloadDecl.newGlobalOverload( + "equals", "equality", SimpleType.BOOL, TYPE_PARAM_A, TYPE_PARAM_A)), + NOT_EQUALS( + CelOverloadDecl.newGlobalOverload( + "not_equals", "inequality", SimpleType.BOOL, TYPE_PARAM_A, TYPE_PARAM_A)), + ; + private final CelOverloadDecl celOverloadDecl; + + Relation(CelOverloadDecl overloadDecl) { + this.celOverloadDecl = overloadDecl; + } + + @Override + public CelOverloadDecl celOverloadDecl() { + return this.celOverloadDecl; + } + } + + enum Arithmetic implements OverloadInterface { + + // Add + ADD_STRING( + CelOverloadDecl.newGlobalOverload( + "add_string", + "string concatenation", + SimpleType.STRING, + SimpleType.STRING, + SimpleType.STRING)), + ADD_BYTES( + CelOverloadDecl.newGlobalOverload( + "add_bytes", + "bytes concatenation", + SimpleType.BYTES, + SimpleType.BYTES, + SimpleType.BYTES)), + ADD_LIST( + CelOverloadDecl.newGlobalOverload( + "add_list", "list concatenation", LIST_OF_A, LIST_OF_A, LIST_OF_A)), + ADD_TIMESTAMP_DURATION( + CelOverloadDecl.newGlobalOverload( + "add_timestamp_duration", + "arithmetic", + SimpleType.TIMESTAMP, + SimpleType.TIMESTAMP, + SimpleType.DURATION)), + ADD_DURATION_TIMESTAMP( + CelOverloadDecl.newGlobalOverload( + "add_duration_timestamp", + "arithmetic", + SimpleType.TIMESTAMP, + SimpleType.DURATION, + SimpleType.TIMESTAMP)), + ADD_DURATION_DURATION( + CelOverloadDecl.newGlobalOverload( + "add_duration_duration", + "arithmetic", + SimpleType.DURATION, + SimpleType.DURATION, + SimpleType.DURATION)), + ADD_INT64( + CelOverloadDecl.newGlobalOverload( + "add_int64", "arithmetic", SimpleType.INT, SimpleType.INT, SimpleType.INT)), + ADD_UINT64( + CelOverloadDecl.newGlobalOverload( + "add_uint64", "arithmetic", SimpleType.UINT, SimpleType.UINT, SimpleType.UINT)), + ADD_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "add_double", + "arithmetic", + SimpleType.DOUBLE, + SimpleType.DOUBLE, + SimpleType.DOUBLE)), + + // Subtract + SUBTRACT_INT64( + CelOverloadDecl.newGlobalOverload( + "subtract_int64", "arithmetic", SimpleType.INT, SimpleType.INT, SimpleType.INT)), + SUBTRACT_UINT64( + CelOverloadDecl.newGlobalOverload( + "subtract_uint64", + "arithmetic", + SimpleType.UINT, + SimpleType.UINT, + SimpleType.UINT)), + SUBTRACT_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "subtract_double", + "arithmetic", + SimpleType.DOUBLE, + SimpleType.DOUBLE, + SimpleType.DOUBLE)), + SUBTRACT_TIMESTAMP_TIMESTAMP( + CelOverloadDecl.newGlobalOverload( + "subtract_timestamp_timestamp", + "arithmetic", + SimpleType.DURATION, + SimpleType.TIMESTAMP, + SimpleType.TIMESTAMP)), + SUBTRACT_TIMESTAMP_DURATION( + CelOverloadDecl.newGlobalOverload( + "subtract_timestamp_duration", + "arithmetic", + SimpleType.TIMESTAMP, + SimpleType.TIMESTAMP, + SimpleType.DURATION)), + SUBTRACT_DURATION_DURATION( + CelOverloadDecl.newGlobalOverload( + "subtract_duration_duration", + "arithmetic", + SimpleType.DURATION, + SimpleType.DURATION, + SimpleType.DURATION)), + + // Multiply + MULTIPLY_INT64( + CelOverloadDecl.newGlobalOverload( + "multiply_int64", "arithmetic", SimpleType.INT, SimpleType.INT, SimpleType.INT)), + MULTIPLY_UINT64( + CelOverloadDecl.newGlobalOverload( + "multiply_uint64", + "arithmetic", + SimpleType.UINT, + SimpleType.UINT, + SimpleType.UINT)), + MULTIPLY_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "multiply_double", + "arithmetic", + SimpleType.DOUBLE, + SimpleType.DOUBLE, + SimpleType.DOUBLE)), + + // Divide + DIVIDE_INT64( + CelOverloadDecl.newGlobalOverload( + "divide_int64", "arithmetic", SimpleType.INT, SimpleType.INT, SimpleType.INT)), + DIVIDE_UINT64( + CelOverloadDecl.newGlobalOverload( + "divide_uint64", "arithmetic", SimpleType.UINT, SimpleType.UINT, SimpleType.UINT)), + DIVIDE_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "divide_double", + "arithmetic", + SimpleType.DOUBLE, + SimpleType.DOUBLE, + SimpleType.DOUBLE)), + + // Modulo + MODULO_INT64( + CelOverloadDecl.newGlobalOverload( + "modulo_int64", "arithmetic", SimpleType.INT, SimpleType.INT, SimpleType.INT)), + MODULO_UINT64( + CelOverloadDecl.newGlobalOverload( + "modulo_uint64", "arithmetic", SimpleType.UINT, SimpleType.UINT, SimpleType.UINT)), + NEGATE_INT64( + CelOverloadDecl.newGlobalOverload( + "negate_int64", "negation", SimpleType.INT, SimpleType.INT)), + NEGATE_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "negate_double", "negation", SimpleType.DOUBLE, SimpleType.DOUBLE)), + ; + private final CelOverloadDecl celOverloadDecl; + + Arithmetic(CelOverloadDecl overloadDecl) { + this.celOverloadDecl = overloadDecl; + } + + @Override + public CelOverloadDecl celOverloadDecl() { + return this.celOverloadDecl; + } + } + + enum Index implements OverloadInterface { + INDEX_LIST( + CelOverloadDecl.newGlobalOverload( + "index_list", "list indexing", TYPE_PARAM_A, LIST_OF_A, SimpleType.INT)), + INDEX_MAP( + CelOverloadDecl.newGlobalOverload( + "index_map", "map indexing", TYPE_PARAM_B, MAP_OF_AB, TYPE_PARAM_A)), + ; + private final CelOverloadDecl celOverloadDecl; + + Index(CelOverloadDecl overloadDecl) { + this.celOverloadDecl = overloadDecl; + } + + @Override + public CelOverloadDecl celOverloadDecl() { + return this.celOverloadDecl; + } + } + + enum Size implements OverloadInterface { + SIZE_STRING( + CelOverloadDecl.newGlobalOverload( + "size_string", "string length", SimpleType.INT, SimpleType.STRING)), + SIZE_BYTES( + CelOverloadDecl.newGlobalOverload( + "size_bytes", "bytes length", SimpleType.INT, SimpleType.BYTES)), + SIZE_LIST( + CelOverloadDecl.newGlobalOverload("size_list", "list size", SimpleType.INT, LIST_OF_A)), + SIZE_MAP( + CelOverloadDecl.newGlobalOverload("size_map", "map size", SimpleType.INT, MAP_OF_AB)), + STRING_SIZE( + CelOverloadDecl.newMemberOverload( + "string_size", "string length", SimpleType.INT, SimpleType.STRING)), + BYTES_SIZE( + CelOverloadDecl.newMemberOverload( + "bytes_size", "bytes length", SimpleType.INT, SimpleType.BYTES)), + LIST_SIZE( + CelOverloadDecl.newMemberOverload("list_size", "list size", SimpleType.INT, LIST_OF_A)), + MAP_SIZE( + CelOverloadDecl.newMemberOverload("map_size", "map size", SimpleType.INT, MAP_OF_AB)), + ; + + private final CelOverloadDecl celOverloadDecl; + + Size(CelOverloadDecl overloadDecl) { + this.celOverloadDecl = overloadDecl; + } + + @Override + public CelOverloadDecl celOverloadDecl() { + return this.celOverloadDecl; + } + } + + enum Conversions implements OverloadInterface { + // Bool conversions + BOOL_TO_BOOL( + CelOverloadDecl.newGlobalOverload( + "bool_to_bool", "type conversion (identity)", SimpleType.BOOL, SimpleType.BOOL)), + STRING_TO_BOOL( + CelOverloadDecl.newGlobalOverload( + "string_to_bool", "type conversion", SimpleType.BOOL, SimpleType.STRING)), + + // Int conversions + INT64_TO_INT64( + CelOverloadDecl.newGlobalOverload( + "int64_to_int64", "type conversion (identity)", SimpleType.INT, SimpleType.INT)), + UINT64_TO_INT64( + CelOverloadDecl.newGlobalOverload( + "uint64_to_int64", "type conversion", SimpleType.INT, SimpleType.UINT)), + DOUBLE_TO_INT64( + CelOverloadDecl.newGlobalOverload( + "double_to_int64", "type conversion", SimpleType.INT, SimpleType.DOUBLE)), + STRING_TO_INT64( + CelOverloadDecl.newGlobalOverload( + "string_to_int64", "type conversion", SimpleType.INT, SimpleType.STRING)), + TIMESTAMP_TO_INT64( + CelOverloadDecl.newGlobalOverload( + "timestamp_to_int64", + "Convert timestamp to int64 in seconds since Unix epoch.", + SimpleType.INT, + SimpleType.TIMESTAMP)), + // Uint conversions + UINT64_TO_UINT64( + CelOverloadDecl.newGlobalOverload( + "uint64_to_uint64", + "type conversion (identity)", + SimpleType.UINT, + SimpleType.UINT)), + INT64_TO_UINT64( + CelOverloadDecl.newGlobalOverload( + "int64_to_uint64", "type conversion", SimpleType.UINT, SimpleType.INT)), + DOUBLE_TO_UINT64( + CelOverloadDecl.newGlobalOverload( + "double_to_uint64", "type conversion", SimpleType.UINT, SimpleType.DOUBLE)), + STRING_TO_UINT64( + CelOverloadDecl.newGlobalOverload( + "string_to_uint64", "type conversion", SimpleType.UINT, SimpleType.STRING)), + // Double conversions + DOUBLE_TO_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "double_to_double", + "type conversion (identity)", + SimpleType.DOUBLE, + SimpleType.DOUBLE)), + INT64_TO_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "int64_to_double", "type conversion", SimpleType.DOUBLE, SimpleType.INT)), + UINT64_TO_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "uint64_to_double", "type conversion", SimpleType.DOUBLE, SimpleType.UINT)), + STRING_TO_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "string_to_double", "type conversion", SimpleType.DOUBLE, SimpleType.STRING)), + // String conversions + STRING_TO_STRING( + CelOverloadDecl.newGlobalOverload( + "string_to_string", + "type conversion (identity)", + SimpleType.STRING, + SimpleType.STRING)), + INT64_TO_STRING( + CelOverloadDecl.newGlobalOverload( + "int64_to_string", "type conversion", SimpleType.STRING, SimpleType.INT)), + UINT64_TO_STRING( + CelOverloadDecl.newGlobalOverload( + "uint64_to_string", "type conversion", SimpleType.STRING, SimpleType.UINT)), + DOUBLE_TO_STRING( + CelOverloadDecl.newGlobalOverload( + "double_to_string", "type conversion", SimpleType.STRING, SimpleType.DOUBLE)), + BYTES_TO_STRING( + CelOverloadDecl.newGlobalOverload( + "bytes_to_string", "type conversion", SimpleType.STRING, SimpleType.BYTES)), + TIMESTAMP_TO_STRING( + CelOverloadDecl.newGlobalOverload( + "timestamp_to_string", "type_conversion", SimpleType.STRING, SimpleType.TIMESTAMP)), + DURATION_TO_STRING( + CelOverloadDecl.newGlobalOverload( + "duration_to_string", "type_conversion", SimpleType.STRING, SimpleType.DURATION)), + // Bytes conversions + BYTES_TO_BYTES( + CelOverloadDecl.newGlobalOverload( + "bytes_to_bytes", + "type conversion (identity)", + SimpleType.BYTES, + SimpleType.BYTES)), + STRING_TO_BYTES( + CelOverloadDecl.newGlobalOverload( + "string_to_bytes", "type conversion", SimpleType.BYTES, SimpleType.STRING)), + // Duration conversions + DURATION_TO_DURATION( + CelOverloadDecl.newGlobalOverload( + "duration_to_duration", + "type conversion (identity)", + SimpleType.DURATION, + SimpleType.DURATION)), + STRING_TO_DURATION( + CelOverloadDecl.newGlobalOverload( + "string_to_duration", + "type conversion, duration should be end with \"s\", which stands for seconds", + SimpleType.DURATION, + SimpleType.STRING)), + + // Dyn conversions + TO_DYN( + CelOverloadDecl.newGlobalOverload( + "to_dyn", "type conversion", SimpleType.DYN, TYPE_PARAM_A)), + ; + private final CelOverloadDecl celOverloadDecl; + + Conversions(CelOverloadDecl overloadDecl) { + this.celOverloadDecl = overloadDecl; + } + + @Override + public CelOverloadDecl celOverloadDecl() { + return this.celOverloadDecl; + } + } + + enum StringMatchers implements OverloadInterface { + MATCHES( + CelOverloadDecl.newGlobalOverload( + "matches", + "matches first argument against regular expression in second argument", + SimpleType.BOOL, + SimpleType.STRING, + SimpleType.STRING)), + + MATCHES_STRING( + CelOverloadDecl.newMemberOverload( + "matches_string", + "matches the self argument against regular expression in first argument", + SimpleType.BOOL, + SimpleType.STRING, + SimpleType.STRING)), + + CONTAINS_STRING( + CelOverloadDecl.newMemberOverload( + "contains_string", + "tests whether the string operand contains the substring", + SimpleType.BOOL, + SimpleType.STRING, + SimpleType.STRING)), + + ENDS_WITH_STRING( + CelOverloadDecl.newMemberOverload( + "ends_with_string", + "tests whether the string operand ends with the suffix argument", + SimpleType.BOOL, + SimpleType.STRING, + SimpleType.STRING)), + + STARTS_WITH_STRING( + CelOverloadDecl.newMemberOverload( + "starts_with_string", + "tests whether the string operand starts with the prefix argument", + SimpleType.BOOL, + SimpleType.STRING, + SimpleType.STRING)), + ; + private final CelOverloadDecl celOverloadDecl; + + StringMatchers(CelOverloadDecl overloadDecl) { + this.celOverloadDecl = overloadDecl; + } + + @Override + public CelOverloadDecl celOverloadDecl() { + return this.celOverloadDecl; + } + } + + enum DateTime implements OverloadInterface { + TIMESTAMP_TO_YEAR( + CelOverloadDecl.newMemberOverload( + "timestamp_to_year", + "get year from the date in UTC", + SimpleType.INT, + SimpleType.TIMESTAMP)), + TIMESTAMP_TO_YEAR_WITH_TZ( + CelOverloadDecl.newMemberOverload( + "timestamp_to_year_with_tz", + "get year from the date with timezone", + SimpleType.INT, + SimpleType.TIMESTAMP, + SimpleType.STRING)), + + TIMESTAMP_TO_MONTH( + CelOverloadDecl.newMemberOverload( + "timestamp_to_month", + "get month from the date in UTC, 0-11", + SimpleType.INT, + SimpleType.TIMESTAMP)), + + TIMESTAMP_TO_MONTH_WITH_TZ( + CelOverloadDecl.newMemberOverload( + "timestamp_to_month_with_tz", + "get month from the date with timezone, 0-11", + SimpleType.INT, + SimpleType.TIMESTAMP, + SimpleType.STRING)), + + TIMESTAMP_TO_DAY_OF_YEAR( + CelOverloadDecl.newMemberOverload( + "timestamp_to_day_of_year", + "get day of year from the date in UTC, zero-based indexing", + SimpleType.INT, + SimpleType.TIMESTAMP)), + + TIMESTAMP_TO_DAY_OF_YEAR_WITH_TZ( + CelOverloadDecl.newMemberOverload( + "timestamp_to_day_of_year_with_tz", + "get day of year from the date with timezone, zero-based indexing", + SimpleType.INT, + SimpleType.TIMESTAMP, + SimpleType.STRING)), + + TIMESTAMP_TO_DAY_OF_MONTH( + CelOverloadDecl.newMemberOverload( + "timestamp_to_day_of_month", + "get day of month from the date in UTC, zero-based indexing", + SimpleType.INT, + SimpleType.TIMESTAMP)), + + TIMESTAMP_TO_DAY_OF_MONTH_WITH_TZ( + CelOverloadDecl.newMemberOverload( + "timestamp_to_day_of_month_with_tz", + "get day of month from the date with timezone, zero-based indexing", + SimpleType.INT, + SimpleType.TIMESTAMP, + SimpleType.STRING)), + + TIMESTAMP_TO_DAY_OF_MONTH_1_BASED( + CelOverloadDecl.newMemberOverload( + "timestamp_to_day_of_month_1_based", + "get day of month from the date in UTC, one-based indexing", + SimpleType.INT, + SimpleType.TIMESTAMP)), + TIMESTAMP_TO_DAY_OF_MONTH_1_BASED_WITH_TZ( + CelOverloadDecl.newMemberOverload( + "timestamp_to_day_of_month_1_based_with_tz", + "get day of month from the date with timezone, one-based indexing", + SimpleType.INT, + SimpleType.TIMESTAMP, + SimpleType.STRING)), + + TIMESTAMP_TO_DAY_OF_WEEK( + CelOverloadDecl.newMemberOverload( + "timestamp_to_day_of_week", + "get day of week from the date in UTC, zero-based, zero for Sunday", + SimpleType.INT, + SimpleType.TIMESTAMP)), + + TIMESTAMP_TO_DAY_OF_WEEK_WITH_TZ( + CelOverloadDecl.newMemberOverload( + "timestamp_to_day_of_week_with_tz", + "get day of week from the date with timezone, zero-based, zero for Sunday", + SimpleType.INT, + SimpleType.TIMESTAMP, + SimpleType.STRING)), + + TIMESTAMP_TO_HOURS( + CelOverloadDecl.newMemberOverload( + "timestamp_to_hours", + "get hours from the date in UTC, 0-23", + SimpleType.INT, + SimpleType.TIMESTAMP)), + + TIMESTAMP_TO_HOURS_WITH_TZ( + CelOverloadDecl.newMemberOverload( + "timestamp_to_hours_with_tz", + "get hours from the date with timezone, 0-23", + SimpleType.INT, + SimpleType.TIMESTAMP, + SimpleType.STRING)), + + DURATION_TO_HOURS( + CelOverloadDecl.newMemberOverload( + "duration_to_hours", + "get hours from duration", + SimpleType.INT, + SimpleType.DURATION)), + TIMESTAMP_TO_MINUTES( + CelOverloadDecl.newMemberOverload( + "timestamp_to_minutes", + "get minutes from the date in UTC, 0-59", + SimpleType.INT, + SimpleType.TIMESTAMP)), + + TIMESTAMP_TO_MINUTES_WITH_TZ( + CelOverloadDecl.newMemberOverload( + "timestamp_to_minutes_with_tz", + "get minutes from the date with timezone, 0-59", + SimpleType.INT, + SimpleType.TIMESTAMP, + SimpleType.STRING)), + + DURATION_TO_MINUTES( + CelOverloadDecl.newMemberOverload( + "duration_to_minutes", + "get minutes from duration", + SimpleType.INT, + SimpleType.DURATION)), + TIMESTAMP_TO_SECONDS( + CelOverloadDecl.newMemberOverload( + "timestamp_to_seconds", + "get seconds from the date in UTC, 0-59", + SimpleType.INT, + SimpleType.TIMESTAMP)), + + TIMESTAMP_TO_SECONDS_WITH_TZ( + CelOverloadDecl.newMemberOverload( + "timestamp_to_seconds_with_tz", + "get seconds from the date with timezone, 0-59", + SimpleType.INT, + SimpleType.TIMESTAMP, + SimpleType.STRING)), + + DURATION_TO_SECONDS( + CelOverloadDecl.newMemberOverload( + "duration_to_seconds", + "get seconds from duration", + SimpleType.INT, + SimpleType.DURATION)), + TIMESTAMP_TO_MILLISECONDS( + CelOverloadDecl.newMemberOverload( + "timestamp_to_milliseconds", + "get milliseconds from the date in UTC, 0-999", + SimpleType.INT, + SimpleType.TIMESTAMP)), + + TIMESTAMP_TO_MILLISECONDS_WITH_TZ( + CelOverloadDecl.newMemberOverload( + "timestamp_to_milliseconds_with_tz", + "get milliseconds from the date with timezone, 0-999", + SimpleType.INT, + SimpleType.TIMESTAMP, + SimpleType.STRING)), + + DURATION_TO_MILLISECONDS( + CelOverloadDecl.newMemberOverload( + "duration_to_milliseconds", + "milliseconds from duration, 0-999", + SimpleType.INT, + SimpleType.DURATION)), + STRING_TO_TIMESTAMP( + CelOverloadDecl.newGlobalOverload( + "string_to_timestamp", + "Type conversion of strings to timestamps according to RFC3339. Example:" + + " \"1972-01-01T10:00:20.021-05:00\".", + SimpleType.TIMESTAMP, + SimpleType.STRING)), + TIMESTAMP_TO_TIMESTAMP( + CelOverloadDecl.newGlobalOverload( + "timestamp_to_timestamp", + "type conversion (identity)", + SimpleType.TIMESTAMP, + SimpleType.TIMESTAMP)), + INT64_TO_TIMESTAMP( + CelOverloadDecl.newGlobalOverload( + "int64_to_timestamp", + "Type conversion of integers as Unix epoch seconds to timestamps.", + SimpleType.TIMESTAMP, + SimpleType.INT)), + ; + private final CelOverloadDecl celOverloadDecl; + + DateTime(CelOverloadDecl overloadDecl) { + this.celOverloadDecl = overloadDecl; + } + + @Override + public CelOverloadDecl celOverloadDecl() { + return this.celOverloadDecl; + } + } + + enum Comparison implements OverloadInterface { + // Less + LESS_BOOL( + CelOverloadDecl.newGlobalOverload( + "less_bool", "ordering", SimpleType.BOOL, SimpleType.BOOL, SimpleType.BOOL)), + LESS_INT64( + CelOverloadDecl.newGlobalOverload( + "less_int64", "ordering", SimpleType.BOOL, SimpleType.INT, SimpleType.INT)), + LESS_UINT64( + CelOverloadDecl.newGlobalOverload( + "less_uint64", "ordering", SimpleType.BOOL, SimpleType.UINT, SimpleType.UINT)), + LESS_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "less_double", "ordering", SimpleType.BOOL, SimpleType.DOUBLE, SimpleType.DOUBLE)), + LESS_STRING( + CelOverloadDecl.newGlobalOverload( + "less_string", "ordering", SimpleType.BOOL, SimpleType.STRING, SimpleType.STRING)), + LESS_BYTES( + CelOverloadDecl.newGlobalOverload( + "less_bytes", "ordering", SimpleType.BOOL, SimpleType.BYTES, SimpleType.BYTES)), + LESS_TIMESTAMP( + CelOverloadDecl.newGlobalOverload( + "less_timestamp", + "ordering", + SimpleType.BOOL, + SimpleType.TIMESTAMP, + SimpleType.TIMESTAMP)), + LESS_DURATION( + CelOverloadDecl.newGlobalOverload( + "less_duration", + "ordering", + SimpleType.BOOL, + SimpleType.DURATION, + SimpleType.DURATION)), + LESS_INT64_UINT64( + CelOverloadDecl.newGlobalOverload( + "less_int64_uint64", + "Compare a signed integer value to an unsigned integer value", + SimpleType.BOOL, + SimpleType.INT, + SimpleType.UINT)), + LESS_UINT64_INT64( + CelOverloadDecl.newGlobalOverload( + "less_uint64_int64", + "Compare an unsigned integer value to a signed integer value", + SimpleType.BOOL, + SimpleType.UINT, + SimpleType.INT)), + LESS_INT64_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "less_int64_double", + "Compare a signed integer value to a double value, coalesces the integer to a" + + " double", + SimpleType.BOOL, + SimpleType.INT, + SimpleType.DOUBLE)), + LESS_DOUBLE_INT64( + CelOverloadDecl.newGlobalOverload( + "less_double_int64", + "Compare a double value to a signed integer value, coalesces the integer to a" + + " double", + SimpleType.BOOL, + SimpleType.DOUBLE, + SimpleType.INT)), + LESS_UINT64_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "less_uint64_double", + "Compare an unsigned integer value to a double value, coalesces the unsigned" + + " integer to a double", + SimpleType.BOOL, + SimpleType.UINT, + SimpleType.DOUBLE)), + LESS_DOUBLE_UINT64( + CelOverloadDecl.newGlobalOverload( + "less_double_uint64", + "Compare a double value to an unsigned integer value, coalesces the unsigned" + + " integer to a double", + SimpleType.BOOL, + SimpleType.DOUBLE, + SimpleType.UINT)), + // Less Equals + LESS_EQUALS_BOOL( + Comparison.LESS_BOOL.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_BOOL + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_INT64( + Comparison.LESS_INT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_INT64 + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_UINT64( + Comparison.LESS_UINT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_UINT64 + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_DOUBLE( + Comparison.LESS_DOUBLE.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_DOUBLE + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_STRING( + Comparison.LESS_STRING.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_STRING + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_BYTES( + Comparison.LESS_BYTES.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_BYTES + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_TIMESTAMP( + Comparison.LESS_TIMESTAMP.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_TIMESTAMP + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_DURATION( + Comparison.LESS_DURATION.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_DURATION + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_INT64_UINT64( + Comparison.LESS_INT64_UINT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_INT64_UINT64 + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_UINT64_INT64( + Comparison.LESS_UINT64_INT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_UINT64_INT64 + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_INT64_DOUBLE( + Comparison.LESS_INT64_DOUBLE.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_INT64_DOUBLE + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_DOUBLE_INT64( + Comparison.LESS_DOUBLE_INT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_DOUBLE_INT64 + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_UINT64_DOUBLE( + Comparison.LESS_UINT64_DOUBLE.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_UINT64_DOUBLE + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + LESS_EQUALS_DOUBLE_UINT64( + Comparison.LESS_DOUBLE_UINT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_DOUBLE_UINT64 + .celOverloadDecl + .overloadId() + .replace("less", "less_equals")) + .build()), + + // Greater + GREATER_BOOL( + CelOverloadDecl.newGlobalOverload( + "greater_bool", "ordering", SimpleType.BOOL, SimpleType.BOOL, SimpleType.BOOL)), + GREATER_INT64( + CelOverloadDecl.newGlobalOverload( + "greater_int64", "ordering", SimpleType.BOOL, SimpleType.INT, SimpleType.INT)), + GREATER_UINT64( + CelOverloadDecl.newGlobalOverload( + "greater_uint64", "ordering", SimpleType.BOOL, SimpleType.UINT, SimpleType.UINT)), + GREATER_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "greater_double", + "ordering", + SimpleType.BOOL, + SimpleType.DOUBLE, + SimpleType.DOUBLE)), + GREATER_STRING( + CelOverloadDecl.newGlobalOverload( + "greater_string", + "ordering", + SimpleType.BOOL, + SimpleType.STRING, + SimpleType.STRING)), + GREATER_BYTES( + CelOverloadDecl.newGlobalOverload( + "greater_bytes", "ordering", SimpleType.BOOL, SimpleType.BYTES, SimpleType.BYTES)), + GREATER_TIMESTAMP( + CelOverloadDecl.newGlobalOverload( + "greater_timestamp", + "ordering", + SimpleType.BOOL, + SimpleType.TIMESTAMP, + SimpleType.TIMESTAMP)), + GREATER_DURATION( + CelOverloadDecl.newGlobalOverload( + "greater_duration", + "ordering", + SimpleType.BOOL, + SimpleType.DURATION, + SimpleType.DURATION)), + GREATER_INT64_UINT64( + CelOverloadDecl.newGlobalOverload( + "greater_int64_uint64", + "Compare a signed integer value to an unsigned integer value", + SimpleType.BOOL, + SimpleType.INT, + SimpleType.UINT)), + GREATER_UINT64_INT64( + CelOverloadDecl.newGlobalOverload( + "greater_uint64_int64", + "Compare an unsigned integer value to a signed integer value", + SimpleType.BOOL, + SimpleType.UINT, + SimpleType.INT)), + GREATER_INT64_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "greater_int64_double", + "Compare a signed integer value to a double value, coalesces the integer to a" + + " double", + SimpleType.BOOL, + SimpleType.INT, + SimpleType.DOUBLE)), + GREATER_DOUBLE_INT64( + CelOverloadDecl.newGlobalOverload( + "greater_double_int64", + "Compare a double value to a signed integer value, coalesces the integer to a" + + " double", + SimpleType.BOOL, + SimpleType.DOUBLE, + SimpleType.INT)), + GREATER_UINT64_DOUBLE( + CelOverloadDecl.newGlobalOverload( + "greater_uint64_double", + "Compare an unsigned integer value to a double value, coalesces the unsigned" + + " integer to a double", + SimpleType.BOOL, + SimpleType.UINT, + SimpleType.DOUBLE)), + GREATER_DOUBLE_UINT64( + CelOverloadDecl.newGlobalOverload( + "greater_double_uint64", + "Compare a double value to an unsigned integer value, coalesces the unsigned" + + " integer to a double", + SimpleType.BOOL, + SimpleType.DOUBLE, + SimpleType.UINT)), + + // Greater Equals + GREATER_EQUALS_BOOL( + Comparison.LESS_BOOL.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_BOOL + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_INT64( + Comparison.LESS_INT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_INT64 + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_UINT64( + Comparison.LESS_UINT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_UINT64 + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_DOUBLE( + Comparison.LESS_DOUBLE.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_DOUBLE + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_STRING( + Comparison.LESS_STRING.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_STRING + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_BYTES( + Comparison.LESS_BYTES.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_BYTES + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_TIMESTAMP( + Comparison.LESS_TIMESTAMP.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_TIMESTAMP + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_DURATION( + Comparison.LESS_DURATION.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_DURATION + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_INT64_UINT64( + Comparison.LESS_INT64_UINT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_INT64_UINT64 + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_UINT64_INT64( + Comparison.LESS_UINT64_INT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_UINT64_INT64 + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_INT64_DOUBLE( + Comparison.LESS_INT64_DOUBLE.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_INT64_DOUBLE + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_DOUBLE_INT64( + Comparison.LESS_DOUBLE_INT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_DOUBLE_INT64 + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_UINT64_DOUBLE( + Comparison.LESS_UINT64_DOUBLE.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_UINT64_DOUBLE + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + GREATER_EQUALS_DOUBLE_UINT64( + Comparison.LESS_DOUBLE_UINT64.celOverloadDecl.toBuilder() + .setOverloadId( + Comparison.LESS_DOUBLE_UINT64 + .celOverloadDecl + .overloadId() + .replace("less", "greater_equals")) + .build()), + ; + + private final CelOverloadDecl celOverloadDecl; + + Comparison(CelOverloadDecl overloadDecl) { + this.celOverloadDecl = overloadDecl; + } + + @Override + public CelOverloadDecl celOverloadDecl() { + return this.celOverloadDecl; + } + } + + private Overload() {} + } + + public String functionName() { + return functionName; + } + + Function(Operator operator, OverloadInterface... overloads) { + this(operator.getFunction(), overloads); + } + + Function(String functionName, OverloadInterface... overloads) { + this.functionName = functionName; + ImmutableSet overloads1 = ImmutableSet.copyOf(overloads); + this.celFunctionDecl = + CelFunctionDecl.newFunctionDeclaration( + functionName, + overloads1.stream() + .map(OverloadInterface::celOverloadDecl) + .collect(toImmutableSet())); + } + } + + enum Identifier { + INT(newStandardIdentDecl(SimpleType.INT)), + UINT(newStandardIdentDecl(SimpleType.UINT)), + BOOL(newStandardIdentDecl(SimpleType.BOOL)), + DOUBLE(newStandardIdentDecl(SimpleType.DOUBLE)), + BYTES(newStandardIdentDecl(SimpleType.BYTES)), + STRING(newStandardIdentDecl(SimpleType.STRING)), + DYN(newStandardIdentDecl(SimpleType.DYN)), + TYPE(newStandardIdentDecl("type", SimpleType.DYN)), + NULL_TYPE(newStandardIdentDecl("null_type", SimpleType.NULL_TYPE)), + LIST(newStandardIdentDecl("list", ListType.create(SimpleType.DYN))), + MAP(newStandardIdentDecl("map", MapType.create(SimpleType.DYN, SimpleType.DYN))), + ; + + private static CelIdentDecl newStandardIdentDecl(CelType celType) { + return newStandardIdentDecl(CelTypes.format(celType), celType); + } + + private static CelIdentDecl newStandardIdentDecl(String identName, CelType celType) { + return CelIdentDecl.newBuilder() + .setName(identName) + .setType(TypeType.create(celType)) + .setDoc("type denotation") + .build(); + } + + private final CelIdentDecl identDecl; + + Identifier(CelIdentDecl identDecl) { + this.identDecl = identDecl; + } + } + + @Immutable + private interface OverloadInterface { + CelOverloadDecl celOverloadDecl(); + } + + /** Set of all standard functions. */ + public static ImmutableSet functions() { + return STANDARD_FUNCTIONS; + } + + /** Set of all standard function names. */ + public static ImmutableSet getAllFunctionNames() { + return STANDARD_FUNCTIONS.stream().map(CelFunctionDecl::name).collect(toImmutableSet()); + } + + /** Set of all standard identifiers. */ + public static ImmutableSet identifiers() { + return STANDARD_IDENTIFIERS; + } + + /** + * Deprecated standard functions maintained for backward compatibility reasons. + * + *

Note: Keep this package-private. + */ + static ImmutableSet deprecatedFunctions() { + return DEPRECATED_STANDARD_FUNCTIONS; + } + + private CelStandardDeclaration() {} +} diff --git a/checker/src/main/java/dev/cel/checker/Env.java b/checker/src/main/java/dev/cel/checker/Env.java index 613bef16..d15708e7 100644 --- a/checker/src/main/java/dev/cel/checker/Env.java +++ b/checker/src/main/java/dev/cel/checker/Env.java @@ -221,7 +221,10 @@ public static Env standard(Errors errors, CelOptions celOptions) { public static Env standard(Errors errors, TypeProvider typeProvider, CelOptions celOptions) { Env env = Env.unconfigured(errors, typeProvider, celOptions); // Isolate the standard declarations into their own scope for forward compatibility. - Standard.add(env); + CelStandardDeclaration.deprecatedFunctions().forEach(env::add); + CelStandardDeclaration.functions().forEach(env::add); + CelStandardDeclaration.identifiers().forEach(env::add); + env.enterScope(); return env; } diff --git a/checker/src/main/java/dev/cel/checker/Standard.java b/checker/src/main/java/dev/cel/checker/Standard.java deleted file mode 100644 index acdc185e..00000000 --- a/checker/src/main/java/dev/cel/checker/Standard.java +++ /dev/null @@ -1,846 +0,0 @@ -// Copyright 2023 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.checker; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.errorprone.annotations.CanIgnoreReturnValue; -import dev.cel.common.CelFunctionDecl; -import dev.cel.common.CelOverloadDecl; -import dev.cel.common.annotations.Internal; -import dev.cel.common.types.CelType; -import dev.cel.common.types.CelTypes; -import dev.cel.common.types.ListType; -import dev.cel.common.types.MapType; -import dev.cel.common.types.SimpleType; -import dev.cel.common.types.TypeParamType; -import dev.cel.common.types.TypeType; -import dev.cel.parser.Operator; - -/** - * Standard declarations for CEL. - * - *

CEL Library Internals. Do Not Use. - */ -@Internal -public final class Standard { - - private static final ImmutableList CORE_FUNCTION_DECLARATIONS = - coreFunctionDeclarations(); - private static final ImmutableList CORE_IDENT_DECLARATIONS = - coreIdentDeclarations(); - - /** Enumeration of Standard Functions that are not present in {@link Operator}). */ - public enum Function { - BOOL("bool"), - BYTES("bytes"), - CONTAINS("contains"), - DOUBLE("double"), - DURATION("duration"), - DYN("dyn"), - ENDS_WITH("endsWith"), - GET_DATE("getDate"), - GET_DAY_OF_MONTH("getDayOfMonth"), - GET_DAY_OF_WEEK("getDayOfWeek"), - GET_DAY_OF_YEAR("getDayOfYear"), - GET_FULL_YEAR("getFullYear"), - GET_HOURS("getHours"), - GET_MILLISECONDS("getMilliseconds"), - GET_MINUTES("getMinutes"), - GET_MONTH("getMonth"), - GET_SECONDS("getSeconds"), - INT("int"), - LIST("list"), - MAP("map"), - MATCHES("matches"), - NULL_TYPE("null_type"), - SIZE("size"), - STARTS_WITH("startsWith"), - STRING("string"), - TIMESTAMP("timestamp"), - TYPE("type"), - UINT("uint"); - - private final String functionName; - - public String getFunction() { - return functionName; - } - - Function(String functionName) { - this.functionName = functionName; - } - } - - /** - * Adds the standard declarations of CEL to the environment. - * - *

Note: Standard declarations should be provided in their own scope to avoid collisions with - * custom declarations. The {@link Env#standard} helper method does this by default. - */ - @CanIgnoreReturnValue - public static Env add(Env env) { - CORE_FUNCTION_DECLARATIONS.forEach(env::add); - CORE_IDENT_DECLARATIONS.forEach(env::add); - - // TODO: Remove this flag guard once the feature has been auto-enabled. - timestampConversionDeclarations(env.enableTimestampEpoch()).forEach(env::add); - numericComparisonDeclarations(env.enableHeterogeneousNumericComparisons()).forEach(env::add); - - if (env.enableUnsignedLongs()) { - env.add( - CelFunctionDecl.newFunctionDeclaration( - Function.INT.getFunction(), - CelOverloadDecl.newGlobalOverload( - "int64_to_int64", "type conversion (identity)", SimpleType.INT, SimpleType.INT))); - } - - return env; - } - - /** Do the expensive work of setting up all the objects in the environment. */ - private static ImmutableList coreIdentDeclarations() { - ImmutableList.Builder identDeclBuilder = ImmutableList.builder(); - - // Type Denotations - for (CelType type : - ImmutableList.of( - SimpleType.INT, - SimpleType.UINT, - SimpleType.BOOL, - SimpleType.DOUBLE, - SimpleType.BYTES, - SimpleType.STRING, - SimpleType.DYN)) { - identDeclBuilder.add( - CelIdentDecl.newBuilder() - .setName(CelTypes.format(type)) - .setType(TypeType.create(type)) - .setDoc("type denotation") - .build()); - } - identDeclBuilder.add( - CelIdentDecl.newBuilder() - .setName("type") - .setType(TypeType.create(SimpleType.DYN)) - .setDoc("type denotation") - .build()); - identDeclBuilder.add( - CelIdentDecl.newBuilder() - .setName("null_type") - .setType(TypeType.create(SimpleType.NULL_TYPE)) - .setDoc("type denotation") - .build()); - identDeclBuilder.add( - CelIdentDecl.newBuilder() - .setName("list") - .setType(TypeType.create(ListType.create(SimpleType.DYN))) - .setDoc("type denotation") - .build()); - identDeclBuilder.add( - CelIdentDecl.newBuilder() - .setName("map") - .setType(TypeType.create(MapType.create(SimpleType.DYN, SimpleType.DYN))) - .setDoc("type denotation") - .build()); - - return identDeclBuilder.build(); - } - - /** Do the expensive work of setting up all the objects in the environment. */ - private static ImmutableList coreFunctionDeclarations() { - // Some shortcuts we use when building declarations. - TypeParamType typeParamA = TypeParamType.create("A"); - ListType listOfA = ListType.create(typeParamA); - TypeParamType typeParamB = TypeParamType.create("B"); - MapType mapOfAb = MapType.create(typeParamA, typeParamB); - - ImmutableList.Builder celFunctionDeclBuilder = ImmutableList.builder(); - - // Booleans - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Operator.CONDITIONAL.getFunction(), - CelOverloadDecl.newGlobalOverload( - "conditional", - "conditional", - typeParamA, - SimpleType.BOOL, - typeParamA, - typeParamA))); - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Operator.LOGICAL_AND.getFunction(), - CelOverloadDecl.newGlobalOverload( - "logical_and", "logical_and", SimpleType.BOOL, SimpleType.BOOL, SimpleType.BOOL))); - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Operator.LOGICAL_OR.getFunction(), - CelOverloadDecl.newGlobalOverload( - "logical_or", "logical or", SimpleType.BOOL, SimpleType.BOOL, SimpleType.BOOL))); - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Operator.LOGICAL_NOT.getFunction(), - CelOverloadDecl.newGlobalOverload( - "logical_not", "logical not", SimpleType.BOOL, SimpleType.BOOL))); - CelFunctionDecl notStrictlyFalse = - CelFunctionDecl.newFunctionDeclaration( - Operator.OLD_NOT_STRICTLY_FALSE.getFunction(), - CelOverloadDecl.newGlobalOverload( - "not_strictly_false", - "false if argument is false, true otherwise (including errors and unknowns)", - SimpleType.BOOL, - SimpleType.BOOL)); - celFunctionDeclBuilder.add(notStrictlyFalse); - celFunctionDeclBuilder.add( - CelFunctionDecl.newBuilder() - .setName(Operator.NOT_STRICTLY_FALSE.getFunction()) - .addOverloads(sameAs(notStrictlyFalse, "", "")) - .build()); - - // Relations - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Operator.EQUALS.getFunction(), - CelOverloadDecl.newGlobalOverload( - "equals", "equality", SimpleType.BOOL, typeParamA, typeParamA))); - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Operator.NOT_EQUALS.getFunction(), - CelOverloadDecl.newGlobalOverload( - "not_equals", "inequality", SimpleType.BOOL, typeParamA, typeParamA))); - - // Algebra - CelFunctionDecl commonArithmetic = - CelFunctionDecl.newFunctionDeclaration( - Operator.SUBTRACT.getFunction(), - CelOverloadDecl.newGlobalOverload( - "common_int64", "arithmetic", SimpleType.INT, SimpleType.INT, SimpleType.INT), - CelOverloadDecl.newGlobalOverload( - "common_uint64", "arithmetic", SimpleType.UINT, SimpleType.UINT, SimpleType.UINT), - CelOverloadDecl.newGlobalOverload( - "common_double", - "arithmetic", - SimpleType.DOUBLE, - SimpleType.DOUBLE, - SimpleType.DOUBLE)); - CelFunctionDecl subtract = - CelFunctionDecl.newBuilder() - .setName(Operator.SUBTRACT.getFunction()) - .addOverloads(sameAs(commonArithmetic, "common", "subtract")) - .addOverloads( - CelOverloadDecl.newGlobalOverload( - "subtract_timestamp_timestamp", - "arithmetic", - SimpleType.DURATION, - SimpleType.TIMESTAMP, - SimpleType.TIMESTAMP), - CelOverloadDecl.newGlobalOverload( - "subtract_timestamp_duration", - "arithmetic", - SimpleType.TIMESTAMP, - SimpleType.TIMESTAMP, - SimpleType.DURATION), - CelOverloadDecl.newGlobalOverload( - "subtract_duration_duration", - "arithmetic", - SimpleType.DURATION, - SimpleType.DURATION, - SimpleType.DURATION)) - .build(); - celFunctionDeclBuilder.add(subtract); - celFunctionDeclBuilder.add( - CelFunctionDecl.newBuilder() - .setName(Operator.MULTIPLY.getFunction()) - .addOverloads(sameAs(commonArithmetic, "common", "multiply")) - .build()); - celFunctionDeclBuilder.add( - CelFunctionDecl.newBuilder() - .setName(Operator.DIVIDE.getFunction()) - .addOverloads(sameAs(commonArithmetic, "common", "divide")) - .build()); - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Operator.MODULO.getFunction(), - CelOverloadDecl.newGlobalOverload( - "modulo_int64", "arithmetic", SimpleType.INT, SimpleType.INT, SimpleType.INT), - CelOverloadDecl.newGlobalOverload( - "modulo_uint64", "arithmetic", SimpleType.UINT, SimpleType.UINT, SimpleType.UINT))); - celFunctionDeclBuilder.add( - CelFunctionDecl.newBuilder() - .setName(Operator.ADD.getFunction()) - .addOverloads(sameAs(commonArithmetic, "common", "add")) - .addOverloads( - CelOverloadDecl.newGlobalOverload( - "add_string", - "string concatenation", - SimpleType.STRING, - SimpleType.STRING, - SimpleType.STRING), - CelOverloadDecl.newGlobalOverload( - "add_bytes", - "bytes concatenation", - SimpleType.BYTES, - SimpleType.BYTES, - SimpleType.BYTES), - CelOverloadDecl.newGlobalOverload( - "add_list", "list concatenation", listOfA, listOfA, listOfA), - CelOverloadDecl.newGlobalOverload( - "add_timestamp_duration", - "arithmetic", - SimpleType.TIMESTAMP, - SimpleType.TIMESTAMP, - SimpleType.DURATION), - CelOverloadDecl.newGlobalOverload( - "add_duration_timestamp", - "arithmetic", - SimpleType.TIMESTAMP, - SimpleType.DURATION, - SimpleType.TIMESTAMP), - CelOverloadDecl.newGlobalOverload( - "add_duration_duration", - "arithmetic", - SimpleType.DURATION, - SimpleType.DURATION, - SimpleType.DURATION)) - .build()); - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Operator.NEGATE.getFunction(), - CelOverloadDecl.newGlobalOverload( - "negate_int64", "negation", SimpleType.INT, SimpleType.INT), - CelOverloadDecl.newGlobalOverload( - "negate_double", "negation", SimpleType.DOUBLE, SimpleType.DOUBLE))); - - // Index - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Operator.INDEX.getFunction(), - CelOverloadDecl.newGlobalOverload( - "index_list", "list indexing", typeParamA, listOfA, SimpleType.INT), - CelOverloadDecl.newGlobalOverload( - "index_map", "map indexing", typeParamB, mapOfAb, typeParamA))); - - // Collections - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - "size", - CelOverloadDecl.newGlobalOverload( - "size_string", "string length", SimpleType.INT, SimpleType.STRING), - CelOverloadDecl.newGlobalOverload( - "size_bytes", "bytes length", SimpleType.INT, SimpleType.BYTES), - CelOverloadDecl.newGlobalOverload("size_list", "list size", SimpleType.INT, listOfA), - CelOverloadDecl.newGlobalOverload("size_map", "map size", SimpleType.INT, mapOfAb), - CelOverloadDecl.newMemberOverload( - "string_size", "string length", SimpleType.INT, SimpleType.STRING), - CelOverloadDecl.newMemberOverload( - "bytes_size", "bytes length", SimpleType.INT, SimpleType.BYTES), - CelOverloadDecl.newMemberOverload("list_size", "list size", SimpleType.INT, listOfA), - CelOverloadDecl.newMemberOverload("map_size", "map size", SimpleType.INT, mapOfAb))); - - // Set membership 'in' operator. - CelFunctionDecl inOperator = - CelFunctionDecl.newFunctionDeclaration( - Operator.OLD_IN.getFunction(), - CelOverloadDecl.newGlobalOverload( - "in_list", "list membership", SimpleType.BOOL, typeParamA, listOfA), - CelOverloadDecl.newGlobalOverload( - "in_map", "map key membership", SimpleType.BOOL, typeParamA, mapOfAb)); - celFunctionDeclBuilder.add(inOperator); - celFunctionDeclBuilder.add( - CelFunctionDecl.newBuilder() - .setName(Operator.IN.getFunction()) - .addOverloads(sameAs(inOperator, "", "")) - .build()); - - // Conversions to type - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.TYPE.getFunction(), - CelOverloadDecl.newGlobalOverload( - "type", "returns type of value", TypeType.create(typeParamA), typeParamA))); - - // Conversions to int - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.INT.getFunction(), - CelOverloadDecl.newGlobalOverload( - "uint64_to_int64", "type conversion", SimpleType.INT, SimpleType.UINT), - CelOverloadDecl.newGlobalOverload( - "double_to_int64", "type conversion", SimpleType.INT, SimpleType.DOUBLE), - CelOverloadDecl.newGlobalOverload( - "string_to_int64", "type conversion", SimpleType.INT, SimpleType.STRING), - CelOverloadDecl.newGlobalOverload( - "timestamp_to_int64", - "Convert timestamp to int64 in seconds since Unix epoch.", - SimpleType.INT, - SimpleType.TIMESTAMP))); - - // Conversions to uint - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.UINT.getFunction(), - CelOverloadDecl.newGlobalOverload( - "uint64_to_uint64", "type conversion (identity)", SimpleType.UINT, SimpleType.UINT), - CelOverloadDecl.newGlobalOverload( - "int64_to_uint64", "type conversion", SimpleType.UINT, SimpleType.INT), - CelOverloadDecl.newGlobalOverload( - "double_to_uint64", "type conversion", SimpleType.UINT, SimpleType.DOUBLE), - CelOverloadDecl.newGlobalOverload( - "string_to_uint64", "type conversion", SimpleType.UINT, SimpleType.STRING))); - - // Conversions to double - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.DOUBLE.getFunction(), - CelOverloadDecl.newGlobalOverload( - "double_to_double", - "type conversion (identity)", - SimpleType.DOUBLE, - SimpleType.DOUBLE), - CelOverloadDecl.newGlobalOverload( - "int64_to_double", "type conversion", SimpleType.DOUBLE, SimpleType.INT), - CelOverloadDecl.newGlobalOverload( - "uint64_to_double", "type conversion", SimpleType.DOUBLE, SimpleType.UINT), - CelOverloadDecl.newGlobalOverload( - "string_to_double", "type conversion", SimpleType.DOUBLE, SimpleType.STRING))); - - // Conversions to string - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.STRING.getFunction(), - CelOverloadDecl.newGlobalOverload( - "string_to_string", - "type conversion (identity)", - SimpleType.STRING, - SimpleType.STRING), - CelOverloadDecl.newGlobalOverload( - "int64_to_string", "type conversion", SimpleType.STRING, SimpleType.INT), - CelOverloadDecl.newGlobalOverload( - "uint64_to_string", "type conversion", SimpleType.STRING, SimpleType.UINT), - CelOverloadDecl.newGlobalOverload( - "double_to_string", "type conversion", SimpleType.STRING, SimpleType.DOUBLE), - CelOverloadDecl.newGlobalOverload( - "bytes_to_string", "type conversion", SimpleType.STRING, SimpleType.BYTES), - CelOverloadDecl.newGlobalOverload( - "timestamp_to_string", "type_conversion", SimpleType.STRING, SimpleType.TIMESTAMP), - CelOverloadDecl.newGlobalOverload( - "duration_to_string", "type_conversion", SimpleType.STRING, SimpleType.DURATION))); - - // Conversions to bytes - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.BYTES.getFunction(), - CelOverloadDecl.newGlobalOverload( - "bytes_to_bytes", "type conversion (identity)", SimpleType.BYTES, SimpleType.BYTES), - CelOverloadDecl.newGlobalOverload( - "string_to_bytes", "type conversion", SimpleType.BYTES, SimpleType.STRING))); - - // Conversions to dyn - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.DYN.getFunction(), - CelOverloadDecl.newGlobalOverload( - "to_dyn", "type conversion", SimpleType.DYN, typeParamA))); - - // Conversions to Duration - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.DURATION.getFunction(), - CelOverloadDecl.newGlobalOverload( - "duration_to_duration", - "type conversion (identity)", - SimpleType.DURATION, - SimpleType.DURATION), - CelOverloadDecl.newGlobalOverload( - "string_to_duration", - "type conversion, duration should be end with \"s\", which stands for seconds", - SimpleType.DURATION, - SimpleType.STRING))); - - // Conversions to boolean - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.BOOL.getFunction(), - CelOverloadDecl.newGlobalOverload( - "bool_to_bool", "type conversion (identity)", SimpleType.BOOL, SimpleType.BOOL), - CelOverloadDecl.newGlobalOverload( - "string_to_bool", "type conversion", SimpleType.BOOL, SimpleType.STRING))); - - // String functions - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.MATCHES.getFunction(), - CelOverloadDecl.newGlobalOverload( - "matches", - "matches first argument against regular expression in second argument", - SimpleType.BOOL, - SimpleType.STRING, - SimpleType.STRING))); - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.MATCHES.getFunction(), - CelOverloadDecl.newMemberOverload( - "matches_string", - "matches the self argument against regular expression in first argument", - SimpleType.BOOL, - SimpleType.STRING, - SimpleType.STRING))); - - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.CONTAINS.getFunction(), - CelOverloadDecl.newMemberOverload( - "contains_string", - "tests whether the string operand contains the substring", - SimpleType.BOOL, - SimpleType.STRING, - SimpleType.STRING))); - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.ENDS_WITH.getFunction(), - CelOverloadDecl.newMemberOverload( - "ends_with_string", - "tests whether the string operand ends with the suffix argument", - SimpleType.BOOL, - SimpleType.STRING, - SimpleType.STRING))); - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.STARTS_WITH.getFunction(), - CelOverloadDecl.newMemberOverload( - "starts_with_string", - "tests whether the string operand starts with the prefix argument", - SimpleType.BOOL, - SimpleType.STRING, - SimpleType.STRING))); - - // Date/time functions - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.GET_FULL_YEAR.getFunction(), - CelOverloadDecl.newMemberOverload( - "timestamp_to_year", - "get year from the date in UTC", - SimpleType.INT, - SimpleType.TIMESTAMP), - CelOverloadDecl.newMemberOverload( - "timestamp_to_year_with_tz", - "get year from the date with timezone", - SimpleType.INT, - SimpleType.TIMESTAMP, - SimpleType.STRING))); - - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.GET_MONTH.getFunction(), - CelOverloadDecl.newMemberOverload( - "timestamp_to_month", - "get month from the date in UTC, 0-11", - SimpleType.INT, - SimpleType.TIMESTAMP), - CelOverloadDecl.newMemberOverload( - "timestamp_to_month_with_tz", - "get month from the date with timezone, 0-11", - SimpleType.INT, - SimpleType.TIMESTAMP, - SimpleType.STRING))); - - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.GET_DAY_OF_YEAR.getFunction(), - CelOverloadDecl.newMemberOverload( - "timestamp_to_day_of_year", - "get day of year from the date in UTC, zero-based indexing", - SimpleType.INT, - SimpleType.TIMESTAMP), - CelOverloadDecl.newMemberOverload( - "timestamp_to_day_of_year_with_tz", - "get day of year from the date with timezone, zero-based indexing", - SimpleType.INT, - SimpleType.TIMESTAMP, - SimpleType.STRING))); - - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.GET_DAY_OF_MONTH.getFunction(), - CelOverloadDecl.newMemberOverload( - "timestamp_to_day_of_month", - "get day of month from the date in UTC, zero-based indexing", - SimpleType.INT, - SimpleType.TIMESTAMP), - CelOverloadDecl.newMemberOverload( - "timestamp_to_day_of_month_with_tz", - "get day of month from the date with timezone, zero-based indexing", - SimpleType.INT, - SimpleType.TIMESTAMP, - SimpleType.STRING))); - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.GET_DATE.getFunction(), - CelOverloadDecl.newMemberOverload( - "timestamp_to_day_of_month_1_based", - "get day of month from the date in UTC, one-based indexing", - SimpleType.INT, - SimpleType.TIMESTAMP), - CelOverloadDecl.newMemberOverload( - "timestamp_to_day_of_month_1_based_with_tz", - "get day of month from the date with timezone, one-based indexing", - SimpleType.INT, - SimpleType.TIMESTAMP, - SimpleType.STRING))); - - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.GET_DAY_OF_WEEK.getFunction(), - CelOverloadDecl.newMemberOverload( - "timestamp_to_day_of_week", - "get day of week from the date in UTC, zero-based, zero for Sunday", - SimpleType.INT, - SimpleType.TIMESTAMP), - CelOverloadDecl.newMemberOverload( - "timestamp_to_day_of_week_with_tz", - "get day of week from the date with timezone, zero-based, zero for Sunday", - SimpleType.INT, - SimpleType.TIMESTAMP, - SimpleType.STRING))); - - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.GET_HOURS.getFunction(), - CelOverloadDecl.newMemberOverload( - "timestamp_to_hours", - "get hours from the date in UTC, 0-23", - SimpleType.INT, - SimpleType.TIMESTAMP), - CelOverloadDecl.newMemberOverload( - "timestamp_to_hours_with_tz", - "get hours from the date with timezone, 0-23", - SimpleType.INT, - SimpleType.TIMESTAMP, - SimpleType.STRING), - CelOverloadDecl.newMemberOverload( - "duration_to_hours", - "get hours from duration", - SimpleType.INT, - SimpleType.DURATION))); - - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.GET_MINUTES.getFunction(), - CelOverloadDecl.newMemberOverload( - "timestamp_to_minutes", - "get minutes from the date in UTC, 0-59", - SimpleType.INT, - SimpleType.TIMESTAMP), - CelOverloadDecl.newMemberOverload( - "timestamp_to_minutes_with_tz", - "get minutes from the date with timezone, 0-59", - SimpleType.INT, - SimpleType.TIMESTAMP, - SimpleType.STRING), - CelOverloadDecl.newMemberOverload( - "duration_to_minutes", - "get minutes from duration", - SimpleType.INT, - SimpleType.DURATION))); - - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.GET_SECONDS.getFunction(), - CelOverloadDecl.newMemberOverload( - "timestamp_to_seconds", - "get seconds from the date in UTC, 0-59", - SimpleType.INT, - SimpleType.TIMESTAMP), - CelOverloadDecl.newMemberOverload( - "timestamp_to_seconds_with_tz", - "get seconds from the date with timezone, 0-59", - SimpleType.INT, - SimpleType.TIMESTAMP, - SimpleType.STRING), - CelOverloadDecl.newMemberOverload( - "duration_to_seconds", - "get seconds from duration", - SimpleType.INT, - SimpleType.DURATION))); - - celFunctionDeclBuilder.add( - CelFunctionDecl.newFunctionDeclaration( - Function.GET_MILLISECONDS.getFunction(), - CelOverloadDecl.newMemberOverload( - "timestamp_to_milliseconds", - "get milliseconds from the date in UTC, 0-999", - SimpleType.INT, - SimpleType.TIMESTAMP), - CelOverloadDecl.newMemberOverload( - "timestamp_to_milliseconds_with_tz", - "get milliseconds from the date with timezone, 0-999", - SimpleType.INT, - SimpleType.TIMESTAMP, - SimpleType.STRING), - CelOverloadDecl.newMemberOverload( - "duration_to_milliseconds", - "milliseconds from duration, 0-999", - SimpleType.INT, - SimpleType.DURATION))); - - return celFunctionDeclBuilder.build(); - } - - private static ImmutableList timestampConversionDeclarations(boolean withEpoch) { - CelFunctionDecl.Builder timestampBuilder = - CelFunctionDecl.newBuilder() - .setName("timestamp") - .addOverloads( - CelOverloadDecl.newGlobalOverload( - "string_to_timestamp", - "Type conversion of strings to timestamps according to RFC3339. Example:" - + " \"1972-01-01T10:00:20.021-05:00\".", - SimpleType.TIMESTAMP, - SimpleType.STRING), - CelOverloadDecl.newGlobalOverload( - "timestamp_to_timestamp", - "type conversion (identity)", - SimpleType.TIMESTAMP, - SimpleType.TIMESTAMP)); - if (withEpoch) { - timestampBuilder.addOverloads( - CelOverloadDecl.newGlobalOverload( - "int64_to_timestamp", - "Type conversion of integers as Unix epoch seconds to timestamps.", - SimpleType.TIMESTAMP, - SimpleType.INT)); - } - return ImmutableList.of(timestampBuilder.build()); - } - - private static ImmutableList numericComparisonDeclarations( - boolean withHeterogeneousComparisons) { - CelFunctionDecl.Builder lessBuilder = - CelFunctionDecl.newBuilder() - .setName(Operator.LESS.getFunction()) - .addOverloads( - CelOverloadDecl.newGlobalOverload( - "less_bool", "ordering", SimpleType.BOOL, SimpleType.BOOL, SimpleType.BOOL), - CelOverloadDecl.newGlobalOverload( - "less_int64", "ordering", SimpleType.BOOL, SimpleType.INT, SimpleType.INT), - CelOverloadDecl.newGlobalOverload( - "less_uint64", "ordering", SimpleType.BOOL, SimpleType.UINT, SimpleType.UINT), - CelOverloadDecl.newGlobalOverload( - "less_double", - "ordering", - SimpleType.BOOL, - SimpleType.DOUBLE, - SimpleType.DOUBLE), - CelOverloadDecl.newGlobalOverload( - "less_string", - "ordering", - SimpleType.BOOL, - SimpleType.STRING, - SimpleType.STRING), - CelOverloadDecl.newGlobalOverload( - "less_bytes", "ordering", SimpleType.BOOL, SimpleType.BYTES, SimpleType.BYTES), - CelOverloadDecl.newGlobalOverload( - "less_timestamp", - "ordering", - SimpleType.BOOL, - SimpleType.TIMESTAMP, - SimpleType.TIMESTAMP), - CelOverloadDecl.newGlobalOverload( - "less_duration", - "ordering", - SimpleType.BOOL, - SimpleType.DURATION, - SimpleType.DURATION)); - - if (withHeterogeneousComparisons) { - lessBuilder.addOverloads( - CelOverloadDecl.newGlobalOverload( - "less_int64_uint64", - "Compare a signed integer value to an unsigned integer value", - SimpleType.BOOL, - SimpleType.INT, - SimpleType.UINT), - CelOverloadDecl.newGlobalOverload( - "less_uint64_int64", - "Compare an unsigned integer value to a signed integer value", - SimpleType.BOOL, - SimpleType.UINT, - SimpleType.INT), - CelOverloadDecl.newGlobalOverload( - "less_int64_double", - "Compare a signed integer value to a double value, coalesces the integer to a double", - SimpleType.BOOL, - SimpleType.INT, - SimpleType.DOUBLE), - CelOverloadDecl.newGlobalOverload( - "less_double_int64", - "Compare a double value to a signed integer value, coalesces the integer to a double", - SimpleType.BOOL, - SimpleType.DOUBLE, - SimpleType.INT), - CelOverloadDecl.newGlobalOverload( - "less_uint64_double", - "Compare an unsigned integer value to a double value, coalesces the unsigned integer" - + " to a double", - SimpleType.BOOL, - SimpleType.UINT, - SimpleType.DOUBLE), - CelOverloadDecl.newGlobalOverload( - "less_double_uint64", - "Compare a double value to an unsigned integer value, coalesces the unsigned integer" - + " to a double", - SimpleType.BOOL, - SimpleType.DOUBLE, - SimpleType.UINT)); - } - - CelFunctionDecl less = lessBuilder.build(); - return ImmutableList.of( - less, - CelFunctionDecl.newBuilder() - .setName(Operator.LESS_EQUALS.getFunction()) - .addOverloads(sameAs(less, "less", "less_equals")) - .build(), - CelFunctionDecl.newBuilder() - .setName(Operator.GREATER.getFunction()) - .addOverloads(sameAs(less, "less", "greater")) - .build(), - CelFunctionDecl.newBuilder() - .setName(Operator.GREATER_EQUALS.getFunction()) - .addOverloads(sameAs(less, "less", "greater_equals")) - .build()); - } - - /** - * Add the overloads of another function to this function, after replacing the overload id as - * specified. - */ - private static ImmutableList sameAs( - CelFunctionDecl func, String idPart, String idPartReplace) { - ImmutableList.Builder overloads = new ImmutableList.Builder<>(); - Preconditions.checkNotNull(func); - for (CelOverloadDecl overload : func.overloads()) { - overloads.add( - overload.toBuilder() - .setOverloadId(overload.overloadId().replace(idPart, idPartReplace)) - .build()); - } - return overloads.build(); - } - - private Standard() {} -} diff --git a/checker/src/test/resources/standardEnvDump.baseline b/checker/src/test/resources/standardEnvDump.baseline index df1c6655..60d19f66 100644 --- a/checker/src/test/resources/standardEnvDump.baseline +++ b/checker/src/test/resources/standardEnvDump.baseline @@ -218,11 +218,11 @@ declare getSeconds { } declare int { value type(int) + function int64_to_int64 (int) -> int function uint64_to_int64 (uint) -> int function double_to_int64 (double) -> int function string_to_int64 (string) -> int function timestamp_to_int64 (google.protobuf.Timestamp) -> int - function int64_to_int64 (int) -> int } declare list { value type(list(dyn)) diff --git a/optimizer/src/main/java/dev/cel/optimizer/optimizers/BUILD.bazel b/optimizer/src/main/java/dev/cel/optimizer/optimizers/BUILD.bazel index 9b679d9b..3662c68c 100644 --- a/optimizer/src/main/java/dev/cel/optimizer/optimizers/BUILD.bazel +++ b/optimizer/src/main/java/dev/cel/optimizer/optimizers/BUILD.bazel @@ -72,7 +72,7 @@ java_library( ], visibility = ["//visibility:private"], deps = [ - "//checker:checker_legacy_environment", + "//checker:standard_decl", "//extensions", "//extensions:optional_library", "//parser:operator", diff --git a/optimizer/src/main/java/dev/cel/optimizer/optimizers/DefaultOptimizerConstants.java b/optimizer/src/main/java/dev/cel/optimizer/optimizers/DefaultOptimizerConstants.java index 07a3f062..63b6d68d 100644 --- a/optimizer/src/main/java/dev/cel/optimizer/optimizers/DefaultOptimizerConstants.java +++ b/optimizer/src/main/java/dev/cel/optimizer/optimizers/DefaultOptimizerConstants.java @@ -19,7 +19,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Streams; -import dev.cel.checker.Standard; +import dev.cel.checker.CelStandardDeclaration; import dev.cel.extensions.CelExtensions; import dev.cel.extensions.CelOptionalLibrary; import dev.cel.extensions.CelOptionalLibrary.Function; @@ -37,12 +37,16 @@ final class DefaultOptimizerConstants { */ static final ImmutableSet CEL_CANONICAL_FUNCTIONS = ImmutableSet.builder() + .addAll(CelStandardDeclaration.getAllFunctionNames()) .addAll( Streams.concat( stream(Operator.values()).map(Operator::getFunction), - stream(Standard.Function.values()).map(Standard.Function::getFunction), stream(CelOptionalLibrary.Function.values()).map(Function::getFunction)) .collect(toImmutableSet())) + .addAll( + stream(CelOptionalLibrary.Function.values()) + .map(Function::getFunction) + .collect(toImmutableSet())) .addAll(CelExtensions.getAllFunctionNames()) .build();