Skip to content

Commit 261b651

Browse files
dmitriplotnikovcopybara-github
authored andcommitted
Update the "strings" extension to be compatible with CelEnvironmentExporter
PiperOrigin-RevId: 786914253
1 parent a1d76e4 commit 261b651

9 files changed

Lines changed: 159 additions & 4 deletions

File tree

bundle/src/main/java/dev/cel/bundle/CelEnvironmentExporter.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,10 @@ public Builder addStandardExtensions(CelOptions options) {
117117
CelExtensions.getExtensionLibrary("encoders", options),
118118
CelExtensions.getExtensionLibrary("lists", options),
119119
CelExtensions.getExtensionLibrary("math", options),
120-
CelExtensions.getExtensionLibrary("protos", options));
120+
CelExtensions.getExtensionLibrary("protos", options),
121+
CelExtensions.getExtensionLibrary("regex", options),
122+
CelExtensions.getExtensionLibrary("sets", options),
123+
CelExtensions.getExtensionLibrary("strings", options));
121124
// TODO: add support for remaining standard extensions
122125
return this;
123126
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ java_library(
8585
"//common/internal",
8686
"//common/types",
8787
"//compiler:compiler_builder",
88+
"//extensions:extension_library",
8889
"//runtime",
8990
"//runtime:evaluation_exception_builder",
9091
"//runtime:function_binding",
@@ -203,6 +204,7 @@ java_library(
203204
"//common/internal:dynamic_proto",
204205
"//common/types",
205206
"//compiler:compiler_builder",
207+
"//extensions:extension_library",
206208
"//runtime",
207209
"//runtime:proto_message_runtime_equality",
208210
"@maven//:com_google_errorprone_error_prone_annotations",
@@ -278,6 +280,7 @@ java_library(
278280
"//common:compiler_common",
279281
"//common/types",
280282
"//compiler:compiler_builder",
283+
"//extensions:extension_library",
281284
"//runtime",
282285
"//runtime:function_binding",
283286
"@maven//:com_google_errorprone_error_prone_annotations",

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,12 @@ public static CelExtensionLibrary<? extends CelExtensionLibrary.FeatureSet> getE
313313
return CelMathExtensions.library(options);
314314
case "protos":
315315
return CelProtoExtensions.library();
316+
case "regex":
317+
return CelRegexExtensions.library();
318+
case "sets":
319+
return CelSetsExtensions.library(options);
320+
case "strings":
321+
return CelStringExtensions.library();
316322
// TODO: add support for remaining standard extensions
317323
default:
318324
throw new IllegalArgumentException("Unknown standard extension '" + name + "'");

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

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package dev.cel.extensions;
1616

17+
import static com.google.common.collect.ImmutableSet.toImmutableSet;
18+
1719
import com.google.common.collect.ImmutableList;
1820
import com.google.common.collect.ImmutableSet;
1921
import com.google.errorprone.annotations.Immutable;
@@ -35,7 +37,8 @@
3537

3638
/** Internal implementation of CEL regex extensions. */
3739
@Immutable
38-
final class CelRegexExtensions implements CelCompilerLibrary, CelRuntimeLibrary {
40+
final class CelRegexExtensions
41+
implements CelCompilerLibrary, CelRuntimeLibrary, CelExtensionLibrary.FeatureSet {
3942

4043
private static final String REGEX_REPLACE_FUNCTION = "regex.replace";
4144
private static final String REGEX_EXTRACT_FUNCTION = "regex.extract";
@@ -124,6 +127,25 @@ String getFunction() {
124127
}
125128
}
126129

130+
private static final CelExtensionLibrary<CelRegexExtensions> LIBRARY =
131+
new CelExtensionLibrary<CelRegexExtensions>() {
132+
private final CelRegexExtensions version0 = new CelRegexExtensions();
133+
134+
@Override
135+
public String name() {
136+
return "regex";
137+
}
138+
139+
@Override
140+
public ImmutableSet<CelRegexExtensions> versions() {
141+
return ImmutableSet.of(version0);
142+
}
143+
};
144+
145+
static CelExtensionLibrary<CelRegexExtensions> library() {
146+
return LIBRARY;
147+
}
148+
127149
private final ImmutableSet<Function> functions;
128150

129151
CelRegexExtensions() {
@@ -134,6 +156,16 @@ String getFunction() {
134156
this.functions = ImmutableSet.copyOf(functions);
135157
}
136158

159+
@Override
160+
public int version() {
161+
return 0;
162+
}
163+
164+
@Override
165+
public ImmutableSet<CelFunctionDecl> functions() {
166+
return functions.stream().map(f -> f.functionDecl).collect(toImmutableSet());
167+
}
168+
137169
@Override
138170
public void setCheckerOptions(CelCheckerBuilder checkerBuilder) {
139171
functions.forEach(function -> checkerBuilder.addFunctionDeclarations(function.functionDecl));

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
* rewrite the AST into a map to achieve a O(1) lookup.
4242
*/
4343
@Immutable
44-
final class CelSetsExtensions implements CelCompilerLibrary, CelRuntimeLibrary {
44+
final class CelSetsExtensions
45+
implements CelCompilerLibrary, CelRuntimeLibrary, CelExtensionLibrary.FeatureSet {
4546

4647
private static final String SET_CONTAINS_OVERLOAD_DOC =
4748
"Returns whether the first list argument contains all elements in the second list"
@@ -90,6 +91,28 @@ final class CelSetsExtensions implements CelCompilerLibrary, CelRuntimeLibrary {
9091
ListType.create(TypeParamType.create("T")),
9192
ListType.create(TypeParamType.create("T")))));
9293

94+
private static final class Library implements CelExtensionLibrary<CelSetsExtensions> {
95+
private final CelSetsExtensions version0;
96+
97+
Library(CelOptions celOptions) {
98+
version0 = new CelSetsExtensions(celOptions);
99+
}
100+
101+
@Override
102+
public String name() {
103+
return "sets";
104+
}
105+
106+
@Override
107+
public ImmutableSet<CelSetsExtensions> versions() {
108+
return ImmutableSet.of(version0);
109+
}
110+
}
111+
112+
static CelExtensionLibrary<CelSetsExtensions> library(CelOptions options) {
113+
return new Library(options);
114+
}
115+
93116
private final ImmutableSet<SetsFunction> functions;
94117
private final SetsExtensionsRuntimeImpl setsExtensionsRuntime;
95118

@@ -105,6 +128,16 @@ final class CelSetsExtensions implements CelCompilerLibrary, CelRuntimeLibrary {
105128
this.setsExtensionsRuntime = new SetsExtensionsRuntimeImpl(runtimeEquality, functions);
106129
}
107130

131+
@Override
132+
public int version() {
133+
return 0;
134+
}
135+
136+
@Override
137+
public ImmutableSet<CelFunctionDecl> functions() {
138+
return ImmutableSet.copyOf(FUNCTION_DECL_MAP.values());
139+
}
140+
108141
@Override
109142
public void setCheckerOptions(CelCheckerBuilder checkerBuilder) {
110143
functions.forEach(

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

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package dev.cel.extensions;
1616

17+
import static com.google.common.collect.ImmutableSet.toImmutableSet;
1718
import static java.lang.Math.max;
1819
import static java.lang.Math.min;
1920

@@ -42,7 +43,8 @@
4243

4344
/** Internal implementation of CEL string extensions. */
4445
@Immutable
45-
public final class CelStringExtensions implements CelCompilerLibrary, CelRuntimeLibrary {
46+
public final class CelStringExtensions
47+
implements CelCompilerLibrary, CelRuntimeLibrary, CelExtensionLibrary.FeatureSet {
4648

4749
/** Denotes the string extension function */
4850
@SuppressWarnings({"unchecked"}) // Unchecked: Type-checker guarantees casting safety.
@@ -250,6 +252,35 @@ String getFunction() {
250252
this.functions = ImmutableSet.copyOf(functions);
251253
}
252254

255+
private static final CelExtensionLibrary<CelStringExtensions> LIBRARY =
256+
new CelExtensionLibrary<CelStringExtensions>() {
257+
private final CelStringExtensions version0 = new CelStringExtensions();
258+
259+
@Override
260+
public String name() {
261+
return "strings";
262+
}
263+
264+
@Override
265+
public ImmutableSet<CelStringExtensions> versions() {
266+
return ImmutableSet.of(version0);
267+
}
268+
};
269+
270+
static CelExtensionLibrary<CelStringExtensions> library() {
271+
return LIBRARY;
272+
}
273+
274+
@Override
275+
public int version() {
276+
return 0;
277+
}
278+
279+
@Override
280+
public ImmutableSet<CelFunctionDecl> functions() {
281+
return functions.stream().map(f -> f.functionDecl).collect(toImmutableSet());
282+
}
283+
253284
@Override
254285
public void setCheckerOptions(CelCheckerBuilder checkerBuilder) {
255286
functions.forEach(function -> checkerBuilder.addFunctionDeclarations(function.functionDecl));

extensions/src/test/java/dev/cel/extensions/CelRegexExtensionsTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
2222
import com.google.testing.junit.testparameterinjector.TestParameters;
2323
import dev.cel.common.CelAbstractSyntaxTree;
24+
import dev.cel.common.CelFunctionDecl;
25+
import dev.cel.common.CelOptions;
2426
import dev.cel.compiler.CelCompiler;
2527
import dev.cel.compiler.CelCompilerFactory;
2628
import dev.cel.runtime.CelEvaluationException;
@@ -38,6 +40,17 @@ public final class CelRegexExtensionsTest {
3840
private static final CelRuntime RUNTIME =
3941
CelRuntimeFactory.standardCelRuntimeBuilder().addLibraries(CelExtensions.regex()).build();
4042

43+
@Test
44+
public void library() {
45+
CelExtensionLibrary<?> library =
46+
CelExtensions.getExtensionLibrary("regex", CelOptions.DEFAULT);
47+
assertThat(library.name()).isEqualTo("regex");
48+
assertThat(library.latest().version()).isEqualTo(0);
49+
assertThat(library.version(0).functions().stream().map(CelFunctionDecl::name))
50+
.containsExactly("regex.replace", "regex.extract", "regex.extractAll");
51+
assertThat(library.version(0).macros()).isEmpty();
52+
}
53+
4154
@Test
4255
@TestParameters("{target: 'abc', regex: '^', replaceStr: 'start_', res: 'start_abc'}")
4356
@TestParameters("{target: 'abc', regex: '$', replaceStr: '_end', res: 'abc_end'}")

extensions/src/test/java/dev/cel/extensions/CelSetsExtensionsTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ public final class CelSetsExtensionsTest {
7272
Math::toIntExact))
7373
.build();
7474

75+
@Test
76+
public void library() {
77+
CelExtensionLibrary<?> library =
78+
CelExtensions.getExtensionLibrary("sets", CelOptions.DEFAULT);
79+
assertThat(library.name()).isEqualTo("sets");
80+
assertThat(library.latest().version()).isEqualTo(0);
81+
assertThat(library.version(0).functions().stream().map(CelFunctionDecl::name))
82+
.containsExactly("sets.contains", "sets.equivalent", "sets.intersects");
83+
assertThat(library.version(0).macros()).isEmpty();
84+
}
85+
7586
@Test
7687
public void contains_integerListWithSameValue_succeeds() throws Exception {
7788
ImmutableList<Integer> list = ImmutableList.of(1, 2, 3, 4);

extensions/src/test/java/dev/cel/extensions/CelStringExtensionsTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
2424
import com.google.testing.junit.testparameterinjector.TestParameters;
2525
import dev.cel.common.CelAbstractSyntaxTree;
26+
import dev.cel.common.CelFunctionDecl;
27+
import dev.cel.common.CelOptions;
2628
import dev.cel.common.CelValidationException;
2729
import dev.cel.common.types.SimpleType;
2830
import dev.cel.compiler.CelCompiler;
@@ -54,6 +56,27 @@ public final class CelStringExtensionsTest {
5456
private static final CelRuntime RUNTIME =
5557
CelRuntimeFactory.standardCelRuntimeBuilder().addLibraries(CelExtensions.strings()).build();
5658

59+
@Test
60+
public void library() {
61+
CelExtensionLibrary<?> library =
62+
CelExtensions.getExtensionLibrary("strings", CelOptions.DEFAULT);
63+
assertThat(library.name()).isEqualTo("strings");
64+
assertThat(library.latest().version()).isEqualTo(0);
65+
assertThat(library.version(0).functions().stream().map(CelFunctionDecl::name))
66+
.containsExactly(
67+
"charAt",
68+
"indexOf",
69+
"join",
70+
"lastIndexOf",
71+
"lowerAscii",
72+
"replace",
73+
"split",
74+
"substring",
75+
"trim",
76+
"upperAscii");
77+
assertThat(library.version(0).macros()).isEmpty();
78+
}
79+
5780
@Test
5881
@TestParameters("{string: 'abcd', beginIndex: 0, expectedResult: 'abcd'}")
5982
@TestParameters("{string: 'abcd', beginIndex: 1, expectedResult: 'bcd'}")

0 commit comments

Comments
 (0)