Skip to content

Commit 09d009a

Browse files
l46kokcopybara-github
authored andcommitted
Properly retain celStandardDeclarations when invoking toBuilder on checker
PiperOrigin-RevId: 802639372
1 parent 8363a89 commit 09d009a

3 files changed

Lines changed: 92 additions & 21 deletions

File tree

checker/src/main/java/dev/cel/checker/CelCheckerLegacyImpl.java

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import java.util.List;
5656
import java.util.SortedSet;
5757
import java.util.TreeSet;
58+
import org.jspecify.annotations.Nullable;
5859

5960
/**
6061
* {@code CelChecker} implementation which uses the original CEL-Java APIs to provide a simple,
@@ -128,6 +129,10 @@ public CelCheckerBuilder toCheckerBuilder() {
128129
builder.setResultType(expectedResultType.get());
129130
}
130131

132+
if (overriddenStandardDeclarations != null) {
133+
builder.setStandardDeclarations(overriddenStandardDeclarations);
134+
}
135+
131136
return builder;
132137
}
133138

@@ -177,6 +182,7 @@ public static CelCheckerBuilder newBuilder() {
177182
/** Builder class for the legacy {@code CelChecker} implementation. */
178183
public static final class Builder implements CelCheckerBuilder {
179184

185+
// LINT.IfChange
180186
private final ImmutableSet.Builder<CelIdentDecl> identDeclarations;
181187
private final ImmutableSet.Builder<CelFunctionDecl> functionDeclarations;
182188
private final ImmutableSet.Builder<ProtoTypeMask> protoTypeMasks;
@@ -191,6 +197,8 @@ public static final class Builder implements CelCheckerBuilder {
191197
private boolean standardEnvironmentEnabled;
192198
private CelStandardDeclarations standardDeclarations;
193199

200+
// LINT.ThenChange(CelCheckerLegacyImplTest.java)
201+
194202
@Override
195203
public CelCheckerBuilder setOptions(CelOptions celOptions) {
196204
this.celOptions = checkNotNull(celOptions);
@@ -379,38 +387,53 @@ Builder addIdentDeclarations(ImmutableSet<CelIdentDecl> identDeclarations) {
379387
return this;
380388
}
381389

382-
// The following getters exist for asserting immutability for collections held by this builder,
383-
// and shouldn't be exposed to the public.
390+
// The following getters marked @VisibleForTesting exist for testing toCheckerBuilder copies
391+
// over all properties. Do not expose these to public
384392
@VisibleForTesting
385-
ImmutableSet.Builder<CelFunctionDecl> getFunctionDecls() {
393+
ImmutableSet.Builder<CelFunctionDecl> functionDecls() {
386394
return this.functionDeclarations;
387395
}
388396

389397
@VisibleForTesting
390-
ImmutableSet.Builder<CelIdentDecl> getIdentDecls() {
398+
ImmutableSet.Builder<CelIdentDecl> identDecls() {
391399
return this.identDeclarations;
392400
}
393401

394402
@VisibleForTesting
395-
ImmutableSet.Builder<ProtoTypeMask> getProtoTypeMasks() {
403+
ImmutableSet.Builder<ProtoTypeMask> protoTypeMasks() {
396404
return this.protoTypeMasks;
397405
}
398406

399407
@VisibleForTesting
400-
ImmutableSet.Builder<Descriptor> getMessageTypes() {
408+
ImmutableSet.Builder<Descriptor> messageTypes() {
401409
return this.messageTypes;
402410
}
403411

404412
@VisibleForTesting
405-
ImmutableSet.Builder<FileDescriptor> getFileTypes() {
413+
ImmutableSet.Builder<FileDescriptor> fileTypes() {
406414
return this.fileTypes;
407415
}
408416

409417
@VisibleForTesting
410-
ImmutableSet.Builder<CelCheckerLibrary> getCheckerLibraries() {
418+
ImmutableSet.Builder<CelCheckerLibrary> checkerLibraries() {
411419
return this.celCheckerLibraries;
412420
}
413421

422+
@VisibleForTesting
423+
CelStandardDeclarations standardDeclarations() {
424+
return this.standardDeclarations;
425+
}
426+
427+
@VisibleForTesting
428+
CelOptions options() {
429+
return this.celOptions;
430+
}
431+
432+
@VisibleForTesting
433+
CelTypeProvider celTypeProvider() {
434+
return this.celTypeProvider;
435+
}
436+
414437
@Override
415438
@CheckReturnValue
416439
public CelCheckerLegacyImpl build() {
@@ -506,7 +529,7 @@ private CelCheckerLegacyImpl(
506529
TypeProvider typeProvider,
507530
CelTypeProvider celTypeProvider,
508531
boolean standardEnvironmentEnabled,
509-
CelStandardDeclarations overriddenStandardDeclarations,
532+
@Nullable CelStandardDeclarations overriddenStandardDeclarations,
510533
ImmutableSet<CelCheckerLibrary> checkerLibraries,
511534
ImmutableSet<FileDescriptor> fileDescriptors,
512535
ImmutableSet<ProtoTypeMask> protoTypeMasks) {

checker/src/test/java/dev/cel/checker/CelCheckerLegacyImplTest.java

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,20 @@
1616

1717
import static com.google.common.truth.Truth.assertThat;
1818

19+
import com.google.common.collect.ImmutableCollection;
20+
import com.google.common.collect.ImmutableList;
21+
import dev.cel.checker.CelStandardDeclarations.StandardFunction;
22+
import dev.cel.common.CelContainer;
1923
import dev.cel.common.CelFunctionDecl;
24+
import dev.cel.common.CelOptions;
2025
import dev.cel.common.CelOverloadDecl;
2126
import dev.cel.common.CelVarDecl;
27+
import dev.cel.common.types.CelType;
28+
import dev.cel.common.types.CelTypeProvider;
2229
import dev.cel.common.types.SimpleType;
2330
import dev.cel.compiler.CelCompilerFactory;
2431
import dev.cel.expr.conformance.proto3.TestAllTypes;
32+
import java.util.Optional;
2533
import org.junit.Test;
2634
import org.junit.runner.RunWith;
2735
import org.junit.runners.JUnit4;
@@ -49,7 +57,45 @@ public void toCheckerBuilder_isImmutable() {
4957
CelCheckerLegacyImpl.Builder newCheckerBuilder =
5058
(CelCheckerLegacyImpl.Builder) celChecker.toCheckerBuilder();
5159

52-
assertThat(newCheckerBuilder.getCheckerLibraries().build()).isEmpty();
60+
assertThat(newCheckerBuilder.checkerLibraries().build()).isEmpty();
61+
}
62+
63+
@Test
64+
public void toCheckerBuilder_singularFields_copied() {
65+
CelStandardDeclarations subsetDecls =
66+
CelStandardDeclarations.newBuilder().includeFunctions(StandardFunction.BOOL).build();
67+
CelOptions celOptions = CelOptions.current().enableTimestampEpoch(true).build();
68+
CelContainer celContainer = CelContainer.ofName("foo");
69+
CelType expectedResultType = SimpleType.BOOL;
70+
CelTypeProvider customTypeProvider =
71+
new CelTypeProvider() {
72+
@Override
73+
public ImmutableCollection<CelType> types() {
74+
return ImmutableList.of();
75+
}
76+
77+
@Override
78+
public Optional<CelType> findType(String typeName) {
79+
return Optional.empty();
80+
}
81+
};
82+
CelCheckerBuilder celCheckerBuilder =
83+
CelCompilerFactory.standardCelCheckerBuilder()
84+
.setOptions(celOptions)
85+
.setContainer(celContainer)
86+
.setResultType(expectedResultType)
87+
.setTypeProvider(customTypeProvider)
88+
.setStandardEnvironmentEnabled(false)
89+
.setStandardDeclarations(subsetDecls);
90+
CelCheckerLegacyImpl celChecker = (CelCheckerLegacyImpl) celCheckerBuilder.build();
91+
92+
CelCheckerLegacyImpl.Builder newCheckerBuilder =
93+
(CelCheckerLegacyImpl.Builder) celChecker.toCheckerBuilder();
94+
95+
assertThat(newCheckerBuilder.standardDeclarations()).isEqualTo(subsetDecls);
96+
assertThat(newCheckerBuilder.options()).isEqualTo(celOptions);
97+
assertThat(newCheckerBuilder.container()).isEqualTo(celContainer);
98+
assertThat(newCheckerBuilder.celTypeProvider()).isEqualTo(customTypeProvider);
5399
}
54100

55101
@Test
@@ -70,12 +116,12 @@ public void toCheckerBuilder_collectionProperties_copied() {
70116
CelCheckerLegacyImpl.Builder newCheckerBuilder =
71117
(CelCheckerLegacyImpl.Builder) celChecker.toCheckerBuilder();
72118

73-
assertThat(newCheckerBuilder.getFunctionDecls().build()).hasSize(1);
74-
assertThat(newCheckerBuilder.getIdentDecls().build()).hasSize(1);
75-
assertThat(newCheckerBuilder.getProtoTypeMasks().build()).hasSize(1);
76-
assertThat(newCheckerBuilder.getFileTypes().build())
119+
assertThat(newCheckerBuilder.functionDecls().build()).hasSize(1);
120+
assertThat(newCheckerBuilder.identDecls().build()).hasSize(1);
121+
assertThat(newCheckerBuilder.protoTypeMasks().build()).hasSize(1);
122+
assertThat(newCheckerBuilder.fileTypes().build())
77123
.hasSize(1); // MessageTypes and FileTypes deduped into the same file descriptor
78-
assertThat(newCheckerBuilder.getCheckerLibraries().build()).hasSize(1);
124+
assertThat(newCheckerBuilder.checkerLibraries().build()).hasSize(1);
79125
}
80126

81127
@Test
@@ -96,11 +142,11 @@ public void toCheckerBuilder_collectionProperties_areImmutable() {
96142
ProtoTypeMask.ofAllFields("cel.expr.conformance.proto3.TestAllTypes"));
97143
celCheckerBuilder.addLibraries(new CelCheckerLibrary() {});
98144

99-
assertThat(newCheckerBuilder.getFunctionDecls().build()).isEmpty();
100-
assertThat(newCheckerBuilder.getIdentDecls().build()).isEmpty();
101-
assertThat(newCheckerBuilder.getProtoTypeMasks().build()).isEmpty();
102-
assertThat(newCheckerBuilder.getMessageTypes().build()).isEmpty();
103-
assertThat(newCheckerBuilder.getFileTypes().build()).isEmpty();
104-
assertThat(newCheckerBuilder.getCheckerLibraries().build()).isEmpty();
145+
assertThat(newCheckerBuilder.functionDecls().build()).isEmpty();
146+
assertThat(newCheckerBuilder.identDecls().build()).isEmpty();
147+
assertThat(newCheckerBuilder.protoTypeMasks().build()).isEmpty();
148+
assertThat(newCheckerBuilder.messageTypes().build()).isEmpty();
149+
assertThat(newCheckerBuilder.fileTypes().build()).isEmpty();
150+
assertThat(newCheckerBuilder.checkerLibraries().build()).isEmpty();
105151
}
106152
}

checker/src/test/java/dev/cel/checker/CelCompilerImplTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,6 @@ public void toCompilerBuilder_isImmutable() {
4242

4343
assertThat(newCompilerBuilder).isNotEqualTo(celCompilerBuilder);
4444
}
45+
46+
4547
}

0 commit comments

Comments
 (0)