Skip to content

Commit 5e9c267

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 57f8218 commit 5e9c267

File tree

9 files changed

+739
-9
lines changed

9 files changed

+739
-9
lines changed

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

Lines changed: 46 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,50 @@ 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+
throw new UnsupportedOperationException(
157+
"Unsupported argument types: "
158+
+ (x != null ? x.getClass() : null)
159+
+ ", "
160+
+ (y != null ? y.getClass() : null));
161+
}
162+
117163
private ComparisonFunctions() {}
118164
}

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy