Skip to content

Commit 1948e2e

Browse files
l46kokcopybara-github
authored andcommitted
Internal Changes
PiperOrigin-RevId: 910292784
1 parent d08c424 commit 1948e2e

16 files changed

Lines changed: 235 additions & 132 deletions

File tree

bundle/src/main/java/dev/cel/bundle/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ java_library(
104104
":required_fields_checker",
105105
"//:auto_value",
106106
"//bundle:cel",
107+
"//checker:proto_type_mask",
107108
"//checker:standard_decl",
108109
"//common:compiler_common",
109110
"//common:container",

bundle/src/main/java/dev/cel/bundle/CelEnvironment.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import dev.cel.checker.CelStandardDeclarations;
3131
import dev.cel.checker.CelStandardDeclarations.StandardFunction;
3232
import dev.cel.checker.CelStandardDeclarations.StandardOverload;
33+
import dev.cel.checker.ProtoTypeMask;
3334
import dev.cel.common.CelContainer;
3435
import dev.cel.common.CelFunctionDecl;
3536
import dev.cel.common.CelOptions;
@@ -134,6 +135,9 @@ public abstract class CelEnvironment {
134135
/** Limits to set in the environment. */
135136
public abstract ImmutableSet<Limit> limits();
136137

138+
/** Context variable to enable in the environment. */
139+
public abstract Optional<ContextVariable> contextVariable();
140+
137141
/** Builder for {@link CelEnvironment}. */
138142
@AutoValue.Builder
139143
public abstract static class Builder {
@@ -199,6 +203,8 @@ public Builder setLimits(Limit... limits) {
199203

200204
public abstract Builder setLimits(ImmutableSet<Limit> limits);
201205

206+
public abstract Builder setContextVariable(ContextVariable contextVariable);
207+
202208
abstract CelEnvironment autoBuild();
203209

204210
@CheckReturnValue
@@ -258,6 +264,12 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
258264

259265
applyStandardLibrarySubset(compilerBuilder);
260266

267+
contextVariable()
268+
.ifPresent(
269+
cv ->
270+
compilerBuilder.addProtoTypeMasks(
271+
ProtoTypeMask.ofAllFields(cv.typeName()).withFieldsAsVariableDeclarations()));
272+
261273
return compilerBuilder.build();
262274
} catch (RuntimeException e) {
263275
throw new CelEnvironmentException(e.getMessage(), e);
@@ -406,6 +418,17 @@ private static CanonicalCelExtension getExtensionOrThrow(String extensionName) {
406418
return extension;
407419
}
408420

421+
/** Represents a context variable declaration. */
422+
@AutoValue
423+
public abstract static class ContextVariable {
424+
/** Fully qualified type name of the context variable. */
425+
public abstract String typeName();
426+
427+
public static ContextVariable create(String typeName) {
428+
return new AutoValue_CelEnvironment_ContextVariable(typeName);
429+
}
430+
}
431+
409432
/** Represents a policy variable declaration. */
410433
@AutoValue
411434
public abstract static class VariableDecl {

bundle/src/main/java/dev/cel/bundle/CelEnvironmentYamlParser.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.google.common.collect.ImmutableSet;
2929
import com.google.errorprone.annotations.CanIgnoreReturnValue;
3030
import dev.cel.bundle.CelEnvironment.Alias;
31+
import dev.cel.bundle.CelEnvironment.ContextVariable;
3132
import dev.cel.bundle.CelEnvironment.ExtensionConfig;
3233
import dev.cel.bundle.CelEnvironment.FunctionDecl;
3334
import dev.cel.bundle.CelEnvironment.LibrarySubset;
@@ -320,6 +321,36 @@ private ImmutableSet<String> parseAbbreviations(ParserContext<Node> ctx, Node no
320321
return builder.build();
321322
}
322323

324+
private ContextVariable parseContextVariable(ParserContext<Node> ctx, Node node) {
325+
long id = ctx.collectMetadata(node);
326+
if (!assertYamlType(ctx, id, node, YamlNodeType.MAP)) {
327+
return ContextVariable.create("");
328+
}
329+
330+
MappingNode mapNode = (MappingNode) node;
331+
String typeName = "";
332+
for (NodeTuple nodeTuple : mapNode.getValue()) {
333+
Node keyNode = nodeTuple.getKeyNode();
334+
long keyId = ctx.collectMetadata(keyNode);
335+
Node valueNode = nodeTuple.getValueNode();
336+
String keyName = ((ScalarNode) keyNode).getValue();
337+
switch (keyName) {
338+
case "type_name":
339+
typeName = newString(ctx, valueNode);
340+
break;
341+
default:
342+
ctx.reportError(keyId, String.format("Unsupported context_variable tag: %s", keyName));
343+
break;
344+
}
345+
}
346+
347+
if (typeName.isEmpty()) {
348+
ctx.reportError(id, "Missing required attribute(s): type_name");
349+
}
350+
351+
return ContextVariable.create(typeName);
352+
}
353+
323354
private ImmutableSet<VariableDecl> parseVariables(ParserContext<Node> ctx, Node node) {
324355
long valueId = ctx.collectMetadata(node);
325356
ImmutableSet.Builder<VariableDecl> variableSetBuilder = ImmutableSet.builder();
@@ -900,6 +931,9 @@ private CelEnvironment.Builder parseConfig(ParserContext<Node> ctx, Node node) {
900931
case "limits":
901932
builder.setLimits(parseLimits(ctx, valueNode));
902933
break;
934+
case "context_variable":
935+
builder.setContextVariable(parseContextVariable(ctx, valueNode));
936+
break;
903937
default:
904938
ctx.reportError(id, "Unknown config tag: " + fieldName);
905939
// continue handling the rest of the nodes

conformance/src/test/java/dev/cel/conformance/policy/BUILD.bazel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ java_library(
1212
deps = [
1313
"//:auto_value",
1414
"//bundle:cel",
15+
"//common/formats:value_string",
16+
"//common/formats:yaml_helper",
17+
"//policy",
18+
"//policy:parser",
19+
"//policy:parser_factory",
20+
"//policy:policy_parser_context",
21+
"//policy:test_policy_helper",
1522
"//runtime:function_binding",
1623
"//testing/testrunner:cel_expression_source",
1724
"//testing/testrunner:cel_test_context",
@@ -23,5 +30,6 @@ java_library(
2330
"@maven//:com_google_guava_guava",
2431
"@maven//:com_google_protobuf_protobuf_java",
2532
"@maven//:junit_junit",
33+
"@maven//:org_yaml_snakeyaml",
2634
],
2735
)

conformance/src/test/java/dev/cel/conformance/policy/PolicyConformanceTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import dev.cel.bundle.Cel;
1919
import dev.cel.bundle.CelFactory;
2020
import dev.cel.expr.conformance.proto3.TestAllTypes;
21+
import dev.cel.policy.CelPolicyParserFactory;
22+
import dev.cel.policy.K8sTagHandler;
2123
import dev.cel.runtime.CelFunctionBinding;
2224
import dev.cel.testing.testrunner.CelExpressionSource;
2325
import dev.cel.testing.testrunner.CelTestContext;
@@ -77,6 +79,13 @@ public void evaluate() throws Throwable {
7779
TestAllTypes.getDescriptor().getFile(),
7880
Struct.getDescriptor().getFile());
7981

82+
// Scopes the custom Kubernetes tag visitor exclusively to k8s tests to prevent non-standard
83+
// grammar leakage.
84+
if (name.startsWith("k8s/")) {
85+
contextBuilder.setCelPolicyParser(
86+
CelPolicyParserFactory.newYamlParserBuilder().addTagVisitor(new K8sTagHandler()).build());
87+
}
88+
8089
Path yamlConfigPath = Paths.get(dirPath, "config.yaml");
8190
Path textprotoConfigPath = Paths.get(dirPath, "config.textproto");
8291

policy/BUILD.bazel

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,9 @@ java_library(
5959
name = "compiler_builder",
6060
exports = ["//policy/src/main/java/dev/cel/policy:compiler_builder"],
6161
)
62+
63+
java_library(
64+
name = "test_policy_helper",
65+
testonly = True,
66+
exports = ["//policy/src/test/java/dev/cel/policy:tests"],
67+
)

policy/src/main/java/dev/cel/policy/CelPolicy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ public abstract static class Builder implements RequiredFieldsChecker {
252252

253253
abstract Optional<Long> id();
254254

255-
abstract Optional<Result> result();
255+
public abstract Optional<Result> result();
256256

257257
abstract Optional<ValueString> explanation();
258258

policy/src/test/java/dev/cel/policy/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ java_library(
1010
resources = [
1111
"//testing:policy_test_resources",
1212
],
13+
tags = ["alt_dep=//policy:test_policy_helper"],
14+
visibility = ["//policy:__pkg__"],
1315
deps = [
1416
"//:java_truth",
1517
"//bundle:cel",
@@ -18,6 +20,7 @@ java_library(
1820
"//common:cel_ast",
1921
"//common:options",
2022
"//common/formats:value_string",
23+
"//common/formats:yaml_helper",
2124
"//common/internal",
2225
"//common/resources/testdata/proto3:standalone_global_enum_java_proto",
2326
"//common/types",

policy/src/test/java/dev/cel/policy/CelPolicyCompilerImplTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import dev.cel.extensions.CelOptionalLibrary;
3838
import dev.cel.parser.CelStandardMacro;
3939
import dev.cel.parser.CelUnparserFactory;
40-
import dev.cel.policy.PolicyTestHelper.K8sTagHandler;
4140
import dev.cel.policy.PolicyTestHelper.PolicyTestSuite;
4241
import dev.cel.policy.PolicyTestHelper.PolicyTestSuite.PolicyTestSection;
4342
import dev.cel.policy.PolicyTestHelper.PolicyTestSuite.PolicyTestSection.PolicyTestCase;

policy/src/test/java/dev/cel/policy/CelPolicyYamlParserTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
2323
import dev.cel.common.formats.ValueString;
2424
import dev.cel.policy.CelPolicy.Import;
25-
import dev.cel.policy.PolicyTestHelper.K8sTagHandler;
2625
import dev.cel.policy.PolicyTestHelper.TestYamlPolicy;
2726
import org.junit.Test;
2827
import org.junit.runner.RunWith;

0 commit comments

Comments
 (0)