Skip to content

Commit d024526

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

2 files changed

Lines changed: 89 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(//depot/google3/third_party/java/cel/checker/src/test/java/dev/cel/checker/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: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,19 @@
1616

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

19+
import com.google.common.collect.ImmutableList;
20+
import dev.cel.checker.CelStandardDeclarations.StandardFunction;
21+
import dev.cel.common.CelContainer;
1922
import dev.cel.common.CelFunctionDecl;
23+
import dev.cel.common.CelOptions;
2024
import dev.cel.common.CelOverloadDecl;
2125
import dev.cel.common.CelVarDecl;
26+
import dev.cel.common.types.CelType;
27+
import dev.cel.common.types.CelTypeProvider;
2228
import dev.cel.common.types.SimpleType;
2329
import dev.cel.compiler.CelCompilerFactory;
2430
import dev.cel.expr.conformance.proto3.TestAllTypes;
31+
import java.util.Optional;
2532
import org.junit.Test;
2633
import org.junit.runner.RunWith;
2734
import org.junit.runners.JUnit4;
@@ -49,7 +56,45 @@ public void toCheckerBuilder_isImmutable() {
4956
CelCheckerLegacyImpl.Builder newCheckerBuilder =
5057
(CelCheckerLegacyImpl.Builder) celChecker.toCheckerBuilder();
5158

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

55100
@Test
@@ -70,12 +115,12 @@ public void toCheckerBuilder_collectionProperties_copied() {
70115
CelCheckerLegacyImpl.Builder newCheckerBuilder =
71116
(CelCheckerLegacyImpl.Builder) celChecker.toCheckerBuilder();
72117

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())
118+
assertThat(newCheckerBuilder.functionDecls().build()).hasSize(1);
119+
assertThat(newCheckerBuilder.identDecls().build()).hasSize(1);
120+
assertThat(newCheckerBuilder.protoTypeMasks().build()).hasSize(1);
121+
assertThat(newCheckerBuilder.fileTypes().build())
77122
.hasSize(1); // MessageTypes and FileTypes deduped into the same file descriptor
78-
assertThat(newCheckerBuilder.getCheckerLibraries().build()).hasSize(1);
123+
assertThat(newCheckerBuilder.checkerLibraries().build()).hasSize(1);
79124
}
80125

81126
@Test
@@ -96,11 +141,11 @@ public void toCheckerBuilder_collectionProperties_areImmutable() {
96141
ProtoTypeMask.ofAllFields("cel.expr.conformance.proto3.TestAllTypes"));
97142
celCheckerBuilder.addLibraries(new CelCheckerLibrary() {});
98143

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();
144+
assertThat(newCheckerBuilder.functionDecls().build()).isEmpty();
145+
assertThat(newCheckerBuilder.identDecls().build()).isEmpty();
146+
assertThat(newCheckerBuilder.protoTypeMasks().build()).isEmpty();
147+
assertThat(newCheckerBuilder.messageTypes().build()).isEmpty();
148+
assertThat(newCheckerBuilder.fileTypes().build()).isEmpty();
149+
assertThat(newCheckerBuilder.checkerLibraries().build()).isEmpty();
105150
}
106151
}

0 commit comments

Comments
 (0)