Skip to content

Commit 57785b8

Browse files
dmitriplotnikovcopybara-github
authored andcommitted
Introduce 'list' extension functions: 'slice', "distinct', 'reverse', 'sort', 'sortBy'
Add versions to the 'lists' extension to gradually expose new functions. PiperOrigin-RevId: 780339619
1 parent 97667f5 commit 57785b8

9 files changed

Lines changed: 702 additions & 9 deletions

File tree

common/src/main/java/dev/cel/common/internal/ComparisonFunctions.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package dev.cel.common.internal;
1616

1717
import com.google.common.primitives.UnsignedLong;
18+
import com.google.common.primitives.UnsignedLongs;
1819
import com.google.errorprone.annotations.CheckReturnValue;
1920
import dev.cel.common.annotations.Internal;
2021

@@ -114,5 +115,46 @@ public static boolean numericEquals(Number x, Number y) {
114115
return false;
115116
}
116117

118+
119+
/**
120+
* Compare two numeric values of any type (double, int, uint).
121+
*/
122+
public static int numericCompare(Number x, Number y) {
123+
if (x instanceof Double) {
124+
if (y instanceof Double) {
125+
return ((Double) x).compareTo((Double) y);
126+
}
127+
if (y instanceof Long) {
128+
return compareDoubleInt((Double) x, (Long) y);
129+
}
130+
if (y instanceof UnsignedLong) {
131+
return compareDoubleUint((Double) x, (UnsignedLong) y);
132+
}
133+
}
134+
if (x instanceof Long) {
135+
if (y instanceof Long) {
136+
return Long.compare((Long) x, (Long) y);
137+
}
138+
if (y instanceof Double) {
139+
return compareIntDouble((Long) x, (Double) y);
140+
}
141+
if (y instanceof UnsignedLong) {
142+
return compareIntUint((Long) x, (UnsignedLong) y);
143+
}
144+
}
145+
if (x instanceof UnsignedLong) {
146+
if (y instanceof UnsignedLong) {
147+
return UnsignedLongs.compare(x.longValue(), y.longValue());
148+
}
149+
if (y instanceof Double) {
150+
return compareUintDouble((UnsignedLong) x, (Double) y);
151+
}
152+
if (y instanceof Long) {
153+
return compareUintInt((UnsignedLong) x, (Long) y);
154+
}
155+
}
156+
return 0;
157+
}
158+
117159
private ComparisonFunctions() {}
118160
}

common/src/test/java/dev/cel/common/internal/ComparisonFunctionsTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,33 @@ public void compareUintIntEdgeCases() {
6464
assertThat(ComparisonFunctions.compareUintInt(ux, 1)).isEqualTo(1);
6565
assertThat(ComparisonFunctions.compareIntUint(1, ux)).isEqualTo(-1);
6666
}
67+
68+
@Test
69+
@TestParameters("{x: 1, y: 1, expect: 0}")
70+
@TestParameters("{x: 1, y: 2, expect: -1}")
71+
@TestParameters("{x: 2, y: -1, expect: 1}")
72+
public void numericCompareDoubleInt(double x, long y, int expect) {
73+
assertThat(ComparisonFunctions.numericCompare(x, y)).isEqualTo(expect);
74+
assertThat(ComparisonFunctions.numericCompare(y, x)).isEqualTo(-1 * expect);
75+
}
76+
77+
@Test
78+
@TestParameters("{x: 1, y: 1, expect: 0}")
79+
@TestParameters("{x: 1, y: 2, expect: -1}")
80+
@TestParameters("{x: 2, y: 1, expect: 1}")
81+
public void numericCompareDoubleUint(double x, long y, int expect) {
82+
UnsignedLong uy = UnsignedLong.valueOf(y);
83+
assertThat(ComparisonFunctions.numericCompare(x, uy)).isEqualTo(expect);
84+
assertThat(ComparisonFunctions.numericCompare(uy, x)).isEqualTo(-1 * expect);
85+
}
86+
87+
@Test
88+
@TestParameters("{x: 1, y: 1, expect: 0}")
89+
@TestParameters("{x: 1, y: 2, expect: -1}")
90+
@TestParameters("{x: 2, y: -1, expect: 1}")
91+
public void numericCompareUintInt(long x, long y, int expect) {
92+
UnsignedLong ux = UnsignedLong.valueOf(x);
93+
assertThat(ComparisonFunctions.numericCompare(ux, y)).isEqualTo(expect);
94+
assertThat(ComparisonFunctions.numericCompare(y, ux)).isEqualTo(-1 * expect);
95+
}
6796
}

extensions/src/main/java/dev/cel/extensions/BUILD.bazel

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ java_library(
2727
":sets_function",
2828
":strings",
2929
"//common:options",
30+
"//common/internal:env_visitor",
31+
"//compiler",
32+
"//compiler:compiler_builder",
3033
"@maven//:com_google_guava_guava",
3134
],
3235
)
@@ -237,10 +240,17 @@ java_library(
237240
deps = [
238241
"//checker:checker_builder",
239242
"//common:compiler_common",
243+
"//common:options",
244+
"//common/ast",
245+
"//common/internal:comparison_functions",
240246
"//common/types",
241247
"//compiler:compiler_builder",
248+
"//parser:macro",
249+
"//parser:operator",
250+
"//parser:parser_builder",
242251
"//runtime",
243252
"//runtime:function_binding",
253+
"//runtime:runtime_equality",
244254
"@maven//:com_google_guava_guava",
245255
],
246256
)

extensions/src/main/java/dev/cel/extensions/CelExtensions.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
import com.google.common.collect.ImmutableSet;
2121
import com.google.common.collect.Streams;
2222
import dev.cel.common.CelOptions;
23+
import dev.cel.common.internal.EnvVisitable;
24+
import dev.cel.compiler.CelCompiler;
25+
import dev.cel.compiler.CelCompilerFactory;
26+
import dev.cel.compiler.CelCompilerLibrary;
2327
import dev.cel.extensions.CelListsExtensions.Function;
2428
import java.util.Set;
2529

@@ -35,7 +39,6 @@ public final class CelExtensions {
3539
private static final CelProtoExtensions PROTO_EXTENSIONS = new CelProtoExtensions();
3640
private static final CelBindingsExtensions BINDINGS_EXTENSIONS = new CelBindingsExtensions();
3741
private static final CelEncoderExtensions ENCODER_EXTENSIONS = new CelEncoderExtensions();
38-
private static final CelListsExtensions LISTS_EXTENSIONS_ALL = new CelListsExtensions();
3942
private static final CelRegexExtensions REGEX_EXTENSIONS = new CelRegexExtensions();
4043

4144
/**
@@ -230,7 +233,16 @@ public static CelSetsExtensions sets(CelOptions celOptions, Set<SetsFunction> fu
230233
* CelListsExtensions.Function}.
231234
*/
232235
public static CelListsExtensions lists() {
233-
return LISTS_EXTENSIONS_ALL;
236+
return new CelListsExtensions(Integer.MAX_VALUE);
237+
}
238+
239+
/**
240+
* Extended functions for List manipulation.
241+
*
242+
* <p>Refer to README.md for functions available in each version.
243+
*/
244+
public static CelListsExtensions lists(int version) {
245+
return new CelListsExtensions(version);
234246
}
235247

236248
/**
@@ -293,5 +305,16 @@ public static ImmutableSet<String> getAllFunctionNames() {
293305
.collect(toImmutableSet());
294306
}
295307

308+
public static ImmutableSet<String> getFunctionNames(CelCompilerLibrary library) {
309+
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
310+
CelCompiler compiler =
311+
CelCompilerFactory.standardCelCompilerBuilder()
312+
.setStandardEnvironmentEnabled(false)
313+
.addLibraries(library)
314+
.build();
315+
((EnvVisitable) compiler).accept((name, decls) -> builder.add(name));
316+
return builder.build();
317+
}
318+
296319
private CelExtensions() {}
297320
}

0 commit comments

Comments
 (0)