From 4f0faaf985a52e5cf41dfef7aaafc0cd7c3cc159 Mon Sep 17 00:00:00 2001 From: Sokwhan Huh Date: Tue, 19 Sep 2023 12:58:10 -0700 Subject: [PATCH] Add general interfaces for instantiating a CelOptimizer PiperOrigin-RevId: 566717698 --- optimizer/BUILD.bazel | 26 ++++ .../main/java/dev/cel/optimizer/BUILD.bazel | 71 ++++++++++ .../dev/cel/optimizer/CelAstOptimizer.java | 28 ++++ .../java/dev/cel/optimizer/CelOptimizer.java | 38 ++++++ .../cel/optimizer/CelOptimizerBuilder.java | 34 +++++ .../cel/optimizer/CelOptimizerFactory.java | 47 +++++++ .../dev/cel/optimizer/CelOptimizerImpl.java | 84 ++++++++++++ .../test/java/dev/cel/optimizer/BUILD.bazel | 32 +++++ .../optimizer/CelOptimizerFactoryTest.java | 61 +++++++++ .../cel/optimizer/CelOptimizerImplTest.java | 126 ++++++++++++++++++ .../validators/DurationLiteralValidator.java | 2 +- .../HomogeneousLiteralValidator.java | 2 +- .../validators/RegexLiteralValidator.java | 2 +- .../validators/TimestampLiteralValidator.java | 2 +- .../cel/validator/CelValidatorImplTest.java | 2 - 15 files changed, 551 insertions(+), 6 deletions(-) create mode 100644 optimizer/BUILD.bazel create mode 100644 optimizer/src/main/java/dev/cel/optimizer/BUILD.bazel create mode 100644 optimizer/src/main/java/dev/cel/optimizer/CelAstOptimizer.java create mode 100644 optimizer/src/main/java/dev/cel/optimizer/CelOptimizer.java create mode 100644 optimizer/src/main/java/dev/cel/optimizer/CelOptimizerBuilder.java create mode 100644 optimizer/src/main/java/dev/cel/optimizer/CelOptimizerFactory.java create mode 100644 optimizer/src/main/java/dev/cel/optimizer/CelOptimizerImpl.java create mode 100644 optimizer/src/test/java/dev/cel/optimizer/BUILD.bazel create mode 100644 optimizer/src/test/java/dev/cel/optimizer/CelOptimizerFactoryTest.java create mode 100644 optimizer/src/test/java/dev/cel/optimizer/CelOptimizerImplTest.java diff --git a/optimizer/BUILD.bazel b/optimizer/BUILD.bazel new file mode 100644 index 00000000..e5060d65 --- /dev/null +++ b/optimizer/BUILD.bazel @@ -0,0 +1,26 @@ +package( + default_applicable_licenses = ["//:license"], + default_visibility = ["//visibility:public"], # TODO: Expose to public +) + +java_library( + name = "optimizer", + exports = ["//optimizer/src/main/java/dev/cel/optimizer"], +) + +java_library( + name = "optimizer_builder", + exports = ["//optimizer/src/main/java/dev/cel/optimizer:optimizer_builder"], +) + +java_library( + name = "ast_optimizer", + exports = ["//optimizer/src/main/java/dev/cel/optimizer:ast_optimizer"], +) + +java_library( + name = "optimizer_impl", + testonly = 1, + visibility = ["//optimizer/src/test/java/dev/cel/optimizer:__pkg__"], + exports = ["//optimizer/src/main/java/dev/cel/optimizer:optimizer_impl"], +) diff --git a/optimizer/src/main/java/dev/cel/optimizer/BUILD.bazel b/optimizer/src/main/java/dev/cel/optimizer/BUILD.bazel new file mode 100644 index 00000000..888efa8b --- /dev/null +++ b/optimizer/src/main/java/dev/cel/optimizer/BUILD.bazel @@ -0,0 +1,71 @@ +package( + default_applicable_licenses = ["//:license"], + default_visibility = [ + "//visibility:public", + ], +) + +java_library( + name = "optimizer", + srcs = [ + "CelOptimizerFactory.java", + ], + tags = [ + ], + deps = [ + ":optimizer_impl", + "//bundle:cel", + "//checker:checker_builder", + "//compiler", + "//compiler:compiler_builder", + "//optimizer:optimizer_builder", + "//parser:parser_builder", + "//runtime", + ], +) + +java_library( + name = "optimizer_builder", + srcs = [ + "CelOptimizer.java", + "CelOptimizerBuilder.java", + ], + tags = [ + ], + deps = [ + ":ast_optimizer", + "//common", + "//common:compiler_common", + "@maven//:com_google_errorprone_error_prone_annotations", + ], +) + +java_library( + name = "optimizer_impl", + srcs = [ + "CelOptimizerImpl.java", + ], + tags = [ + ], + deps = [ + ":ast_optimizer", + ":optimizer_builder", + "//bundle:cel", + "//common", + "//common:compiler_common", + "//common/navigation", + "@maven//:com_google_guava_guava", + ], +) + +java_library( + name = "ast_optimizer", + srcs = ["CelAstOptimizer.java"], + tags = [ + ], + deps = [ + "//bundle:cel", + "//common", + "//common/navigation", + ], +) diff --git a/optimizer/src/main/java/dev/cel/optimizer/CelAstOptimizer.java b/optimizer/src/main/java/dev/cel/optimizer/CelAstOptimizer.java new file mode 100644 index 00000000..8dc80f15 --- /dev/null +++ b/optimizer/src/main/java/dev/cel/optimizer/CelAstOptimizer.java @@ -0,0 +1,28 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.optimizer; + +import dev.cel.bundle.Cel; +import dev.cel.common.CelAbstractSyntaxTree; +import dev.cel.common.navigation.CelNavigableAst; + +/** Public interface for performing a single, custom optimization on an AST. */ +public interface CelAstOptimizer { + + /** + * Optimizes a single AST. + **/ + CelAbstractSyntaxTree optimize(CelNavigableAst navigableAst, Cel cel); +} diff --git a/optimizer/src/main/java/dev/cel/optimizer/CelOptimizer.java b/optimizer/src/main/java/dev/cel/optimizer/CelOptimizer.java new file mode 100644 index 00000000..2faa18e3 --- /dev/null +++ b/optimizer/src/main/java/dev/cel/optimizer/CelOptimizer.java @@ -0,0 +1,38 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.optimizer; + +import dev.cel.common.CelAbstractSyntaxTree; +import dev.cel.common.CelValidationException; + +/** Public interface for optimizing an AST. */ +public interface CelOptimizer { + + /** + * Performs custom optimization of the provided AST. + * + *

This invokes all the AST optimizers present in this CelOptimizer instance via {@link + * CelOptimizerBuilder#addAstOptimizers} in their added order. Any exceptions thrown within the + * AST optimizer will be propagated to the caller and will abort the optimization process. + * + *

Note that the produced expression string from unparsing an optimized AST will likely not be + * equal to the original expression. + * + * @param ast A type-checked AST. + * @throws CelValidationException If the optimized AST fails to type-check after a single + * optimization pass. + */ + CelAbstractSyntaxTree optimize(CelAbstractSyntaxTree ast) throws CelValidationException; +} diff --git a/optimizer/src/main/java/dev/cel/optimizer/CelOptimizerBuilder.java b/optimizer/src/main/java/dev/cel/optimizer/CelOptimizerBuilder.java new file mode 100644 index 00000000..abfed8f3 --- /dev/null +++ b/optimizer/src/main/java/dev/cel/optimizer/CelOptimizerBuilder.java @@ -0,0 +1,34 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.optimizer; + +import com.google.errorprone.annotations.CanIgnoreReturnValue; +import com.google.errorprone.annotations.CheckReturnValue; + +/** Interface for building an instance of CelOptimizer. */ +public interface CelOptimizerBuilder { + + /** Adds one or more optimizer to perform custom AST optimizations. */ + @CanIgnoreReturnValue + CelOptimizerBuilder addAstOptimizers(CelAstOptimizer... astOptimizers); + + /** Adds one or more optimizer to perform custom AST optimizations. */ + @CanIgnoreReturnValue + CelOptimizerBuilder addAstOptimizers(Iterable astOptimizers); + + /** Build a new instance of the {@link CelOptimizer}. */ + @CheckReturnValue + CelOptimizer build(); +} diff --git a/optimizer/src/main/java/dev/cel/optimizer/CelOptimizerFactory.java b/optimizer/src/main/java/dev/cel/optimizer/CelOptimizerFactory.java new file mode 100644 index 00000000..1ebfd293 --- /dev/null +++ b/optimizer/src/main/java/dev/cel/optimizer/CelOptimizerFactory.java @@ -0,0 +1,47 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.optimizer; + +import dev.cel.bundle.Cel; +import dev.cel.bundle.CelFactory; +import dev.cel.checker.CelChecker; +import dev.cel.compiler.CelCompiler; +import dev.cel.compiler.CelCompilerFactory; +import dev.cel.parser.CelParser; +import dev.cel.runtime.CelRuntime; + +/** Factory class for constructing an {@link CelOptimizer} instance. */ +public final class CelOptimizerFactory { + + /** Create a new builder for constructing a {@link CelOptimizer} instance. */ + public static CelOptimizerBuilder standardCelOptimizerBuilder(Cel cel) { + return CelOptimizerImpl.newBuilder(cel); + } + + /** Create a new builder for constructing a {@link CelOptimizer} instance. */ + public static CelOptimizerBuilder standardCelOptimizerBuilder( + CelCompiler celCompiler, CelRuntime celRuntime) { + return standardCelOptimizerBuilder(CelFactory.combine(celCompiler, celRuntime)); + } + + /** Create a new builder for constructing a {@link CelOptimizer} instance. */ + public static CelOptimizerBuilder standardCelOptimizerBuilder( + CelParser celParser, CelChecker celChecker, CelRuntime celRuntime) { + return standardCelOptimizerBuilder( + CelCompilerFactory.combine(celParser, celChecker), celRuntime); + } + + private CelOptimizerFactory() {} +} diff --git a/optimizer/src/main/java/dev/cel/optimizer/CelOptimizerImpl.java b/optimizer/src/main/java/dev/cel/optimizer/CelOptimizerImpl.java new file mode 100644 index 00000000..e5049011 --- /dev/null +++ b/optimizer/src/main/java/dev/cel/optimizer/CelOptimizerImpl.java @@ -0,0 +1,84 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.optimizer; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.collect.ImmutableSet; +import dev.cel.bundle.Cel; +import dev.cel.common.CelAbstractSyntaxTree; +import dev.cel.common.CelValidationException; +import dev.cel.common.navigation.CelNavigableAst; +import java.util.Arrays; + +final class CelOptimizerImpl implements CelOptimizer { + private final Cel cel; + private final ImmutableSet astOptimizers; + + CelOptimizerImpl(Cel cel, ImmutableSet astOptimizers) { + this.cel = cel; + this.astOptimizers = astOptimizers; + } + + @Override + public CelAbstractSyntaxTree optimize(CelAbstractSyntaxTree ast) throws CelValidationException { + if (!ast.isChecked()) { + throw new IllegalArgumentException("AST must be type-checked."); + } + + CelAbstractSyntaxTree optimizedAst = ast; + for (CelAstOptimizer optimizer : astOptimizers) { + CelNavigableAst navigableAst = CelNavigableAst.fromAst(ast); + optimizedAst = optimizer.optimize(navigableAst, cel); + optimizedAst = cel.check(optimizedAst).getAst(); + } + + return optimizedAst; + } + + /** Create a new builder for constructing a {@link CelOptimizer} instance. */ + static CelOptimizerImpl.Builder newBuilder(Cel cel) { + return new CelOptimizerImpl.Builder(cel); + } + + /** Builder class for {@link CelOptimizerImpl}. */ + static final class Builder implements CelOptimizerBuilder { + private final Cel cel; + private final ImmutableSet.Builder astOptimizers; + + private Builder(Cel cel) { + this.cel = cel; + this.astOptimizers = ImmutableSet.builder(); + } + + @Override + public CelOptimizerBuilder addAstOptimizers(CelAstOptimizer... astOptimizers) { + checkNotNull(astOptimizers); + return addAstOptimizers(Arrays.asList(astOptimizers)); + } + + @Override + public CelOptimizerBuilder addAstOptimizers(Iterable astOptimizers) { + checkNotNull(astOptimizers); + this.astOptimizers.addAll(astOptimizers); + return this; + } + + @Override + public CelOptimizer build() { + return new CelOptimizerImpl(cel, astOptimizers.build()); + } + } +} diff --git a/optimizer/src/test/java/dev/cel/optimizer/BUILD.bazel b/optimizer/src/test/java/dev/cel/optimizer/BUILD.bazel new file mode 100644 index 00000000..99f5babd --- /dev/null +++ b/optimizer/src/test/java/dev/cel/optimizer/BUILD.bazel @@ -0,0 +1,32 @@ +load("//:testing.bzl", "junit4_test_suites") + +package(default_applicable_licenses = ["//:license"]) + +java_library( + name = "tests", + testonly = 1, + srcs = glob(["*.java"]), + deps = [ + "//:java_truth", + "//bundle:cel", + "//common", + "//common:compiler_common", + "//common/ast", + "//compiler", + "//optimizer", + "//optimizer:optimizer_builder", + "//optimizer:optimizer_impl", + "//parser", + "//runtime", + "@maven//:junit_junit", + ], +) + +junit4_test_suites( + name = "test_suites", + sizes = [ + "small", + ], + src_dir = "src/test/java", + deps = [":tests"], +) diff --git a/optimizer/src/test/java/dev/cel/optimizer/CelOptimizerFactoryTest.java b/optimizer/src/test/java/dev/cel/optimizer/CelOptimizerFactoryTest.java new file mode 100644 index 00000000..41c7ecd7 --- /dev/null +++ b/optimizer/src/test/java/dev/cel/optimizer/CelOptimizerFactoryTest.java @@ -0,0 +1,61 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.optimizer; + +import static com.google.common.truth.Truth.assertThat; + +import dev.cel.bundle.CelFactory; +import dev.cel.compiler.CelCompilerFactory; +import dev.cel.parser.CelParserFactory; +import dev.cel.runtime.CelRuntimeFactory; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class CelOptimizerFactoryTest { + + @Test + public void standardCelOptimizerBuilder_withParserCheckerAndRuntime() { + CelOptimizerBuilder builder = + CelOptimizerFactory.standardCelOptimizerBuilder( + CelParserFactory.standardCelParserBuilder().build(), + CelCompilerFactory.standardCelCheckerBuilder().build(), + CelRuntimeFactory.standardCelRuntimeBuilder().build()); + + assertThat(builder).isNotNull(); + assertThat(builder.build()).isNotNull(); + } + + @Test + public void standardCelOptimizerBuilder_withCompilerAndRuntime() { + CelOptimizerBuilder builder = + CelOptimizerFactory.standardCelOptimizerBuilder( + CelCompilerFactory.standardCelCompilerBuilder().build(), + CelRuntimeFactory.standardCelRuntimeBuilder().build()); + + assertThat(builder).isNotNull(); + assertThat(builder.build()).isNotNull(); + } + + @Test + public void standardCelOptimizerBuilder_withCel() { + CelOptimizerBuilder builder = + CelOptimizerFactory.standardCelOptimizerBuilder(CelFactory.standardCelBuilder().build()); + + assertThat(builder).isNotNull(); + assertThat(builder.build()).isNotNull(); + } +} diff --git a/optimizer/src/test/java/dev/cel/optimizer/CelOptimizerImplTest.java b/optimizer/src/test/java/dev/cel/optimizer/CelOptimizerImplTest.java new file mode 100644 index 00000000..903e726c --- /dev/null +++ b/optimizer/src/test/java/dev/cel/optimizer/CelOptimizerImplTest.java @@ -0,0 +1,126 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.optimizer; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import dev.cel.bundle.Cel; +import dev.cel.bundle.CelFactory; +import dev.cel.common.CelAbstractSyntaxTree; +import dev.cel.common.CelSource; +import dev.cel.common.CelValidationException; +import dev.cel.common.ast.CelExpr; +import java.util.ArrayList; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class CelOptimizerImplTest { + + private static final Cel CEL = CelFactory.standardCelBuilder().build(); + + @Test + public void constructCelOptimizer_success() { + CelOptimizer celOptimizer = + CelOptimizerImpl.newBuilder(CEL) + .addAstOptimizers( + (navigableAst, cel) -> + // no-op + navigableAst.getAst()) + .build(); + + assertThat(celOptimizer).isNotNull(); + assertThat(celOptimizer).isInstanceOf(CelOptimizerImpl.class); + } + + @Test + public void astOptimizers_invokedInOrder() throws Exception { + List list = new ArrayList<>(); + + CelOptimizer celOptimizer = + CelOptimizerImpl.newBuilder(CEL) + .addAstOptimizers( + (navigableAst, cel) -> { + list.add(1); + return navigableAst.getAst(); + }) + .addAstOptimizers( + (navigableAst, cel) -> { + list.add(2); + return navigableAst.getAst(); + }) + .addAstOptimizers( + (navigableAst, cel) -> { + list.add(3); + return navigableAst.getAst(); + }) + .build(); + + CelAbstractSyntaxTree ast = celOptimizer.optimize(CEL.compile("'hello world'").getAst()); + + assertThat(ast).isNotNull(); + assertThat(list).containsExactly(1, 2, 3).inOrder(); + } + + @Test + public void optimizer_whenAstOptimizerThrows_throwsException() { + CelOptimizer celOptimizer = + CelOptimizerImpl.newBuilder(CEL) + .addAstOptimizers( + (navigableAst, cel) -> { + throw new IllegalArgumentException("Test exception"); + }) + .build(); + + IllegalArgumentException e = + assertThrows( + IllegalArgumentException.class, + () -> celOptimizer.optimize(CEL.compile("'hello world'").getAst())); + assertThat(e).hasMessageThat().isEqualTo("Test exception"); + } + + @Test + public void parsedAst_throwsException() { + CelOptimizer celOptimizer = CelOptimizerImpl.newBuilder(CEL).build(); + + IllegalArgumentException e = + assertThrows( + IllegalArgumentException.class, + () -> celOptimizer.optimize(CEL.parse("'test'").getAst())); + assertThat(e).hasMessageThat().contains("AST must be type-checked."); + } + + @Test + public void optimizedAst_failsToTypeCheck_throwsException() { + CelOptimizer celOptimizer = + CelOptimizerImpl.newBuilder(CEL) + .addAstOptimizers( + (navigableAst, cel) -> + CelAbstractSyntaxTree.newParsedAst( + CelExpr.ofIdentExpr(1, "undeclared_ident"), CelSource.newBuilder().build())) + .build(); + + CelValidationException e = + assertThrows( + CelValidationException.class, + () -> celOptimizer.optimize(CEL.compile("'hello world'").getAst())); + assertThat(e) + .hasMessageThat() + .contains("ERROR: :1:1: undeclared reference to 'undeclared_ident' (in container '')"); + } +} diff --git a/validator/src/main/java/dev/cel/validator/validators/DurationLiteralValidator.java b/validator/src/main/java/dev/cel/validator/validators/DurationLiteralValidator.java index 622bc2e1..349374ca 100644 --- a/validator/src/main/java/dev/cel/validator/validators/DurationLiteralValidator.java +++ b/validator/src/main/java/dev/cel/validator/validators/DurationLiteralValidator.java @@ -17,7 +17,7 @@ import com.google.protobuf.Duration; /** DurationLiteralValidator ensures that duration literal arguments are valid. */ -public class DurationLiteralValidator extends LiteralValidator { +public final class DurationLiteralValidator extends LiteralValidator { public static final DurationLiteralValidator INSTANCE = new DurationLiteralValidator("duration", Duration.class); diff --git a/validator/src/main/java/dev/cel/validator/validators/HomogeneousLiteralValidator.java b/validator/src/main/java/dev/cel/validator/validators/HomogeneousLiteralValidator.java index db787d89..a6d64131 100644 --- a/validator/src/main/java/dev/cel/validator/validators/HomogeneousLiteralValidator.java +++ b/validator/src/main/java/dev/cel/validator/validators/HomogeneousLiteralValidator.java @@ -34,7 +34,7 @@ * HomogeneousLiteralValidator checks that all list and map literals entries have the same types, * i.e. no mixed list element types or mixed map key or map value types. */ -public class HomogeneousLiteralValidator implements CelAstValidator { +public final class HomogeneousLiteralValidator implements CelAstValidator { private final ImmutableSet exemptFunctions; /** diff --git a/validator/src/main/java/dev/cel/validator/validators/RegexLiteralValidator.java b/validator/src/main/java/dev/cel/validator/validators/RegexLiteralValidator.java index 6c1ac143..fc79083c 100644 --- a/validator/src/main/java/dev/cel/validator/validators/RegexLiteralValidator.java +++ b/validator/src/main/java/dev/cel/validator/validators/RegexLiteralValidator.java @@ -24,7 +24,7 @@ import java.util.regex.PatternSyntaxException; /** RegexLiteralValidator ensures that regex patterns are valid. */ -public class RegexLiteralValidator implements CelAstValidator { +public final class RegexLiteralValidator implements CelAstValidator { public static final RegexLiteralValidator INSTANCE = new RegexLiteralValidator(); @Override diff --git a/validator/src/main/java/dev/cel/validator/validators/TimestampLiteralValidator.java b/validator/src/main/java/dev/cel/validator/validators/TimestampLiteralValidator.java index bc179c97..4f6a5209 100644 --- a/validator/src/main/java/dev/cel/validator/validators/TimestampLiteralValidator.java +++ b/validator/src/main/java/dev/cel/validator/validators/TimestampLiteralValidator.java @@ -17,7 +17,7 @@ import com.google.protobuf.Timestamp; /** TimestampLiteralValidator ensures that timestamp literal arguments are valid. */ -public class TimestampLiteralValidator extends LiteralValidator { +public final class TimestampLiteralValidator extends LiteralValidator { public static final TimestampLiteralValidator INSTANCE = new TimestampLiteralValidator("timestamp", Timestamp.class); diff --git a/validator/src/test/java/dev/cel/validator/CelValidatorImplTest.java b/validator/src/test/java/dev/cel/validator/CelValidatorImplTest.java index 495b10e9..521faa9d 100644 --- a/validator/src/test/java/dev/cel/validator/CelValidatorImplTest.java +++ b/validator/src/test/java/dev/cel/validator/CelValidatorImplTest.java @@ -31,8 +31,6 @@ public class CelValidatorImplTest { private static final Cel CEL = CelFactory.standardCelBuilder().build(); - // private static final CelValidatorImpl CEL_VALIDATOR = new CelValidatorImpl(CEL, - @Test public void constructCelValidator_success() { CelValidator celValidator =