Skip to content

Commit

Permalink
Add evaluation listener
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 569010652
  • Loading branch information
l46kok authored and copybara-github committed Sep 28, 2023
1 parent 817b335 commit 6750212
Show file tree
Hide file tree
Showing 12 changed files with 316 additions and 48 deletions.
1 change: 1 addition & 0 deletions bundle/src/main/java/dev/cel/bundle/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ java_library(
"//parser:macro",
"//parser:parser_builder",
"//runtime",
"//runtime:evaluation_listener",
"@cel_spec//proto/cel/expr:expr_java_proto",
"@maven//:com_google_code_findbugs_annotations",
"@maven//:com_google_errorprone_error_prone_annotations",
Expand Down
5 changes: 5 additions & 0 deletions bundle/src/main/java/dev/cel/bundle/CelBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import dev.cel.compiler.CelCompilerLibrary;
import dev.cel.parser.CelMacro;
import dev.cel.parser.CelStandardMacro;
import dev.cel.runtime.CelEvaluationListener;
import dev.cel.runtime.CelRuntime;
import dev.cel.runtime.CelRuntimeLibrary;
import java.util.function.Function;
Expand Down Expand Up @@ -282,6 +283,10 @@ public interface CelBuilder {
@CanIgnoreReturnValue
CelBuilder addRuntimeLibraries(Iterable<CelRuntimeLibrary> libraries);

/** Adds a listener that gets invoked as evaluation progresses through the AST. */
@CanIgnoreReturnValue
CelBuilder addEvaluationListener(CelEvaluationListener listener);

/** Construct a new {@code Cel} instance from the provided configuration. */
Cel build();
}
8 changes: 8 additions & 0 deletions bundle/src/main/java/dev/cel/bundle/CelImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import dev.cel.parser.CelParserBuilder;
import dev.cel.parser.CelStandardMacro;
import dev.cel.runtime.CelEvaluationException;
import dev.cel.runtime.CelEvaluationListener;
import dev.cel.runtime.CelRuntime;
import dev.cel.runtime.CelRuntimeBuilder;
import dev.cel.runtime.CelRuntimeLegacyImpl;
Expand Down Expand Up @@ -339,6 +340,13 @@ public Builder addRuntimeLibraries(Iterable<CelRuntimeLibrary> libraries) {
return this;
}

@Override
public CelBuilder addEvaluationListener(CelEvaluationListener listener) {
checkNotNull(listener);
runtimeBuilder.addEvaluationListener(listener);
return this;
}

@Override
public Cel build() {
return new CelImpl(
Expand Down
2 changes: 0 additions & 2 deletions common/src/main/java/dev/cel/common/CelDescriptorUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

package dev.cel.common;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.protobuf.DescriptorProtos.FileDescriptorSet;
Expand Down Expand Up @@ -63,7 +62,6 @@ public static ImmutableSet<FileDescriptor> getFileDescriptorsForDescriptors(
* <p>Warning: This will produce unique FileDescriptor instances. Use with care especially in
* hermetic environments.
*/
@VisibleForTesting
public static ImmutableSet<FileDescriptor> getFileDescriptorsFromFileDescriptorSet(
FileDescriptorSet fileDescriptorSet) {
return FileDescriptorSetConverter.convert(fileDescriptorSet);
Expand Down
5 changes: 5 additions & 0 deletions runtime/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,8 @@ java_library(
name = "interpreter_util",
exports = ["//runtime/src/main/java/dev/cel/runtime:interpreter_util"],
)

java_library(
name = "evaluation_listener",
exports = ["//runtime/src/main/java/dev/cel/runtime:evaluation_listener"],
)
17 changes: 14 additions & 3 deletions runtime/src/main/java/dev/cel/runtime/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ java_library(
exports = [":base"],
deps = [
":base",
":evaluation_listener",
":runtime_helper",
":unknown_attributes",
"//:auto_value",
Expand All @@ -85,7 +86,6 @@ java_library(
"//common/ast",
"//common/internal:dynamic_proto",
"//common/types:type_providers",
"//runtime:unknown_attributes",
"@cel_spec//proto/cel/expr:expr_java_proto",
"@maven//:com_google_code_findbugs_annotations",
"@maven//:com_google_errorprone_error_prone_annotations",
Expand Down Expand Up @@ -142,14 +142,14 @@ java_library(
],
deps = [
":base",
":interpreter",
":unknown_attributes",
":evaluation_listener",
"//:auto_value",
"//common",
"//common:error_codes",
"//common:options",
"//common/annotations",
"//common/internal:dynamic_proto",
"//runtime:interpreter",
"//runtime:unknown_attributes",
"@maven//:com_google_code_findbugs_annotations",
"@maven//:com_google_errorprone_error_prone_annotations",
Expand Down Expand Up @@ -216,3 +216,14 @@ java_library(
"@maven//:org_jspecify_jspecify",
],
)

java_library(
name = "evaluation_listener",
srcs = ["CelEvaluationListener.java"],
tags = [
],
deps = [
"//common/ast",
"@maven//:com_google_errorprone_error_prone_annotations",
],
)
37 changes: 37 additions & 0 deletions runtime/src/main/java/dev/cel/runtime/CelEvaluationListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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.runtime;

import com.google.errorprone.annotations.Immutable;
import dev.cel.common.ast.CelExpr;

/** Functional interface for a callback method invoked by the runtime. */
@FunctionalInterface
@Immutable
public interface CelEvaluationListener {

/**
* Callback method invoked by the CEL runtime as evaluation progresses through the AST.
*
* @param expr CelExpr that was evaluated to produce the evaluated result.
* @param evaluatedResult Evaluated result.
*/
void callback(CelExpr expr, Object evaluatedResult);

/** Construct a listener that does nothing. */
static CelEvaluationListener noOpListener() {
return (arg1, arg2) -> {};
}
}
4 changes: 4 additions & 0 deletions runtime/src/main/java/dev/cel/runtime/CelRuntimeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ public interface CelRuntimeBuilder {
@CanIgnoreReturnValue
CelRuntimeBuilder addLibraries(Iterable<? extends CelRuntimeLibrary> libraries);

/** Adds a listener that gets invoked as evaluation progresses through the AST. */
@CanIgnoreReturnValue
CelRuntimeBuilder addEvaluationListener(CelEvaluationListener listener);

/** Build a new instance of the {@code CelRuntime}. */
@CheckReturnValue
CelRuntime build();
Expand Down
25 changes: 12 additions & 13 deletions runtime/src/main/java/dev/cel/runtime/CelRuntimeLegacyImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,92 +74,81 @@ public static final class Builder implements CelRuntimeBuilder {

private boolean standardEnvironmentEnabled;
private Function<String, Message.Builder> customTypeFactory;
private CelEvaluationListener evaluationListener;

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder setOptions(CelOptions options) {
this.options = options;
return this;
}

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder addFunctionBindings(CelFunctionBinding... bindings) {
return addFunctionBindings(Arrays.asList(bindings));
}

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder addFunctionBindings(Iterable<CelFunctionBinding> bindings) {
bindings.forEach(o -> functionBindings.put(o.getOverloadId(), o));
return this;
}

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder addMessageTypes(Descriptor... descriptors) {
return addMessageTypes(Arrays.asList(descriptors));
}

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder addMessageTypes(Iterable<Descriptor> descriptors) {
return addFileTypes(CelDescriptorUtil.getFileDescriptorsForDescriptors(descriptors));
}

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder addFileTypes(FileDescriptor... fileDescriptors) {
return addFileTypes(Arrays.asList(fileDescriptors));
}

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder addFileTypes(Iterable<FileDescriptor> fileDescriptors) {
this.fileTypes.addAll(checkNotNull(fileDescriptors));
return this;
}

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder addFileTypes(FileDescriptorSet fileDescriptorSet) {
return addFileTypes(
CelDescriptorUtil.getFileDescriptorsFromFileDescriptorSet(fileDescriptorSet));
}

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder setTypeFactory(Function<String, Message.Builder> typeFactory) {
this.customTypeFactory = typeFactory;
return this;
}

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder setStandardEnvironmentEnabled(boolean value) {
standardEnvironmentEnabled = value;
return this;
}

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder addLibraries(CelRuntimeLibrary... libraries) {
checkNotNull(libraries);
return this.addLibraries(Arrays.asList(libraries));
}

/** {@inheritDoc} */
@Override
@CanIgnoreReturnValue
public Builder addLibraries(Iterable<? extends CelRuntimeLibrary> libraries) {
Expand All @@ -168,6 +157,14 @@ public Builder addLibraries(Iterable<? extends CelRuntimeLibrary> libraries) {
return this;
}

@Override
@CanIgnoreReturnValue
public CelRuntimeBuilder addEvaluationListener(CelEvaluationListener listener) {
checkNotNull(listener);
this.evaluationListener = listener;
return this;
}

/** Build a new {@code CelRuntimeLegacyImpl} instance from the builder config. */
@Override
@CanIgnoreReturnValue
Expand Down Expand Up @@ -232,7 +229,8 @@ public CelRuntimeLegacyImpl build() {
new DefaultInterpreter(
new DescriptorMessageProvider(runtimeTypeFactory, dynamicProto, options),
dispatcher,
options),
options,
evaluationListener),
options);
}

Expand All @@ -252,6 +250,7 @@ private Builder() {
this.messageTypes = ImmutableSet.builder();
this.functionBindings = ImmutableMap.builder();
this.celRuntimeLibraries = ImmutableSet.builder();
this.evaluationListener = CelEvaluationListener.noOpListener();
this.customTypeFactory = null;
}
}
Expand Down
Loading

0 comments on commit 6750212

Please sign in to comment.