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 =