Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bundle/src/main/java/dev/cel/bundle/BUILD.bazel
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,7 +73,6 @@ java_library(
"//common/types:type_providers",
"//compiler:compiler_builder",
"//extensions",
"//extensions:optional_library",
"//parser:macro",
"//runtime",
"@maven//:com_google_errorprone_error_prone_annotations",
Expand DownExpand Up@@ -103,6 +102,7 @@ java_library(
":environment",
":environment_exception",
"//common:compiler_common",
"//common:container",
"//common/formats:file_source",
"//common/formats:parser_context",
"//common/formats:yaml_helper",
Expand Down
52 changes: 42 additions & 10 deletions bundle/src/main/java/dev/cel/bundle/CelEnvironment.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -80,10 +80,9 @@ public abstract class CelEnvironment {
public abstract String name();

/**
* An optional description of the config (example: location of the file containing the config
* content).
* Container, which captures default namespace and aliases for value resolution.
*/
public abstract String container();
public abstract CelContainer container();

/**
* An optional description of the environment (example: location of the file containing the config
Expand DownExpand Up@@ -124,7 +123,12 @@ public abstract static class Builder {

public abstract Builder setDescription(String description);

public abstract Builder setContainer(String container);
public abstract Builder setContainer(CelContainer container);

@CanIgnoreReturnValue
public Builder setContainer(String container) {
return setContainer(CelContainer.ofName(container));
}

@CanIgnoreReturnValue
public Builder addExtensions(ExtensionConfig... extensions) {
Expand DownExpand Up@@ -182,7 +186,7 @@ public static Builder newBuilder() {
return new AutoValue_CelEnvironment.Builder()
.setName("")
.setDescription("")
.setContainer("")
.setContainer(CelContainer.ofName(""))
.setVariables(ImmutableSet.of())
.setFunctions(ImmutableSet.of());
}
Expand All@@ -195,8 +199,8 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
CelCompilerBuilder compilerBuilder =
celCompiler
.toCompilerBuilder()
.setContainer(container())
.setTypeProvider(celTypeProvider)
.setContainer(CelContainer.ofName(container()))
.addVarDeclarations(
variables().stream()
.map(v -> v.toCelVarDecl(celTypeProvider))
Expand All@@ -206,10 +210,6 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
.map(f -> f.toCelFunctionDecl(celTypeProvider))
.collect(toImmutableList()));

if (!container().isEmpty()) {
compilerBuilder.setContainer(CelContainer.ofName(container()));
}

addAllCompilerExtensions(compilerBuilder, celOptions);

applyStandardLibrarySubset(compilerBuilder);
Expand DownExpand Up@@ -683,6 +683,38 @@ public static ExtensionConfig latest(String name) {
}
}

@AutoValue
abstract static class Alias {
abstract String alias();

abstract String qualifiedName();

static Builder newBuilder() {
return new AutoValue_CelEnvironment_Alias.Builder();
}

@AutoValue.Builder
abstract static class Builder implements RequiredFieldsChecker {

abstract Optional<String> alias();

abstract Optional<String> qualifiedName();

abstract Builder setAlias(String alias);

abstract Builder setQualifiedName(String qualifiedName);

abstract Alias build();

@Override
public ImmutableList<RequiredField> requiredFields() {
return ImmutableList.of(
RequiredField.of("alias", this::alias),
RequiredField.of("qualified_name", this::qualifiedName));
}
}
}

@VisibleForTesting
enum CanonicalCelExtension {
BINDINGS((options, version) -> CelExtensions.bindings()),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -161,6 +161,9 @@ public static CelEnvironmentExporter.Builder newBuilder() {
* </ul>
*/
public CelEnvironment export(Cel cel) {
CelEnvironment.Builder envBuilder =
CelEnvironment.newBuilder().setContainer(cel.toCheckerBuilder().container());

// Inventory is a full set of declarations and macros that are found in the configuration of
// the supplied CEL instance.
//
Expand All@@ -171,8 +174,6 @@ public CelEnvironment export(Cel cel) {

Set<Object> inventory = new HashSet<>();
collectInventory(inventory, cel);

CelEnvironment.Builder envBuilder = CelEnvironment.newBuilder();
addExtensionConfigsAndRemoveFromInventory(envBuilder, inventory);
addStandardLibrarySubsetAndRemoveFromInventory(envBuilder, inventory);
addCustomDecls(envBuilder, inventory);
Expand Down
124 changes: 123 additions & 1 deletion bundle/src/main/java/dev/cel/bundle/CelEnvironmentYamlParser.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.ExtensionConfig;
import dev.cel.bundle.CelEnvironment.FunctionDecl;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
Expand All@@ -35,6 +36,7 @@
import dev.cel.bundle.CelEnvironment.OverloadDecl;
import dev.cel.bundle.CelEnvironment.TypeDecl;
import dev.cel.bundle.CelEnvironment.VariableDecl;
import dev.cel.common.CelContainer;
import dev.cel.common.CelIssue;
import dev.cel.common.formats.CelFileSource;
import dev.cel.common.formats.ParserContext;
Expand DownExpand Up@@ -64,6 +66,8 @@ public final class CelEnvironmentYamlParser {
private static final ExtensionConfig ERROR_EXTENSION_DECL = ExtensionConfig.of(ERROR);
private static final FunctionSelector ERROR_FUNCTION_SELECTOR =
FunctionSelector.create(ERROR, ImmutableSet.of());
private static final Alias ERROR_ALIAS =
Alias.newBuilder().setAlias(ERROR).setQualifiedName(ERROR).build();

/** Generates a new instance of {@code CelEnvironmentYamlParser}. */
public static CelEnvironmentYamlParser newInstance() {
Expand All@@ -88,6 +92,124 @@ public CelEnvironment parse(String environmentYamlSource, String description)
return parser.parseYaml(environmentYamlSource, description);
}

private CelContainer parseContainer(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
// Syntax variant 1: "container: `str`"
if (validateYamlType(node, YamlNodeType.STRING, YamlNodeType.TEXT)) {
return CelContainer.ofName(newString(ctx, node));
}

// Syntax variant 2:
// container
// name: str
// abbreviations:
// - a1
// - a2
// aliases:
// - alias: a1
// qualified_name: q1
// - alias: a2
// qualified_name: q2
if (!assertYamlType(ctx, valueId, node, YamlNodeType.MAP)) {
return CelContainer.ofName(ERROR);
}

CelContainer.Builder builder = CelContainer.newBuilder();
MappingNode variableMap = (MappingNode) node;
for (NodeTuple nodeTuple : variableMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "name":
builder.setName(newString(ctx, valueNode));
break;
case "aliases":
ImmutableSet<Alias> aliases = parseAliases(ctx, valueNode);
for (Alias alias : aliases) {
builder.addAlias(alias.alias(), alias.qualifiedName());
}
break;
case "abbreviations":
builder.addAbbreviations(parseAbbreviations(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported container tag: %s", keyName));
break;
}
}

return builder.build();
}

private ImmutableSet<Alias> parseAliases(ParserContext<Node> ctx, Node node) {
ImmutableSet.Builder<Alias> aliasSetBuilder = ImmutableSet.builder();
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return aliasSetBuilder.build();
}

SequenceNode variableListNode = (SequenceNode) node;
for (Node elementNode : variableListNode.getValue()) {
aliasSetBuilder.add(parseAlias(ctx, elementNode));
}

return aliasSetBuilder.build();
}

private Alias parseAlias(ParserContext<Node> ctx, Node node) {
long id = ctx.collectMetadata(node);
if (!assertYamlType(ctx, id, node, YamlNodeType.MAP)) {
return ERROR_ALIAS;
}

Alias.Builder builder = Alias.newBuilder();
MappingNode attrMap = (MappingNode) node;
for (NodeTuple nodeTuple : attrMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "alias":
builder.setAlias(newString(ctx, valueNode));
break;
case "qualified_name":
builder.setQualifiedName(newString(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported alias tag: %s", keyName));
break;
}
}

if (!assertRequiredFields(ctx, id, builder.getMissingRequiredFieldNames())) {
return ERROR_ALIAS;
}

return builder.build();
}

private ImmutableSet<String> parseAbbreviations(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return ImmutableSet.of(ERROR);
}

ImmutableSet.Builder<String> builder = ImmutableSet.builder();
SequenceNode nameListNode = (SequenceNode) node;
for (Node elementNode : nameListNode.getValue()) {
long elementId = ctx.collectMetadata(elementNode);
if (!assertYamlType(ctx, elementId, elementNode, YamlNodeType.STRING)) {
return ImmutableSet.of(ERROR);
}

builder.add(((ScalarNode) elementNode).getValue());
}
return builder.build();
}

private ImmutableSet<VariableDecl> parseVariables(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
ImmutableSet.Builder<VariableDecl> variableSetBuilder = ImmutableSet.builder();
Expand DownExpand Up@@ -620,7 +742,7 @@ private CelEnvironment.Builder parseConfig(ParserContext<Node> ctx, Node node) {
builder.setDescription(newString(ctx, valueNode));
break;
case "container":
builder.setContainer(newString(ctx, valueNode));
builder.setContainer(parseContainer(ctx, valueNode));
break;
case "variables":
builder.setVariables(parseVariables(ctx, valueNode));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,10 +16,13 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
import dev.cel.bundle.CelEnvironment.LibrarySubset.FunctionSelector;
import dev.cel.bundle.CelEnvironment.LibrarySubset.OverloadSelector;
import dev.cel.common.CelContainer;
import java.util.Comparator;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Node;
Expand DownExpand Up@@ -55,6 +58,8 @@ private CelEnvironmentYamlSerializer() {
CelEnvironment.LibrarySubset.FunctionSelector.class, new RepresentFunctionSelector());
this.multiRepresenters.put(
CelEnvironment.LibrarySubset.OverloadSelector.class, new RepresentOverloadSelector());
this.multiRepresenters.put(CelEnvironment.Alias.class, new RepresentAlias());
this.multiRepresenters.put(CelContainer.class, new RepresentContainer());
}

public static String toYaml(CelEnvironment environment) {
Expand All@@ -72,7 +77,9 @@ public Node representData(Object data) {
if (!environment.description().isEmpty()) {
configMap.put("description", environment.description());
}
if (!environment.container().isEmpty()) {
if (!environment.container().name().isEmpty()
|| !environment.container().abbreviations().isEmpty()
|| !environment.container().aliases().isEmpty()) {
configMap.put("container", environment.container());
}
if (!environment.extensions().isEmpty()) {
Expand All@@ -91,6 +98,43 @@ public Node representData(Object data) {
}
}

private final class RepresentContainer implements Represent {

@Override
public Node representData(Object data) {
CelContainer container = (CelContainer) data;
ImmutableMap.Builder<String, Object> configMap = ImmutableMap.builder();
if (!container.name().isEmpty()) {
configMap.put("name", container.name());
}
if (!container.abbreviations().isEmpty()) {
configMap.put("abbreviations", container.abbreviations());
}
if (!container.aliases().isEmpty()) {
ImmutableList.Builder<Alias> aliases = ImmutableList.builder();
for (Map.Entry<String, String> entry : container.aliases().entrySet()) {
aliases.add(
Alias.newBuilder()
.setAlias(entry.getKey())
.setQualifiedName(entry.getValue())
.build());
}
configMap.put("aliases", aliases.build());
}
return represent(configMap.buildOrThrow());
}
}

private final class RepresentAlias implements Represent {

@Override
public Node representData(Object data) {
Alias alias = (Alias) data;
return represent(
ImmutableMap.of("alias", alias.alias(), "qualified_name", alias.qualifiedName()));
}
}

private final class RepresentExtensionConfig implements Represent {
@Override
public Node representData(Object data) {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bundle/src/main/java/dev/cel/bundle/BUILD.bazel
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,7 +73,6 @@ java_library(
"//common/types:type_providers",
"//compiler:compiler_builder",
"//extensions",
"//extensions:optional_library",
"//parser:macro",
"//runtime",
"@maven//:com_google_errorprone_error_prone_annotations",
Expand DownExpand Up@@ -103,6 +102,7 @@ java_library(
":environment",
":environment_exception",
"//common:compiler_common",
"//common:container",
"//common/formats:file_source",
"//common/formats:parser_context",
"//common/formats:yaml_helper",
Expand Down
52 changes: 42 additions & 10 deletions bundle/src/main/java/dev/cel/bundle/CelEnvironment.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -80,10 +80,9 @@ public abstract class CelEnvironment {
public abstract String name();

/**
* An optional description of the config (example: location of the file containing the config
* content).
* Container, which captures default namespace and aliases for value resolution.
*/
public abstract String container();
public abstract CelContainer container();

/**
* An optional description of the environment (example: location of the file containing the config
Expand DownExpand Up@@ -124,7 +123,12 @@ public abstract static class Builder {

public abstract Builder setDescription(String description);

public abstract Builder setContainer(String container);
public abstract Builder setContainer(CelContainer container);

@CanIgnoreReturnValue
public Builder setContainer(String container) {
return setContainer(CelContainer.ofName(container));
}

@CanIgnoreReturnValue
public Builder addExtensions(ExtensionConfig... extensions) {
Expand DownExpand Up@@ -182,7 +186,7 @@ public static Builder newBuilder() {
return new AutoValue_CelEnvironment.Builder()
.setName("")
.setDescription("")
.setContainer("")
.setContainer(CelContainer.ofName(""))
.setVariables(ImmutableSet.of())
.setFunctions(ImmutableSet.of());
}
Expand All@@ -195,8 +199,8 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
CelCompilerBuilder compilerBuilder =
celCompiler
.toCompilerBuilder()
.setContainer(container())
.setTypeProvider(celTypeProvider)
.setContainer(CelContainer.ofName(container()))
.addVarDeclarations(
variables().stream()
.map(v -> v.toCelVarDecl(celTypeProvider))
Expand All@@ -206,10 +210,6 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
.map(f -> f.toCelFunctionDecl(celTypeProvider))
.collect(toImmutableList()));

if (!container().isEmpty()) {
compilerBuilder.setContainer(CelContainer.ofName(container()));
}

addAllCompilerExtensions(compilerBuilder, celOptions);

applyStandardLibrarySubset(compilerBuilder);
Expand DownExpand Up@@ -683,6 +683,38 @@ public static ExtensionConfig latest(String name) {
}
}

@AutoValue
abstract static class Alias {
abstract String alias();

abstract String qualifiedName();

static Builder newBuilder() {
return new AutoValue_CelEnvironment_Alias.Builder();
}

@AutoValue.Builder
abstract static class Builder implements RequiredFieldsChecker {

abstract Optional<String> alias();

abstract Optional<String> qualifiedName();

abstract Builder setAlias(String alias);

abstract Builder setQualifiedName(String qualifiedName);

abstract Alias build();

@Override
public ImmutableList<RequiredField> requiredFields() {
return ImmutableList.of(
RequiredField.of("alias", this::alias),
RequiredField.of("qualified_name", this::qualifiedName));
}
}
}

@VisibleForTesting
enum CanonicalCelExtension {
BINDINGS((options, version) -> CelExtensions.bindings()),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -161,6 +161,9 @@ public static CelEnvironmentExporter.Builder newBuilder() {
* </ul>
*/
public CelEnvironment export(Cel cel) {
CelEnvironment.Builder envBuilder =
CelEnvironment.newBuilder().setContainer(cel.toCheckerBuilder().container());

// Inventory is a full set of declarations and macros that are found in the configuration of
// the supplied CEL instance.
//
Expand All@@ -171,8 +174,6 @@ public CelEnvironment export(Cel cel) {

Set<Object> inventory = new HashSet<>();
collectInventory(inventory, cel);

CelEnvironment.Builder envBuilder = CelEnvironment.newBuilder();
addExtensionConfigsAndRemoveFromInventory(envBuilder, inventory);
addStandardLibrarySubsetAndRemoveFromInventory(envBuilder, inventory);
addCustomDecls(envBuilder, inventory);
Expand Down
124 changes: 123 additions & 1 deletion bundle/src/main/java/dev/cel/bundle/CelEnvironmentYamlParser.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.ExtensionConfig;
import dev.cel.bundle.CelEnvironment.FunctionDecl;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
Expand All@@ -35,6 +36,7 @@
import dev.cel.bundle.CelEnvironment.OverloadDecl;
import dev.cel.bundle.CelEnvironment.TypeDecl;
import dev.cel.bundle.CelEnvironment.VariableDecl;
import dev.cel.common.CelContainer;
import dev.cel.common.CelIssue;
import dev.cel.common.formats.CelFileSource;
import dev.cel.common.formats.ParserContext;
Expand DownExpand Up@@ -64,6 +66,8 @@ public final class CelEnvironmentYamlParser {
private static final ExtensionConfig ERROR_EXTENSION_DECL = ExtensionConfig.of(ERROR);
private static final FunctionSelector ERROR_FUNCTION_SELECTOR =
FunctionSelector.create(ERROR, ImmutableSet.of());
private static final Alias ERROR_ALIAS =
Alias.newBuilder().setAlias(ERROR).setQualifiedName(ERROR).build();

/** Generates a new instance of {@code CelEnvironmentYamlParser}. */
public static CelEnvironmentYamlParser newInstance() {
Expand All@@ -88,6 +92,124 @@ public CelEnvironment parse(String environmentYamlSource, String description)
return parser.parseYaml(environmentYamlSource, description);
}

private CelContainer parseContainer(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
// Syntax variant 1: "container: `str`"
if (validateYamlType(node, YamlNodeType.STRING, YamlNodeType.TEXT)) {
return CelContainer.ofName(newString(ctx, node));
}

// Syntax variant 2:
// container
// name: str
// abbreviations:
// - a1
// - a2
// aliases:
// - alias: a1
// qualified_name: q1
// - alias: a2
// qualified_name: q2
if (!assertYamlType(ctx, valueId, node, YamlNodeType.MAP)) {
return CelContainer.ofName(ERROR);
}

CelContainer.Builder builder = CelContainer.newBuilder();
MappingNode variableMap = (MappingNode) node;
for (NodeTuple nodeTuple : variableMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "name":
builder.setName(newString(ctx, valueNode));
break;
case "aliases":
ImmutableSet<Alias> aliases = parseAliases(ctx, valueNode);
for (Alias alias : aliases) {
builder.addAlias(alias.alias(), alias.qualifiedName());
}
break;
case "abbreviations":
builder.addAbbreviations(parseAbbreviations(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported container tag: %s", keyName));
break;
}
}

return builder.build();
}

private ImmutableSet<Alias> parseAliases(ParserContext<Node> ctx, Node node) {
ImmutableSet.Builder<Alias> aliasSetBuilder = ImmutableSet.builder();
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return aliasSetBuilder.build();
}

SequenceNode variableListNode = (SequenceNode) node;
for (Node elementNode : variableListNode.getValue()) {
aliasSetBuilder.add(parseAlias(ctx, elementNode));
}

return aliasSetBuilder.build();
}

private Alias parseAlias(ParserContext<Node> ctx, Node node) {
long id = ctx.collectMetadata(node);
if (!assertYamlType(ctx, id, node, YamlNodeType.MAP)) {
return ERROR_ALIAS;
}

Alias.Builder builder = Alias.newBuilder();
MappingNode attrMap = (MappingNode) node;
for (NodeTuple nodeTuple : attrMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "alias":
builder.setAlias(newString(ctx, valueNode));
break;
case "qualified_name":
builder.setQualifiedName(newString(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported alias tag: %s", keyName));
break;
}
}

if (!assertRequiredFields(ctx, id, builder.getMissingRequiredFieldNames())) {
return ERROR_ALIAS;
}

return builder.build();
}

private ImmutableSet<String> parseAbbreviations(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return ImmutableSet.of(ERROR);
}

ImmutableSet.Builder<String> builder = ImmutableSet.builder();
SequenceNode nameListNode = (SequenceNode) node;
for (Node elementNode : nameListNode.getValue()) {
long elementId = ctx.collectMetadata(elementNode);
if (!assertYamlType(ctx, elementId, elementNode, YamlNodeType.STRING)) {
return ImmutableSet.of(ERROR);
}

builder.add(((ScalarNode) elementNode).getValue());
}
return builder.build();
}

private ImmutableSet<VariableDecl> parseVariables(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
ImmutableSet.Builder<VariableDecl> variableSetBuilder = ImmutableSet.builder();
Expand DownExpand Up@@ -620,7 +742,7 @@ private CelEnvironment.Builder parseConfig(ParserContext<Node> ctx, Node node) {
builder.setDescription(newString(ctx, valueNode));
break;
case "container":
builder.setContainer(newString(ctx, valueNode));
builder.setContainer(parseContainer(ctx, valueNode));
break;
case "variables":
builder.setVariables(parseVariables(ctx, valueNode));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,10 +16,13 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
import dev.cel.bundle.CelEnvironment.LibrarySubset.FunctionSelector;
import dev.cel.bundle.CelEnvironment.LibrarySubset.OverloadSelector;
import dev.cel.common.CelContainer;
import java.util.Comparator;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Node;
Expand DownExpand Up@@ -55,6 +58,8 @@ private CelEnvironmentYamlSerializer() {
CelEnvironment.LibrarySubset.FunctionSelector.class, new RepresentFunctionSelector());
this.multiRepresenters.put(
CelEnvironment.LibrarySubset.OverloadSelector.class, new RepresentOverloadSelector());
this.multiRepresenters.put(CelEnvironment.Alias.class, new RepresentAlias());
this.multiRepresenters.put(CelContainer.class, new RepresentContainer());
}

public static String toYaml(CelEnvironment environment) {
Expand All@@ -72,7 +77,9 @@ public Node representData(Object data) {
if (!environment.description().isEmpty()) {
configMap.put("description", environment.description());
}
if (!environment.container().isEmpty()) {
if (!environment.container().name().isEmpty()
|| !environment.container().abbreviations().isEmpty()
|| !environment.container().aliases().isEmpty()) {
configMap.put("container", environment.container());
}
if (!environment.extensions().isEmpty()) {
Expand All@@ -91,6 +98,43 @@ public Node representData(Object data) {
}
}

private final class RepresentContainer implements Represent {

@Override
public Node representData(Object data) {
CelContainer container = (CelContainer) data;
ImmutableMap.Builder<String, Object> configMap = ImmutableMap.builder();
if (!container.name().isEmpty()) {
configMap.put("name", container.name());
}
if (!container.abbreviations().isEmpty()) {
configMap.put("abbreviations", container.abbreviations());
}
if (!container.aliases().isEmpty()) {
ImmutableList.Builder<Alias> aliases = ImmutableList.builder();
for (Map.Entry<String, String> entry : container.aliases().entrySet()) {
aliases.add(
Alias.newBuilder()
.setAlias(entry.getKey())
.setQualifiedName(entry.getValue())
.build());
}
configMap.put("aliases", aliases.build());
}
return represent(configMap.buildOrThrow());
}
}

private final class RepresentAlias implements Represent {

@Override
public Node representData(Object data) {
Alias alias = (Alias) data;
return represent(
ImmutableMap.of("alias", alias.alias(), "qualified_name", alias.qualifiedName()));
}
}

private final class RepresentExtensionConfig implements Represent {
@Override
public Node representData(Object data) {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bundle/src/main/java/dev/cel/bundle/BUILD.bazel
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,7 +73,6 @@ java_library(
"//common/types:type_providers",
"//compiler:compiler_builder",
"//extensions",
"//extensions:optional_library",
"//parser:macro",
"//runtime",
"@maven//:com_google_errorprone_error_prone_annotations",
Expand DownExpand Up@@ -103,6 +102,7 @@ java_library(
":environment",
":environment_exception",
"//common:compiler_common",
"//common:container",
"//common/formats:file_source",
"//common/formats:parser_context",
"//common/formats:yaml_helper",
Expand Down
52 changes: 42 additions & 10 deletions bundle/src/main/java/dev/cel/bundle/CelEnvironment.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -80,10 +80,9 @@ public abstract class CelEnvironment {
public abstract String name();

/**
* An optional description of the config (example: location of the file containing the config
* content).
* Container, which captures default namespace and aliases for value resolution.
*/
public abstract String container();
public abstract CelContainer container();

/**
* An optional description of the environment (example: location of the file containing the config
Expand DownExpand Up@@ -124,7 +123,12 @@ public abstract static class Builder {

public abstract Builder setDescription(String description);

public abstract Builder setContainer(String container);
public abstract Builder setContainer(CelContainer container);

@CanIgnoreReturnValue
public Builder setContainer(String container) {
return setContainer(CelContainer.ofName(container));
}

@CanIgnoreReturnValue
public Builder addExtensions(ExtensionConfig... extensions) {
Expand DownExpand Up@@ -182,7 +186,7 @@ public static Builder newBuilder() {
return new AutoValue_CelEnvironment.Builder()
.setName("")
.setDescription("")
.setContainer("")
.setContainer(CelContainer.ofName(""))
.setVariables(ImmutableSet.of())
.setFunctions(ImmutableSet.of());
}
Expand All@@ -195,8 +199,8 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
CelCompilerBuilder compilerBuilder =
celCompiler
.toCompilerBuilder()
.setContainer(container())
.setTypeProvider(celTypeProvider)
.setContainer(CelContainer.ofName(container()))
.addVarDeclarations(
variables().stream()
.map(v -> v.toCelVarDecl(celTypeProvider))
Expand All@@ -206,10 +210,6 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
.map(f -> f.toCelFunctionDecl(celTypeProvider))
.collect(toImmutableList()));

if (!container().isEmpty()) {
compilerBuilder.setContainer(CelContainer.ofName(container()));
}

addAllCompilerExtensions(compilerBuilder, celOptions);

applyStandardLibrarySubset(compilerBuilder);
Expand DownExpand Up@@ -683,6 +683,38 @@ public static ExtensionConfig latest(String name) {
}
}

@AutoValue
abstract static class Alias {
abstract String alias();

abstract String qualifiedName();

static Builder newBuilder() {
return new AutoValue_CelEnvironment_Alias.Builder();
}

@AutoValue.Builder
abstract static class Builder implements RequiredFieldsChecker {

abstract Optional<String> alias();

abstract Optional<String> qualifiedName();

abstract Builder setAlias(String alias);

abstract Builder setQualifiedName(String qualifiedName);

abstract Alias build();

@Override
public ImmutableList<RequiredField> requiredFields() {
return ImmutableList.of(
RequiredField.of("alias", this::alias),
RequiredField.of("qualified_name", this::qualifiedName));
}
}
}

@VisibleForTesting
enum CanonicalCelExtension {
BINDINGS((options, version) -> CelExtensions.bindings()),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -161,6 +161,9 @@ public static CelEnvironmentExporter.Builder newBuilder() {
* </ul>
*/
public CelEnvironment export(Cel cel) {
CelEnvironment.Builder envBuilder =
CelEnvironment.newBuilder().setContainer(cel.toCheckerBuilder().container());

// Inventory is a full set of declarations and macros that are found in the configuration of
// the supplied CEL instance.
//
Expand All@@ -171,8 +174,6 @@ public CelEnvironment export(Cel cel) {

Set<Object> inventory = new HashSet<>();
collectInventory(inventory, cel);

CelEnvironment.Builder envBuilder = CelEnvironment.newBuilder();
addExtensionConfigsAndRemoveFromInventory(envBuilder, inventory);
addStandardLibrarySubsetAndRemoveFromInventory(envBuilder, inventory);
addCustomDecls(envBuilder, inventory);
Expand Down
124 changes: 123 additions & 1 deletion bundle/src/main/java/dev/cel/bundle/CelEnvironmentYamlParser.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.ExtensionConfig;
import dev.cel.bundle.CelEnvironment.FunctionDecl;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
Expand All@@ -35,6 +36,7 @@
import dev.cel.bundle.CelEnvironment.OverloadDecl;
import dev.cel.bundle.CelEnvironment.TypeDecl;
import dev.cel.bundle.CelEnvironment.VariableDecl;
import dev.cel.common.CelContainer;
import dev.cel.common.CelIssue;
import dev.cel.common.formats.CelFileSource;
import dev.cel.common.formats.ParserContext;
Expand DownExpand Up@@ -64,6 +66,8 @@ public final class CelEnvironmentYamlParser {
private static final ExtensionConfig ERROR_EXTENSION_DECL = ExtensionConfig.of(ERROR);
private static final FunctionSelector ERROR_FUNCTION_SELECTOR =
FunctionSelector.create(ERROR, ImmutableSet.of());
private static final Alias ERROR_ALIAS =
Alias.newBuilder().setAlias(ERROR).setQualifiedName(ERROR).build();

/** Generates a new instance of {@code CelEnvironmentYamlParser}. */
public static CelEnvironmentYamlParser newInstance() {
Expand All@@ -88,6 +92,124 @@ public CelEnvironment parse(String environmentYamlSource, String description)
return parser.parseYaml(environmentYamlSource, description);
}

private CelContainer parseContainer(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
// Syntax variant 1: "container: `str`"
if (validateYamlType(node, YamlNodeType.STRING, YamlNodeType.TEXT)) {
return CelContainer.ofName(newString(ctx, node));
}

// Syntax variant 2:
// container
// name: str
// abbreviations:
// - a1
// - a2
// aliases:
// - alias: a1
// qualified_name: q1
// - alias: a2
// qualified_name: q2
if (!assertYamlType(ctx, valueId, node, YamlNodeType.MAP)) {
return CelContainer.ofName(ERROR);
}

CelContainer.Builder builder = CelContainer.newBuilder();
MappingNode variableMap = (MappingNode) node;
for (NodeTuple nodeTuple : variableMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "name":
builder.setName(newString(ctx, valueNode));
break;
case "aliases":
ImmutableSet<Alias> aliases = parseAliases(ctx, valueNode);
for (Alias alias : aliases) {
builder.addAlias(alias.alias(), alias.qualifiedName());
}
break;
case "abbreviations":
builder.addAbbreviations(parseAbbreviations(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported container tag: %s", keyName));
break;
}
}

return builder.build();
}

private ImmutableSet<Alias> parseAliases(ParserContext<Node> ctx, Node node) {
ImmutableSet.Builder<Alias> aliasSetBuilder = ImmutableSet.builder();
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return aliasSetBuilder.build();
}

SequenceNode variableListNode = (SequenceNode) node;
for (Node elementNode : variableListNode.getValue()) {
aliasSetBuilder.add(parseAlias(ctx, elementNode));
}

return aliasSetBuilder.build();
}

private Alias parseAlias(ParserContext<Node> ctx, Node node) {
long id = ctx.collectMetadata(node);
if (!assertYamlType(ctx, id, node, YamlNodeType.MAP)) {
return ERROR_ALIAS;
}

Alias.Builder builder = Alias.newBuilder();
MappingNode attrMap = (MappingNode) node;
for (NodeTuple nodeTuple : attrMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "alias":
builder.setAlias(newString(ctx, valueNode));
break;
case "qualified_name":
builder.setQualifiedName(newString(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported alias tag: %s", keyName));
break;
}
}

if (!assertRequiredFields(ctx, id, builder.getMissingRequiredFieldNames())) {
return ERROR_ALIAS;
}

return builder.build();
}

private ImmutableSet<String> parseAbbreviations(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return ImmutableSet.of(ERROR);
}

ImmutableSet.Builder<String> builder = ImmutableSet.builder();
SequenceNode nameListNode = (SequenceNode) node;
for (Node elementNode : nameListNode.getValue()) {
long elementId = ctx.collectMetadata(elementNode);
if (!assertYamlType(ctx, elementId, elementNode, YamlNodeType.STRING)) {
return ImmutableSet.of(ERROR);
}

builder.add(((ScalarNode) elementNode).getValue());
}
return builder.build();
}

private ImmutableSet<VariableDecl> parseVariables(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
ImmutableSet.Builder<VariableDecl> variableSetBuilder = ImmutableSet.builder();
Expand DownExpand Up@@ -620,7 +742,7 @@ private CelEnvironment.Builder parseConfig(ParserContext<Node> ctx, Node node) {
builder.setDescription(newString(ctx, valueNode));
break;
case "container":
builder.setContainer(newString(ctx, valueNode));
builder.setContainer(parseContainer(ctx, valueNode));
break;
case "variables":
builder.setVariables(parseVariables(ctx, valueNode));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,10 +16,13 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
import dev.cel.bundle.CelEnvironment.LibrarySubset.FunctionSelector;
import dev.cel.bundle.CelEnvironment.LibrarySubset.OverloadSelector;
import dev.cel.common.CelContainer;
import java.util.Comparator;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Node;
Expand DownExpand Up@@ -55,6 +58,8 @@ private CelEnvironmentYamlSerializer() {
CelEnvironment.LibrarySubset.FunctionSelector.class, new RepresentFunctionSelector());
this.multiRepresenters.put(
CelEnvironment.LibrarySubset.OverloadSelector.class, new RepresentOverloadSelector());
this.multiRepresenters.put(CelEnvironment.Alias.class, new RepresentAlias());
this.multiRepresenters.put(CelContainer.class, new RepresentContainer());
}

public static String toYaml(CelEnvironment environment) {
Expand All@@ -72,7 +77,9 @@ public Node representData(Object data) {
if (!environment.description().isEmpty()) {
configMap.put("description", environment.description());
}
if (!environment.container().isEmpty()) {
if (!environment.container().name().isEmpty()
|| !environment.container().abbreviations().isEmpty()
|| !environment.container().aliases().isEmpty()) {
configMap.put("container", environment.container());
}
if (!environment.extensions().isEmpty()) {
Expand All@@ -91,6 +98,43 @@ public Node representData(Object data) {
}
}

private final class RepresentContainer implements Represent {

@Override
public Node representData(Object data) {
CelContainer container = (CelContainer) data;
ImmutableMap.Builder<String, Object> configMap = ImmutableMap.builder();
if (!container.name().isEmpty()) {
configMap.put("name", container.name());
}
if (!container.abbreviations().isEmpty()) {
configMap.put("abbreviations", container.abbreviations());
}
if (!container.aliases().isEmpty()) {
ImmutableList.Builder<Alias> aliases = ImmutableList.builder();
for (Map.Entry<String, String> entry : container.aliases().entrySet()) {
aliases.add(
Alias.newBuilder()
.setAlias(entry.getKey())
.setQualifiedName(entry.getValue())
.build());
}
configMap.put("aliases", aliases.build());
}
return represent(configMap.buildOrThrow());
}
}

private final class RepresentAlias implements Represent {

@Override
public Node representData(Object data) {
Alias alias = (Alias) data;
return represent(
ImmutableMap.of("alias", alias.alias(), "qualified_name", alias.qualifiedName()));
}
}

private final class RepresentExtensionConfig implements Represent {
@Override
public Node representData(Object data) {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bundle/src/main/java/dev/cel/bundle/BUILD.bazel
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,7 +73,6 @@ java_library(
"//common/types:type_providers",
"//compiler:compiler_builder",
"//extensions",
"//extensions:optional_library",
"//parser:macro",
"//runtime",
"@maven//:com_google_errorprone_error_prone_annotations",
Expand DownExpand Up@@ -103,6 +102,7 @@ java_library(
":environment",
":environment_exception",
"//common:compiler_common",
"//common:container",
"//common/formats:file_source",
"//common/formats:parser_context",
"//common/formats:yaml_helper",
Expand Down
52 changes: 42 additions & 10 deletions bundle/src/main/java/dev/cel/bundle/CelEnvironment.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -80,10 +80,9 @@ public abstract class CelEnvironment {
public abstract String name();

/**
* An optional description of the config (example: location of the file containing the config
* content).
* Container, which captures default namespace and aliases for value resolution.
*/
public abstract String container();
public abstract CelContainer container();

/**
* An optional description of the environment (example: location of the file containing the config
Expand DownExpand Up@@ -124,7 +123,12 @@ public abstract static class Builder {

public abstract Builder setDescription(String description);

public abstract Builder setContainer(String container);
public abstract Builder setContainer(CelContainer container);

@CanIgnoreReturnValue
public Builder setContainer(String container) {
return setContainer(CelContainer.ofName(container));
}

@CanIgnoreReturnValue
public Builder addExtensions(ExtensionConfig... extensions) {
Expand DownExpand Up@@ -182,7 +186,7 @@ public static Builder newBuilder() {
return new AutoValue_CelEnvironment.Builder()
.setName("")
.setDescription("")
.setContainer("")
.setContainer(CelContainer.ofName(""))
.setVariables(ImmutableSet.of())
.setFunctions(ImmutableSet.of());
}
Expand All@@ -195,8 +199,8 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
CelCompilerBuilder compilerBuilder =
celCompiler
.toCompilerBuilder()
.setContainer(container())
.setTypeProvider(celTypeProvider)
.setContainer(CelContainer.ofName(container()))
.addVarDeclarations(
variables().stream()
.map(v -> v.toCelVarDecl(celTypeProvider))
Expand All@@ -206,10 +210,6 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
.map(f -> f.toCelFunctionDecl(celTypeProvider))
.collect(toImmutableList()));

if (!container().isEmpty()) {
compilerBuilder.setContainer(CelContainer.ofName(container()));
}

addAllCompilerExtensions(compilerBuilder, celOptions);

applyStandardLibrarySubset(compilerBuilder);
Expand DownExpand Up@@ -683,6 +683,38 @@ public static ExtensionConfig latest(String name) {
}
}

@AutoValue
abstract static class Alias {
abstract String alias();

abstract String qualifiedName();

static Builder newBuilder() {
return new AutoValue_CelEnvironment_Alias.Builder();
}

@AutoValue.Builder
abstract static class Builder implements RequiredFieldsChecker {

abstract Optional<String> alias();

abstract Optional<String> qualifiedName();

abstract Builder setAlias(String alias);

abstract Builder setQualifiedName(String qualifiedName);

abstract Alias build();

@Override
public ImmutableList<RequiredField> requiredFields() {
return ImmutableList.of(
RequiredField.of("alias", this::alias),
RequiredField.of("qualified_name", this::qualifiedName));
}
}
}

@VisibleForTesting
enum CanonicalCelExtension {
BINDINGS((options, version) -> CelExtensions.bindings()),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -161,6 +161,9 @@ public static CelEnvironmentExporter.Builder newBuilder() {
* </ul>
*/
public CelEnvironment export(Cel cel) {
CelEnvironment.Builder envBuilder =
CelEnvironment.newBuilder().setContainer(cel.toCheckerBuilder().container());

// Inventory is a full set of declarations and macros that are found in the configuration of
// the supplied CEL instance.
//
Expand All@@ -171,8 +174,6 @@ public CelEnvironment export(Cel cel) {

Set<Object> inventory = new HashSet<>();
collectInventory(inventory, cel);

CelEnvironment.Builder envBuilder = CelEnvironment.newBuilder();
addExtensionConfigsAndRemoveFromInventory(envBuilder, inventory);
addStandardLibrarySubsetAndRemoveFromInventory(envBuilder, inventory);
addCustomDecls(envBuilder, inventory);
Expand Down
124 changes: 123 additions & 1 deletion bundle/src/main/java/dev/cel/bundle/CelEnvironmentYamlParser.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.ExtensionConfig;
import dev.cel.bundle.CelEnvironment.FunctionDecl;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
Expand All@@ -35,6 +36,7 @@
import dev.cel.bundle.CelEnvironment.OverloadDecl;
import dev.cel.bundle.CelEnvironment.TypeDecl;
import dev.cel.bundle.CelEnvironment.VariableDecl;
import dev.cel.common.CelContainer;
import dev.cel.common.CelIssue;
import dev.cel.common.formats.CelFileSource;
import dev.cel.common.formats.ParserContext;
Expand DownExpand Up@@ -64,6 +66,8 @@ public final class CelEnvironmentYamlParser {
private static final ExtensionConfig ERROR_EXTENSION_DECL = ExtensionConfig.of(ERROR);
private static final FunctionSelector ERROR_FUNCTION_SELECTOR =
FunctionSelector.create(ERROR, ImmutableSet.of());
private static final Alias ERROR_ALIAS =
Alias.newBuilder().setAlias(ERROR).setQualifiedName(ERROR).build();

/** Generates a new instance of {@code CelEnvironmentYamlParser}. */
public static CelEnvironmentYamlParser newInstance() {
Expand All@@ -88,6 +92,124 @@ public CelEnvironment parse(String environmentYamlSource, String description)
return parser.parseYaml(environmentYamlSource, description);
}

private CelContainer parseContainer(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
// Syntax variant 1: "container: `str`"
if (validateYamlType(node, YamlNodeType.STRING, YamlNodeType.TEXT)) {
return CelContainer.ofName(newString(ctx, node));
}

// Syntax variant 2:
// container
// name: str
// abbreviations:
// - a1
// - a2
// aliases:
// - alias: a1
// qualified_name: q1
// - alias: a2
// qualified_name: q2
if (!assertYamlType(ctx, valueId, node, YamlNodeType.MAP)) {
return CelContainer.ofName(ERROR);
}

CelContainer.Builder builder = CelContainer.newBuilder();
MappingNode variableMap = (MappingNode) node;
for (NodeTuple nodeTuple : variableMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "name":
builder.setName(newString(ctx, valueNode));
break;
case "aliases":
ImmutableSet<Alias> aliases = parseAliases(ctx, valueNode);
for (Alias alias : aliases) {
builder.addAlias(alias.alias(), alias.qualifiedName());
}
break;
case "abbreviations":
builder.addAbbreviations(parseAbbreviations(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported container tag: %s", keyName));
break;
}
}

return builder.build();
}

private ImmutableSet<Alias> parseAliases(ParserContext<Node> ctx, Node node) {
ImmutableSet.Builder<Alias> aliasSetBuilder = ImmutableSet.builder();
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return aliasSetBuilder.build();
}

SequenceNode variableListNode = (SequenceNode) node;
for (Node elementNode : variableListNode.getValue()) {
aliasSetBuilder.add(parseAlias(ctx, elementNode));
}

return aliasSetBuilder.build();
}

private Alias parseAlias(ParserContext<Node> ctx, Node node) {
long id = ctx.collectMetadata(node);
if (!assertYamlType(ctx, id, node, YamlNodeType.MAP)) {
return ERROR_ALIAS;
}

Alias.Builder builder = Alias.newBuilder();
MappingNode attrMap = (MappingNode) node;
for (NodeTuple nodeTuple : attrMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "alias":
builder.setAlias(newString(ctx, valueNode));
break;
case "qualified_name":
builder.setQualifiedName(newString(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported alias tag: %s", keyName));
break;
}
}

if (!assertRequiredFields(ctx, id, builder.getMissingRequiredFieldNames())) {
return ERROR_ALIAS;
}

return builder.build();
}

private ImmutableSet<String> parseAbbreviations(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return ImmutableSet.of(ERROR);
}

ImmutableSet.Builder<String> builder = ImmutableSet.builder();
SequenceNode nameListNode = (SequenceNode) node;
for (Node elementNode : nameListNode.getValue()) {
long elementId = ctx.collectMetadata(elementNode);
if (!assertYamlType(ctx, elementId, elementNode, YamlNodeType.STRING)) {
return ImmutableSet.of(ERROR);
}

builder.add(((ScalarNode) elementNode).getValue());
}
return builder.build();
}

private ImmutableSet<VariableDecl> parseVariables(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
ImmutableSet.Builder<VariableDecl> variableSetBuilder = ImmutableSet.builder();
Expand DownExpand Up@@ -620,7 +742,7 @@ private CelEnvironment.Builder parseConfig(ParserContext<Node> ctx, Node node) {
builder.setDescription(newString(ctx, valueNode));
break;
case "container":
builder.setContainer(newString(ctx, valueNode));
builder.setContainer(parseContainer(ctx, valueNode));
break;
case "variables":
builder.setVariables(parseVariables(ctx, valueNode));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,10 +16,13 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
import dev.cel.bundle.CelEnvironment.LibrarySubset.FunctionSelector;
import dev.cel.bundle.CelEnvironment.LibrarySubset.OverloadSelector;
import dev.cel.common.CelContainer;
import java.util.Comparator;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Node;
Expand DownExpand Up@@ -55,6 +58,8 @@ private CelEnvironmentYamlSerializer() {
CelEnvironment.LibrarySubset.FunctionSelector.class, new RepresentFunctionSelector());
this.multiRepresenters.put(
CelEnvironment.LibrarySubset.OverloadSelector.class, new RepresentOverloadSelector());
this.multiRepresenters.put(CelEnvironment.Alias.class, new RepresentAlias());
this.multiRepresenters.put(CelContainer.class, new RepresentContainer());
}

public static String toYaml(CelEnvironment environment) {
Expand All@@ -72,7 +77,9 @@ public Node representData(Object data) {
if (!environment.description().isEmpty()) {
configMap.put("description", environment.description());
}
if (!environment.container().isEmpty()) {
if (!environment.container().name().isEmpty()
|| !environment.container().abbreviations().isEmpty()
|| !environment.container().aliases().isEmpty()) {
configMap.put("container", environment.container());
}
if (!environment.extensions().isEmpty()) {
Expand All@@ -91,6 +98,43 @@ public Node representData(Object data) {
}
}

private final class RepresentContainer implements Represent {

@Override
public Node representData(Object data) {
CelContainer container = (CelContainer) data;
ImmutableMap.Builder<String, Object> configMap = ImmutableMap.builder();
if (!container.name().isEmpty()) {
configMap.put("name", container.name());
}
if (!container.abbreviations().isEmpty()) {
configMap.put("abbreviations", container.abbreviations());
}
if (!container.aliases().isEmpty()) {
ImmutableList.Builder<Alias> aliases = ImmutableList.builder();
for (Map.Entry<String, String> entry : container.aliases().entrySet()) {
aliases.add(
Alias.newBuilder()
.setAlias(entry.getKey())
.setQualifiedName(entry.getValue())
.build());
}
configMap.put("aliases", aliases.build());
}
return represent(configMap.buildOrThrow());
}
}

private final class RepresentAlias implements Represent {

@Override
public Node representData(Object data) {
Alias alias = (Alias) data;
return represent(
ImmutableMap.of("alias", alias.alias(), "qualified_name", alias.qualifiedName()));
}
}

private final class RepresentExtensionConfig implements Represent {
@Override
public Node representData(Object data) {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bundle/src/main/java/dev/cel/bundle/BUILD.bazel
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,7 +73,6 @@ java_library(
"//common/types:type_providers",
"//compiler:compiler_builder",
"//extensions",
"//extensions:optional_library",
"//parser:macro",
"//runtime",
"@maven//:com_google_errorprone_error_prone_annotations",
Expand DownExpand Up@@ -103,6 +102,7 @@ java_library(
":environment",
":environment_exception",
"//common:compiler_common",
"//common:container",
"//common/formats:file_source",
"//common/formats:parser_context",
"//common/formats:yaml_helper",
Expand Down
52 changes: 42 additions & 10 deletions bundle/src/main/java/dev/cel/bundle/CelEnvironment.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -80,10 +80,9 @@ public abstract class CelEnvironment {
public abstract String name();

/**
* An optional description of the config (example: location of the file containing the config
* content).
* Container, which captures default namespace and aliases for value resolution.
*/
public abstract String container();
public abstract CelContainer container();

/**
* An optional description of the environment (example: location of the file containing the config
Expand DownExpand Up@@ -124,7 +123,12 @@ public abstract static class Builder {

public abstract Builder setDescription(String description);

public abstract Builder setContainer(String container);
public abstract Builder setContainer(CelContainer container);

@CanIgnoreReturnValue
public Builder setContainer(String container) {
return setContainer(CelContainer.ofName(container));
}

@CanIgnoreReturnValue
public Builder addExtensions(ExtensionConfig... extensions) {
Expand DownExpand Up@@ -182,7 +186,7 @@ public static Builder newBuilder() {
return new AutoValue_CelEnvironment.Builder()
.setName("")
.setDescription("")
.setContainer("")
.setContainer(CelContainer.ofName(""))
.setVariables(ImmutableSet.of())
.setFunctions(ImmutableSet.of());
}
Expand All@@ -195,8 +199,8 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
CelCompilerBuilder compilerBuilder =
celCompiler
.toCompilerBuilder()
.setContainer(container())
.setTypeProvider(celTypeProvider)
.setContainer(CelContainer.ofName(container()))
.addVarDeclarations(
variables().stream()
.map(v -> v.toCelVarDecl(celTypeProvider))
Expand All@@ -206,10 +210,6 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
.map(f -> f.toCelFunctionDecl(celTypeProvider))
.collect(toImmutableList()));

if (!container().isEmpty()) {
compilerBuilder.setContainer(CelContainer.ofName(container()));
}

addAllCompilerExtensions(compilerBuilder, celOptions);

applyStandardLibrarySubset(compilerBuilder);
Expand DownExpand Up@@ -683,6 +683,38 @@ public static ExtensionConfig latest(String name) {
}
}

@AutoValue
abstract static class Alias {
abstract String alias();

abstract String qualifiedName();

static Builder newBuilder() {
return new AutoValue_CelEnvironment_Alias.Builder();
}

@AutoValue.Builder
abstract static class Builder implements RequiredFieldsChecker {

abstract Optional<String> alias();

abstract Optional<String> qualifiedName();

abstract Builder setAlias(String alias);

abstract Builder setQualifiedName(String qualifiedName);

abstract Alias build();

@Override
public ImmutableList<RequiredField> requiredFields() {
return ImmutableList.of(
RequiredField.of("alias", this::alias),
RequiredField.of("qualified_name", this::qualifiedName));
}
}
}

@VisibleForTesting
enum CanonicalCelExtension {
BINDINGS((options, version) -> CelExtensions.bindings()),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -161,6 +161,9 @@ public static CelEnvironmentExporter.Builder newBuilder() {
* </ul>
*/
public CelEnvironment export(Cel cel) {
CelEnvironment.Builder envBuilder =
CelEnvironment.newBuilder().setContainer(cel.toCheckerBuilder().container());

// Inventory is a full set of declarations and macros that are found in the configuration of
// the supplied CEL instance.
//
Expand All@@ -171,8 +174,6 @@ public CelEnvironment export(Cel cel) {

Set<Object> inventory = new HashSet<>();
collectInventory(inventory, cel);

CelEnvironment.Builder envBuilder = CelEnvironment.newBuilder();
addExtensionConfigsAndRemoveFromInventory(envBuilder, inventory);
addStandardLibrarySubsetAndRemoveFromInventory(envBuilder, inventory);
addCustomDecls(envBuilder, inventory);
Expand Down
124 changes: 123 additions & 1 deletion bundle/src/main/java/dev/cel/bundle/CelEnvironmentYamlParser.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.ExtensionConfig;
import dev.cel.bundle.CelEnvironment.FunctionDecl;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
Expand All@@ -35,6 +36,7 @@
import dev.cel.bundle.CelEnvironment.OverloadDecl;
import dev.cel.bundle.CelEnvironment.TypeDecl;
import dev.cel.bundle.CelEnvironment.VariableDecl;
import dev.cel.common.CelContainer;
import dev.cel.common.CelIssue;
import dev.cel.common.formats.CelFileSource;
import dev.cel.common.formats.ParserContext;
Expand DownExpand Up@@ -64,6 +66,8 @@ public final class CelEnvironmentYamlParser {
private static final ExtensionConfig ERROR_EXTENSION_DECL = ExtensionConfig.of(ERROR);
private static final FunctionSelector ERROR_FUNCTION_SELECTOR =
FunctionSelector.create(ERROR, ImmutableSet.of());
private static final Alias ERROR_ALIAS =
Alias.newBuilder().setAlias(ERROR).setQualifiedName(ERROR).build();

/** Generates a new instance of {@code CelEnvironmentYamlParser}. */
public static CelEnvironmentYamlParser newInstance() {
Expand All@@ -88,6 +92,124 @@ public CelEnvironment parse(String environmentYamlSource, String description)
return parser.parseYaml(environmentYamlSource, description);
}

private CelContainer parseContainer(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
// Syntax variant 1: "container: `str`"
if (validateYamlType(node, YamlNodeType.STRING, YamlNodeType.TEXT)) {
return CelContainer.ofName(newString(ctx, node));
}

// Syntax variant 2:
// container
// name: str
// abbreviations:
// - a1
// - a2
// aliases:
// - alias: a1
// qualified_name: q1
// - alias: a2
// qualified_name: q2
if (!assertYamlType(ctx, valueId, node, YamlNodeType.MAP)) {
return CelContainer.ofName(ERROR);
}

CelContainer.Builder builder = CelContainer.newBuilder();
MappingNode variableMap = (MappingNode) node;
for (NodeTuple nodeTuple : variableMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "name":
builder.setName(newString(ctx, valueNode));
break;
case "aliases":
ImmutableSet<Alias> aliases = parseAliases(ctx, valueNode);
for (Alias alias : aliases) {
builder.addAlias(alias.alias(), alias.qualifiedName());
}
break;
case "abbreviations":
builder.addAbbreviations(parseAbbreviations(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported container tag: %s", keyName));
break;
}
}

return builder.build();
}

private ImmutableSet<Alias> parseAliases(ParserContext<Node> ctx, Node node) {
ImmutableSet.Builder<Alias> aliasSetBuilder = ImmutableSet.builder();
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return aliasSetBuilder.build();
}

SequenceNode variableListNode = (SequenceNode) node;
for (Node elementNode : variableListNode.getValue()) {
aliasSetBuilder.add(parseAlias(ctx, elementNode));
}

return aliasSetBuilder.build();
}

private Alias parseAlias(ParserContext<Node> ctx, Node node) {
long id = ctx.collectMetadata(node);
if (!assertYamlType(ctx, id, node, YamlNodeType.MAP)) {
return ERROR_ALIAS;
}

Alias.Builder builder = Alias.newBuilder();
MappingNode attrMap = (MappingNode) node;
for (NodeTuple nodeTuple : attrMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "alias":
builder.setAlias(newString(ctx, valueNode));
break;
case "qualified_name":
builder.setQualifiedName(newString(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported alias tag: %s", keyName));
break;
}
}

if (!assertRequiredFields(ctx, id, builder.getMissingRequiredFieldNames())) {
return ERROR_ALIAS;
}

return builder.build();
}

private ImmutableSet<String> parseAbbreviations(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return ImmutableSet.of(ERROR);
}

ImmutableSet.Builder<String> builder = ImmutableSet.builder();
SequenceNode nameListNode = (SequenceNode) node;
for (Node elementNode : nameListNode.getValue()) {
long elementId = ctx.collectMetadata(elementNode);
if (!assertYamlType(ctx, elementId, elementNode, YamlNodeType.STRING)) {
return ImmutableSet.of(ERROR);
}

builder.add(((ScalarNode) elementNode).getValue());
}
return builder.build();
}

private ImmutableSet<VariableDecl> parseVariables(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
ImmutableSet.Builder<VariableDecl> variableSetBuilder = ImmutableSet.builder();
Expand DownExpand Up@@ -620,7 +742,7 @@ private CelEnvironment.Builder parseConfig(ParserContext<Node> ctx, Node node) {
builder.setDescription(newString(ctx, valueNode));
break;
case "container":
builder.setContainer(newString(ctx, valueNode));
builder.setContainer(parseContainer(ctx, valueNode));
break;
case "variables":
builder.setVariables(parseVariables(ctx, valueNode));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,10 +16,13 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
import dev.cel.bundle.CelEnvironment.LibrarySubset.FunctionSelector;
import dev.cel.bundle.CelEnvironment.LibrarySubset.OverloadSelector;
import dev.cel.common.CelContainer;
import java.util.Comparator;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Node;
Expand DownExpand Up@@ -55,6 +58,8 @@ private CelEnvironmentYamlSerializer() {
CelEnvironment.LibrarySubset.FunctionSelector.class, new RepresentFunctionSelector());
this.multiRepresenters.put(
CelEnvironment.LibrarySubset.OverloadSelector.class, new RepresentOverloadSelector());
this.multiRepresenters.put(CelEnvironment.Alias.class, new RepresentAlias());
this.multiRepresenters.put(CelContainer.class, new RepresentContainer());
}

public static String toYaml(CelEnvironment environment) {
Expand All@@ -72,7 +77,9 @@ public Node representData(Object data) {
if (!environment.description().isEmpty()) {
configMap.put("description", environment.description());
}
if (!environment.container().isEmpty()) {
if (!environment.container().name().isEmpty()
|| !environment.container().abbreviations().isEmpty()
|| !environment.container().aliases().isEmpty()) {
configMap.put("container", environment.container());
}
if (!environment.extensions().isEmpty()) {
Expand All@@ -91,6 +98,43 @@ public Node representData(Object data) {
}
}

private final class RepresentContainer implements Represent {

@Override
public Node representData(Object data) {
CelContainer container = (CelContainer) data;
ImmutableMap.Builder<String, Object> configMap = ImmutableMap.builder();
if (!container.name().isEmpty()) {
configMap.put("name", container.name());
}
if (!container.abbreviations().isEmpty()) {
configMap.put("abbreviations", container.abbreviations());
}
if (!container.aliases().isEmpty()) {
ImmutableList.Builder<Alias> aliases = ImmutableList.builder();
for (Map.Entry<String, String> entry : container.aliases().entrySet()) {
aliases.add(
Alias.newBuilder()
.setAlias(entry.getKey())
.setQualifiedName(entry.getValue())
.build());
}
configMap.put("aliases", aliases.build());
}
return represent(configMap.buildOrThrow());
}
}

private final class RepresentAlias implements Represent {

@Override
public Node representData(Object data) {
Alias alias = (Alias) data;
return represent(
ImmutableMap.of("alias", alias.alias(), "qualified_name", alias.qualifiedName()));
}
}

private final class RepresentExtensionConfig implements Represent {
@Override
public Node representData(Object data) {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bundle/src/main/java/dev/cel/bundle/BUILD.bazel
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,7 +73,6 @@ java_library(
"//common/types:type_providers",
"//compiler:compiler_builder",
"//extensions",
"//extensions:optional_library",
"//parser:macro",
"//runtime",
"@maven//:com_google_errorprone_error_prone_annotations",
Expand DownExpand Up@@ -103,6 +102,7 @@ java_library(
":environment",
":environment_exception",
"//common:compiler_common",
"//common:container",
"//common/formats:file_source",
"//common/formats:parser_context",
"//common/formats:yaml_helper",
Expand Down
52 changes: 42 additions & 10 deletions bundle/src/main/java/dev/cel/bundle/CelEnvironment.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -80,10 +80,9 @@ public abstract class CelEnvironment {
public abstract String name();

/**
* An optional description of the config (example: location of the file containing the config
* content).
* Container, which captures default namespace and aliases for value resolution.
*/
public abstract String container();
public abstract CelContainer container();

/**
* An optional description of the environment (example: location of the file containing the config
Expand DownExpand Up@@ -124,7 +123,12 @@ public abstract static class Builder {

public abstract Builder setDescription(String description);

public abstract Builder setContainer(String container);
public abstract Builder setContainer(CelContainer container);

@CanIgnoreReturnValue
public Builder setContainer(String container) {
return setContainer(CelContainer.ofName(container));
}

@CanIgnoreReturnValue
public Builder addExtensions(ExtensionConfig... extensions) {
Expand DownExpand Up@@ -182,7 +186,7 @@ public static Builder newBuilder() {
return new AutoValue_CelEnvironment.Builder()
.setName("")
.setDescription("")
.setContainer("")
.setContainer(CelContainer.ofName(""))
.setVariables(ImmutableSet.of())
.setFunctions(ImmutableSet.of());
}
Expand All@@ -195,8 +199,8 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
CelCompilerBuilder compilerBuilder =
celCompiler
.toCompilerBuilder()
.setContainer(container())
.setTypeProvider(celTypeProvider)
.setContainer(CelContainer.ofName(container()))
.addVarDeclarations(
variables().stream()
.map(v -> v.toCelVarDecl(celTypeProvider))
Expand All@@ -206,10 +210,6 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
.map(f -> f.toCelFunctionDecl(celTypeProvider))
.collect(toImmutableList()));

if (!container().isEmpty()) {
compilerBuilder.setContainer(CelContainer.ofName(container()));
}

addAllCompilerExtensions(compilerBuilder, celOptions);

applyStandardLibrarySubset(compilerBuilder);
Expand DownExpand Up@@ -683,6 +683,38 @@ public static ExtensionConfig latest(String name) {
}
}

@AutoValue
abstract static class Alias {
abstract String alias();

abstract String qualifiedName();

static Builder newBuilder() {
return new AutoValue_CelEnvironment_Alias.Builder();
}

@AutoValue.Builder
abstract static class Builder implements RequiredFieldsChecker {

abstract Optional<String> alias();

abstract Optional<String> qualifiedName();

abstract Builder setAlias(String alias);

abstract Builder setQualifiedName(String qualifiedName);

abstract Alias build();

@Override
public ImmutableList<RequiredField> requiredFields() {
return ImmutableList.of(
RequiredField.of("alias", this::alias),
RequiredField.of("qualified_name", this::qualifiedName));
}
}
}

@VisibleForTesting
enum CanonicalCelExtension {
BINDINGS((options, version) -> CelExtensions.bindings()),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -161,6 +161,9 @@ public static CelEnvironmentExporter.Builder newBuilder() {
* </ul>
*/
public CelEnvironment export(Cel cel) {
CelEnvironment.Builder envBuilder =
CelEnvironment.newBuilder().setContainer(cel.toCheckerBuilder().container());

// Inventory is a full set of declarations and macros that are found in the configuration of
// the supplied CEL instance.
//
Expand All@@ -171,8 +174,6 @@ public CelEnvironment export(Cel cel) {

Set<Object> inventory = new HashSet<>();
collectInventory(inventory, cel);

CelEnvironment.Builder envBuilder = CelEnvironment.newBuilder();
addExtensionConfigsAndRemoveFromInventory(envBuilder, inventory);
addStandardLibrarySubsetAndRemoveFromInventory(envBuilder, inventory);
addCustomDecls(envBuilder, inventory);
Expand Down
124 changes: 123 additions & 1 deletion bundle/src/main/java/dev/cel/bundle/CelEnvironmentYamlParser.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.ExtensionConfig;
import dev.cel.bundle.CelEnvironment.FunctionDecl;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
Expand All@@ -35,6 +36,7 @@
import dev.cel.bundle.CelEnvironment.OverloadDecl;
import dev.cel.bundle.CelEnvironment.TypeDecl;
import dev.cel.bundle.CelEnvironment.VariableDecl;
import dev.cel.common.CelContainer;
import dev.cel.common.CelIssue;
import dev.cel.common.formats.CelFileSource;
import dev.cel.common.formats.ParserContext;
Expand DownExpand Up@@ -64,6 +66,8 @@ public final class CelEnvironmentYamlParser {
private static final ExtensionConfig ERROR_EXTENSION_DECL = ExtensionConfig.of(ERROR);
private static final FunctionSelector ERROR_FUNCTION_SELECTOR =
FunctionSelector.create(ERROR, ImmutableSet.of());
private static final Alias ERROR_ALIAS =
Alias.newBuilder().setAlias(ERROR).setQualifiedName(ERROR).build();

/** Generates a new instance of {@code CelEnvironmentYamlParser}. */
public static CelEnvironmentYamlParser newInstance() {
Expand All@@ -88,6 +92,124 @@ public CelEnvironment parse(String environmentYamlSource, String description)
return parser.parseYaml(environmentYamlSource, description);
}

private CelContainer parseContainer(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
// Syntax variant 1: "container: `str`"
if (validateYamlType(node, YamlNodeType.STRING, YamlNodeType.TEXT)) {
return CelContainer.ofName(newString(ctx, node));
}

// Syntax variant 2:
// container
// name: str
// abbreviations:
// - a1
// - a2
// aliases:
// - alias: a1
// qualified_name: q1
// - alias: a2
// qualified_name: q2
if (!assertYamlType(ctx, valueId, node, YamlNodeType.MAP)) {
return CelContainer.ofName(ERROR);
}

CelContainer.Builder builder = CelContainer.newBuilder();
MappingNode variableMap = (MappingNode) node;
for (NodeTuple nodeTuple : variableMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "name":
builder.setName(newString(ctx, valueNode));
break;
case "aliases":
ImmutableSet<Alias> aliases = parseAliases(ctx, valueNode);
for (Alias alias : aliases) {
builder.addAlias(alias.alias(), alias.qualifiedName());
}
break;
case "abbreviations":
builder.addAbbreviations(parseAbbreviations(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported container tag: %s", keyName));
break;
}
}

return builder.build();
}

private ImmutableSet<Alias> parseAliases(ParserContext<Node> ctx, Node node) {
ImmutableSet.Builder<Alias> aliasSetBuilder = ImmutableSet.builder();
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return aliasSetBuilder.build();
}

SequenceNode variableListNode = (SequenceNode) node;
for (Node elementNode : variableListNode.getValue()) {
aliasSetBuilder.add(parseAlias(ctx, elementNode));
}

return aliasSetBuilder.build();
}

private Alias parseAlias(ParserContext<Node> ctx, Node node) {
long id = ctx.collectMetadata(node);
if (!assertYamlType(ctx, id, node, YamlNodeType.MAP)) {
return ERROR_ALIAS;
}

Alias.Builder builder = Alias.newBuilder();
MappingNode attrMap = (MappingNode) node;
for (NodeTuple nodeTuple : attrMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "alias":
builder.setAlias(newString(ctx, valueNode));
break;
case "qualified_name":
builder.setQualifiedName(newString(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported alias tag: %s", keyName));
break;
}
}

if (!assertRequiredFields(ctx, id, builder.getMissingRequiredFieldNames())) {
return ERROR_ALIAS;
}

return builder.build();
}

private ImmutableSet<String> parseAbbreviations(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return ImmutableSet.of(ERROR);
}

ImmutableSet.Builder<String> builder = ImmutableSet.builder();
SequenceNode nameListNode = (SequenceNode) node;
for (Node elementNode : nameListNode.getValue()) {
long elementId = ctx.collectMetadata(elementNode);
if (!assertYamlType(ctx, elementId, elementNode, YamlNodeType.STRING)) {
return ImmutableSet.of(ERROR);
}

builder.add(((ScalarNode) elementNode).getValue());
}
return builder.build();
}

private ImmutableSet<VariableDecl> parseVariables(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
ImmutableSet.Builder<VariableDecl> variableSetBuilder = ImmutableSet.builder();
Expand DownExpand Up@@ -620,7 +742,7 @@ private CelEnvironment.Builder parseConfig(ParserContext<Node> ctx, Node node) {
builder.setDescription(newString(ctx, valueNode));
break;
case "container":
builder.setContainer(newString(ctx, valueNode));
builder.setContainer(parseContainer(ctx, valueNode));
break;
case "variables":
builder.setVariables(parseVariables(ctx, valueNode));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,10 +16,13 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
import dev.cel.bundle.CelEnvironment.LibrarySubset.FunctionSelector;
import dev.cel.bundle.CelEnvironment.LibrarySubset.OverloadSelector;
import dev.cel.common.CelContainer;
import java.util.Comparator;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Node;
Expand DownExpand Up@@ -55,6 +58,8 @@ private CelEnvironmentYamlSerializer() {
CelEnvironment.LibrarySubset.FunctionSelector.class, new RepresentFunctionSelector());
this.multiRepresenters.put(
CelEnvironment.LibrarySubset.OverloadSelector.class, new RepresentOverloadSelector());
this.multiRepresenters.put(CelEnvironment.Alias.class, new RepresentAlias());
this.multiRepresenters.put(CelContainer.class, new RepresentContainer());
}

public static String toYaml(CelEnvironment environment) {
Expand All@@ -72,7 +77,9 @@ public Node representData(Object data) {
if (!environment.description().isEmpty()) {
configMap.put("description", environment.description());
}
if (!environment.container().isEmpty()) {
if (!environment.container().name().isEmpty()
|| !environment.container().abbreviations().isEmpty()
|| !environment.container().aliases().isEmpty()) {
configMap.put("container", environment.container());
}
if (!environment.extensions().isEmpty()) {
Expand All@@ -91,6 +98,43 @@ public Node representData(Object data) {
}
}

private final class RepresentContainer implements Represent {

@Override
public Node representData(Object data) {
CelContainer container = (CelContainer) data;
ImmutableMap.Builder<String, Object> configMap = ImmutableMap.builder();
if (!container.name().isEmpty()) {
configMap.put("name", container.name());
}
if (!container.abbreviations().isEmpty()) {
configMap.put("abbreviations", container.abbreviations());
}
if (!container.aliases().isEmpty()) {
ImmutableList.Builder<Alias> aliases = ImmutableList.builder();
for (Map.Entry<String, String> entry : container.aliases().entrySet()) {
aliases.add(
Alias.newBuilder()
.setAlias(entry.getKey())
.setQualifiedName(entry.getValue())
.build());
}
configMap.put("aliases", aliases.build());
}
return represent(configMap.buildOrThrow());
}
}

private final class RepresentAlias implements Represent {

@Override
public Node representData(Object data) {
Alias alias = (Alias) data;
return represent(
ImmutableMap.of("alias", alias.alias(), "qualified_name", alias.qualifiedName()));
}
}

private final class RepresentExtensionConfig implements Represent {
@Override
public Node representData(Object data) {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bundle/src/main/java/dev/cel/bundle/BUILD.bazel
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,7 +73,6 @@ java_library(
"//common/types:type_providers",
"//compiler:compiler_builder",
"//extensions",
"//extensions:optional_library",
"//parser:macro",
"//runtime",
"@maven//:com_google_errorprone_error_prone_annotations",
Expand DownExpand Up@@ -103,6 +102,7 @@ java_library(
":environment",
":environment_exception",
"//common:compiler_common",
"//common:container",
"//common/formats:file_source",
"//common/formats:parser_context",
"//common/formats:yaml_helper",
Expand Down
52 changes: 42 additions & 10 deletions bundle/src/main/java/dev/cel/bundle/CelEnvironment.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -80,10 +80,9 @@ public abstract class CelEnvironment {
public abstract String name();

/**
* An optional description of the config (example: location of the file containing the config
* content).
* Container, which captures default namespace and aliases for value resolution.
*/
public abstract String container();
public abstract CelContainer container();

/**
* An optional description of the environment (example: location of the file containing the config
Expand DownExpand Up@@ -124,7 +123,12 @@ public abstract static class Builder {

public abstract Builder setDescription(String description);

public abstract Builder setContainer(String container);
public abstract Builder setContainer(CelContainer container);

@CanIgnoreReturnValue
public Builder setContainer(String container) {
return setContainer(CelContainer.ofName(container));
}

@CanIgnoreReturnValue
public Builder addExtensions(ExtensionConfig... extensions) {
Expand DownExpand Up@@ -182,7 +186,7 @@ public static Builder newBuilder() {
return new AutoValue_CelEnvironment.Builder()
.setName("")
.setDescription("")
.setContainer("")
.setContainer(CelContainer.ofName(""))
.setVariables(ImmutableSet.of())
.setFunctions(ImmutableSet.of());
}
Expand All@@ -195,8 +199,8 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
CelCompilerBuilder compilerBuilder =
celCompiler
.toCompilerBuilder()
.setContainer(container())
.setTypeProvider(celTypeProvider)
.setContainer(CelContainer.ofName(container()))
.addVarDeclarations(
variables().stream()
.map(v -> v.toCelVarDecl(celTypeProvider))
Expand All@@ -206,10 +210,6 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
.map(f -> f.toCelFunctionDecl(celTypeProvider))
.collect(toImmutableList()));

if (!container().isEmpty()) {
compilerBuilder.setContainer(CelContainer.ofName(container()));
}

addAllCompilerExtensions(compilerBuilder, celOptions);

applyStandardLibrarySubset(compilerBuilder);
Expand DownExpand Up@@ -683,6 +683,38 @@ public static ExtensionConfig latest(String name) {
}
}

@AutoValue
abstract static class Alias {
abstract String alias();

abstract String qualifiedName();

static Builder newBuilder() {
return new AutoValue_CelEnvironment_Alias.Builder();
}

@AutoValue.Builder
abstract static class Builder implements RequiredFieldsChecker {

abstract Optional<String> alias();

abstract Optional<String> qualifiedName();

abstract Builder setAlias(String alias);

abstract Builder setQualifiedName(String qualifiedName);

abstract Alias build();

@Override
public ImmutableList<RequiredField> requiredFields() {
return ImmutableList.of(
RequiredField.of("alias", this::alias),
RequiredField.of("qualified_name", this::qualifiedName));
}
}
}

@VisibleForTesting
enum CanonicalCelExtension {
BINDINGS((options, version) -> CelExtensions.bindings()),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -161,6 +161,9 @@ public static CelEnvironmentExporter.Builder newBuilder() {
* </ul>
*/
public CelEnvironment export(Cel cel) {
CelEnvironment.Builder envBuilder =
CelEnvironment.newBuilder().setContainer(cel.toCheckerBuilder().container());

// Inventory is a full set of declarations and macros that are found in the configuration of
// the supplied CEL instance.
//
Expand All@@ -171,8 +174,6 @@ public CelEnvironment export(Cel cel) {

Set<Object> inventory = new HashSet<>();
collectInventory(inventory, cel);

CelEnvironment.Builder envBuilder = CelEnvironment.newBuilder();
addExtensionConfigsAndRemoveFromInventory(envBuilder, inventory);
addStandardLibrarySubsetAndRemoveFromInventory(envBuilder, inventory);
addCustomDecls(envBuilder, inventory);
Expand Down
124 changes: 123 additions & 1 deletion bundle/src/main/java/dev/cel/bundle/CelEnvironmentYamlParser.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.ExtensionConfig;
import dev.cel.bundle.CelEnvironment.FunctionDecl;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
Expand All@@ -35,6 +36,7 @@
import dev.cel.bundle.CelEnvironment.OverloadDecl;
import dev.cel.bundle.CelEnvironment.TypeDecl;
import dev.cel.bundle.CelEnvironment.VariableDecl;
import dev.cel.common.CelContainer;
import dev.cel.common.CelIssue;
import dev.cel.common.formats.CelFileSource;
import dev.cel.common.formats.ParserContext;
Expand DownExpand Up@@ -64,6 +66,8 @@ public final class CelEnvironmentYamlParser {
private static final ExtensionConfig ERROR_EXTENSION_DECL = ExtensionConfig.of(ERROR);
private static final FunctionSelector ERROR_FUNCTION_SELECTOR =
FunctionSelector.create(ERROR, ImmutableSet.of());
private static final Alias ERROR_ALIAS =
Alias.newBuilder().setAlias(ERROR).setQualifiedName(ERROR).build();

/** Generates a new instance of {@code CelEnvironmentYamlParser}. */
public static CelEnvironmentYamlParser newInstance() {
Expand All@@ -88,6 +92,124 @@ public CelEnvironment parse(String environmentYamlSource, String description)
return parser.parseYaml(environmentYamlSource, description);
}

private CelContainer parseContainer(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
// Syntax variant 1: "container: `str`"
if (validateYamlType(node, YamlNodeType.STRING, YamlNodeType.TEXT)) {
return CelContainer.ofName(newString(ctx, node));
}

// Syntax variant 2:
// container
// name: str
// abbreviations:
// - a1
// - a2
// aliases:
// - alias: a1
// qualified_name: q1
// - alias: a2
// qualified_name: q2
if (!assertYamlType(ctx, valueId, node, YamlNodeType.MAP)) {
return CelContainer.ofName(ERROR);
}

CelContainer.Builder builder = CelContainer.newBuilder();
MappingNode variableMap = (MappingNode) node;
for (NodeTuple nodeTuple : variableMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "name":
builder.setName(newString(ctx, valueNode));
break;
case "aliases":
ImmutableSet<Alias> aliases = parseAliases(ctx, valueNode);
for (Alias alias : aliases) {
builder.addAlias(alias.alias(), alias.qualifiedName());
}
break;
case "abbreviations":
builder.addAbbreviations(parseAbbreviations(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported container tag: %s", keyName));
break;
}
}

return builder.build();
}

private ImmutableSet<Alias> parseAliases(ParserContext<Node> ctx, Node node) {
ImmutableSet.Builder<Alias> aliasSetBuilder = ImmutableSet.builder();
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return aliasSetBuilder.build();
}

SequenceNode variableListNode = (SequenceNode) node;
for (Node elementNode : variableListNode.getValue()) {
aliasSetBuilder.add(parseAlias(ctx, elementNode));
}

return aliasSetBuilder.build();
}

private Alias parseAlias(ParserContext<Node> ctx, Node node) {
long id = ctx.collectMetadata(node);
if (!assertYamlType(ctx, id, node, YamlNodeType.MAP)) {
return ERROR_ALIAS;
}

Alias.Builder builder = Alias.newBuilder();
MappingNode attrMap = (MappingNode) node;
for (NodeTuple nodeTuple : attrMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "alias":
builder.setAlias(newString(ctx, valueNode));
break;
case "qualified_name":
builder.setQualifiedName(newString(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported alias tag: %s", keyName));
break;
}
}

if (!assertRequiredFields(ctx, id, builder.getMissingRequiredFieldNames())) {
return ERROR_ALIAS;
}

return builder.build();
}

private ImmutableSet<String> parseAbbreviations(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return ImmutableSet.of(ERROR);
}

ImmutableSet.Builder<String> builder = ImmutableSet.builder();
SequenceNode nameListNode = (SequenceNode) node;
for (Node elementNode : nameListNode.getValue()) {
long elementId = ctx.collectMetadata(elementNode);
if (!assertYamlType(ctx, elementId, elementNode, YamlNodeType.STRING)) {
return ImmutableSet.of(ERROR);
}

builder.add(((ScalarNode) elementNode).getValue());
}
return builder.build();
}

private ImmutableSet<VariableDecl> parseVariables(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
ImmutableSet.Builder<VariableDecl> variableSetBuilder = ImmutableSet.builder();
Expand DownExpand Up@@ -620,7 +742,7 @@ private CelEnvironment.Builder parseConfig(ParserContext<Node> ctx, Node node) {
builder.setDescription(newString(ctx, valueNode));
break;
case "container":
builder.setContainer(newString(ctx, valueNode));
builder.setContainer(parseContainer(ctx, valueNode));
break;
case "variables":
builder.setVariables(parseVariables(ctx, valueNode));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,10 +16,13 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
import dev.cel.bundle.CelEnvironment.LibrarySubset.FunctionSelector;
import dev.cel.bundle.CelEnvironment.LibrarySubset.OverloadSelector;
import dev.cel.common.CelContainer;
import java.util.Comparator;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Node;
Expand DownExpand Up@@ -55,6 +58,8 @@ private CelEnvironmentYamlSerializer() {
CelEnvironment.LibrarySubset.FunctionSelector.class, new RepresentFunctionSelector());
this.multiRepresenters.put(
CelEnvironment.LibrarySubset.OverloadSelector.class, new RepresentOverloadSelector());
this.multiRepresenters.put(CelEnvironment.Alias.class, new RepresentAlias());
this.multiRepresenters.put(CelContainer.class, new RepresentContainer());
}

public static String toYaml(CelEnvironment environment) {
Expand All@@ -72,7 +77,9 @@ public Node representData(Object data) {
if (!environment.description().isEmpty()) {
configMap.put("description", environment.description());
}
if (!environment.container().isEmpty()) {
if (!environment.container().name().isEmpty()
|| !environment.container().abbreviations().isEmpty()
|| !environment.container().aliases().isEmpty()) {
configMap.put("container", environment.container());
}
if (!environment.extensions().isEmpty()) {
Expand All@@ -91,6 +98,43 @@ public Node representData(Object data) {
}
}

private final class RepresentContainer implements Represent {

@Override
public Node representData(Object data) {
CelContainer container = (CelContainer) data;
ImmutableMap.Builder<String, Object> configMap = ImmutableMap.builder();
if (!container.name().isEmpty()) {
configMap.put("name", container.name());
}
if (!container.abbreviations().isEmpty()) {
configMap.put("abbreviations", container.abbreviations());
}
if (!container.aliases().isEmpty()) {
ImmutableList.Builder<Alias> aliases = ImmutableList.builder();
for (Map.Entry<String, String> entry : container.aliases().entrySet()) {
aliases.add(
Alias.newBuilder()
.setAlias(entry.getKey())
.setQualifiedName(entry.getValue())
.build());
}
configMap.put("aliases", aliases.build());
}
return represent(configMap.buildOrThrow());
}
}

private final class RepresentAlias implements Represent {

@Override
public Node representData(Object data) {
Alias alias = (Alias) data;
return represent(
ImmutableMap.of("alias", alias.alias(), "qualified_name", alias.qualifiedName()));
}
}

private final class RepresentExtensionConfig implements Represent {
@Override
public Node representData(Object data) {
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bundle/src/main/java/dev/cel/bundle/BUILD.bazel
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,7 +73,6 @@ java_library(
"//common/types:type_providers",
"//compiler:compiler_builder",
"//extensions",
"//extensions:optional_library",
"//parser:macro",
"//runtime",
"@maven//:com_google_errorprone_error_prone_annotations",
Expand DownExpand Up@@ -103,6 +102,7 @@ java_library(
":environment",
":environment_exception",
"//common:compiler_common",
"//common:container",
"//common/formats:file_source",
"//common/formats:parser_context",
"//common/formats:yaml_helper",
Expand Down
52 changes: 42 additions & 10 deletions bundle/src/main/java/dev/cel/bundle/CelEnvironment.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -80,10 +80,9 @@ public abstract class CelEnvironment {
public abstract String name();

/**
* An optional description of the config (example: location of the file containing the config
* content).
* Container, which captures default namespace and aliases for value resolution.
*/
public abstract String container();
public abstract CelContainer container();

/**
* An optional description of the environment (example: location of the file containing the config
Expand DownExpand Up@@ -124,7 +123,12 @@ public abstract static class Builder {

public abstract Builder setDescription(String description);

public abstract Builder setContainer(String container);
public abstract Builder setContainer(CelContainer container);

@CanIgnoreReturnValue
public Builder setContainer(String container) {
return setContainer(CelContainer.ofName(container));
}

@CanIgnoreReturnValue
public Builder addExtensions(ExtensionConfig... extensions) {
Expand DownExpand Up@@ -182,7 +186,7 @@ public static Builder newBuilder() {
return new AutoValue_CelEnvironment.Builder()
.setName("")
.setDescription("")
.setContainer("")
.setContainer(CelContainer.ofName(""))
.setVariables(ImmutableSet.of())
.setFunctions(ImmutableSet.of());
}
Expand All@@ -195,8 +199,8 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
CelCompilerBuilder compilerBuilder =
celCompiler
.toCompilerBuilder()
.setContainer(container())
.setTypeProvider(celTypeProvider)
.setContainer(CelContainer.ofName(container()))
.addVarDeclarations(
variables().stream()
.map(v -> v.toCelVarDecl(celTypeProvider))
Expand All@@ -206,10 +210,6 @@ public CelCompiler extend(CelCompiler celCompiler, CelOptions celOptions)
.map(f -> f.toCelFunctionDecl(celTypeProvider))
.collect(toImmutableList()));

if (!container().isEmpty()) {
compilerBuilder.setContainer(CelContainer.ofName(container()));
}

addAllCompilerExtensions(compilerBuilder, celOptions);

applyStandardLibrarySubset(compilerBuilder);
Expand DownExpand Up@@ -683,6 +683,38 @@ public static ExtensionConfig latest(String name) {
}
}

@AutoValue
abstract static class Alias {
abstract String alias();

abstract String qualifiedName();

static Builder newBuilder() {
return new AutoValue_CelEnvironment_Alias.Builder();
}

@AutoValue.Builder
abstract static class Builder implements RequiredFieldsChecker {

abstract Optional<String> alias();

abstract Optional<String> qualifiedName();

abstract Builder setAlias(String alias);

abstract Builder setQualifiedName(String qualifiedName);

abstract Alias build();

@Override
public ImmutableList<RequiredField> requiredFields() {
return ImmutableList.of(
RequiredField.of("alias", this::alias),
RequiredField.of("qualified_name", this::qualifiedName));
}
}
}

@VisibleForTesting
enum CanonicalCelExtension {
BINDINGS((options, version) -> CelExtensions.bindings()),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -161,6 +161,9 @@ public static CelEnvironmentExporter.Builder newBuilder() {
* </ul>
*/
public CelEnvironment export(Cel cel) {
CelEnvironment.Builder envBuilder =
CelEnvironment.newBuilder().setContainer(cel.toCheckerBuilder().container());

// Inventory is a full set of declarations and macros that are found in the configuration of
// the supplied CEL instance.
//
Expand All@@ -171,8 +174,6 @@ public CelEnvironment export(Cel cel) {

Set<Object> inventory = new HashSet<>();
collectInventory(inventory, cel);

CelEnvironment.Builder envBuilder = CelEnvironment.newBuilder();
addExtensionConfigsAndRemoveFromInventory(envBuilder, inventory);
addStandardLibrarySubsetAndRemoveFromInventory(envBuilder, inventory);
addCustomDecls(envBuilder, inventory);
Expand Down
124 changes: 123 additions & 1 deletion bundle/src/main/java/dev/cel/bundle/CelEnvironmentYamlParser.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.ExtensionConfig;
import dev.cel.bundle.CelEnvironment.FunctionDecl;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
Expand All@@ -35,6 +36,7 @@
import dev.cel.bundle.CelEnvironment.OverloadDecl;
import dev.cel.bundle.CelEnvironment.TypeDecl;
import dev.cel.bundle.CelEnvironment.VariableDecl;
import dev.cel.common.CelContainer;
import dev.cel.common.CelIssue;
import dev.cel.common.formats.CelFileSource;
import dev.cel.common.formats.ParserContext;
Expand DownExpand Up@@ -64,6 +66,8 @@ public final class CelEnvironmentYamlParser {
private static final ExtensionConfig ERROR_EXTENSION_DECL = ExtensionConfig.of(ERROR);
private static final FunctionSelector ERROR_FUNCTION_SELECTOR =
FunctionSelector.create(ERROR, ImmutableSet.of());
private static final Alias ERROR_ALIAS =
Alias.newBuilder().setAlias(ERROR).setQualifiedName(ERROR).build();

/** Generates a new instance of {@code CelEnvironmentYamlParser}. */
public static CelEnvironmentYamlParser newInstance() {
Expand All@@ -88,6 +92,124 @@ public CelEnvironment parse(String environmentYamlSource, String description)
return parser.parseYaml(environmentYamlSource, description);
}

private CelContainer parseContainer(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
// Syntax variant 1: "container: `str`"
if (validateYamlType(node, YamlNodeType.STRING, YamlNodeType.TEXT)) {
return CelContainer.ofName(newString(ctx, node));
}

// Syntax variant 2:
// container
// name: str
// abbreviations:
// - a1
// - a2
// aliases:
// - alias: a1
// qualified_name: q1
// - alias: a2
// qualified_name: q2
if (!assertYamlType(ctx, valueId, node, YamlNodeType.MAP)) {
return CelContainer.ofName(ERROR);
}

CelContainer.Builder builder = CelContainer.newBuilder();
MappingNode variableMap = (MappingNode) node;
for (NodeTuple nodeTuple : variableMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "name":
builder.setName(newString(ctx, valueNode));
break;
case "aliases":
ImmutableSet<Alias> aliases = parseAliases(ctx, valueNode);
for (Alias alias : aliases) {
builder.addAlias(alias.alias(), alias.qualifiedName());
}
break;
case "abbreviations":
builder.addAbbreviations(parseAbbreviations(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported container tag: %s", keyName));
break;
}
}

return builder.build();
}

private ImmutableSet<Alias> parseAliases(ParserContext<Node> ctx, Node node) {
ImmutableSet.Builder<Alias> aliasSetBuilder = ImmutableSet.builder();
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return aliasSetBuilder.build();
}

SequenceNode variableListNode = (SequenceNode) node;
for (Node elementNode : variableListNode.getValue()) {
aliasSetBuilder.add(parseAlias(ctx, elementNode));
}

return aliasSetBuilder.build();
}

private Alias parseAlias(ParserContext<Node> ctx, Node node) {
long id = ctx.collectMetadata(node);
if (!assertYamlType(ctx, id, node, YamlNodeType.MAP)) {
return ERROR_ALIAS;
}

Alias.Builder builder = Alias.newBuilder();
MappingNode attrMap = (MappingNode) node;
for (NodeTuple nodeTuple : attrMap.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
long keyId = ctx.collectMetadata(keyNode);
Node valueNode = nodeTuple.getValueNode();
String keyName = ((ScalarNode) keyNode).getValue();
switch (keyName) {
case "alias":
builder.setAlias(newString(ctx, valueNode));
break;
case "qualified_name":
builder.setQualifiedName(newString(ctx, valueNode));
break;
default:
ctx.reportError(keyId, String.format("Unsupported alias tag: %s", keyName));
break;
}
}

if (!assertRequiredFields(ctx, id, builder.getMissingRequiredFieldNames())) {
return ERROR_ALIAS;
}

return builder.build();
}

private ImmutableSet<String> parseAbbreviations(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
if (!assertYamlType(ctx, valueId, node, YamlNodeType.LIST)) {
return ImmutableSet.of(ERROR);
}

ImmutableSet.Builder<String> builder = ImmutableSet.builder();
SequenceNode nameListNode = (SequenceNode) node;
for (Node elementNode : nameListNode.getValue()) {
long elementId = ctx.collectMetadata(elementNode);
if (!assertYamlType(ctx, elementId, elementNode, YamlNodeType.STRING)) {
return ImmutableSet.of(ERROR);
}

builder.add(((ScalarNode) elementNode).getValue());
}
return builder.build();
}

private ImmutableSet<VariableDecl> parseVariables(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
ImmutableSet.Builder<VariableDecl> variableSetBuilder = ImmutableSet.builder();
Expand DownExpand Up@@ -620,7 +742,7 @@ private CelEnvironment.Builder parseConfig(ParserContext<Node> ctx, Node node) {
builder.setDescription(newString(ctx, valueNode));
break;
case "container":
builder.setContainer(newString(ctx, valueNode));
builder.setContainer(parseContainer(ctx, valueNode));
break;
case "variables":
builder.setVariables(parseVariables(ctx, valueNode));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,10 +16,13 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import dev.cel.bundle.CelEnvironment.Alias;
import dev.cel.bundle.CelEnvironment.LibrarySubset;
import dev.cel.bundle.CelEnvironment.LibrarySubset.FunctionSelector;
import dev.cel.bundle.CelEnvironment.LibrarySubset.OverloadSelector;
import dev.cel.common.CelContainer;
import java.util.Comparator;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Node;
Expand DownExpand Up@@ -55,6 +58,8 @@ private CelEnvironmentYamlSerializer() {
CelEnvironment.LibrarySubset.FunctionSelector.class, new RepresentFunctionSelector());
this.multiRepresenters.put(
CelEnvironment.LibrarySubset.OverloadSelector.class, new RepresentOverloadSelector());
this.multiRepresenters.put(CelEnvironment.Alias.class, new RepresentAlias());
this.multiRepresenters.put(CelContainer.class, new RepresentContainer());
}

public static String toYaml(CelEnvironment environment) {
Expand All@@ -72,7 +77,9 @@ public Node representData(Object data) {
if (!environment.description().isEmpty()) {
configMap.put("description", environment.description());
}
if (!environment.container().isEmpty()) {
if (!environment.container().name().isEmpty()
|| !environment.container().abbreviations().isEmpty()
|| !environment.container().aliases().isEmpty()) {
configMap.put("container", environment.container());
}
if (!environment.extensions().isEmpty()) {
Expand All@@ -91,6 +98,43 @@ public Node representData(Object data) {
}
}

private final class RepresentContainer implements Represent {

@Override
public Node representData(Object data) {
CelContainer container = (CelContainer) data;
ImmutableMap.Builder<String, Object> configMap = ImmutableMap.builder();
if (!container.name().isEmpty()) {
configMap.put("name", container.name());
}
if (!container.abbreviations().isEmpty()) {
configMap.put("abbreviations", container.abbreviations());
}
if (!container.aliases().isEmpty()) {
ImmutableList.Builder<Alias> aliases = ImmutableList.builder();
for (Map.Entry<String, String> entry : container.aliases().entrySet()) {
aliases.add(
Alias.newBuilder()
.setAlias(entry.getKey())
.setQualifiedName(entry.getValue())
.build());
}
configMap.put("aliases", aliases.build());
}
return represent(configMap.buildOrThrow());
}
}

private final class RepresentAlias implements Represent {

@Override
public Node representData(Object data) {
Alias alias = (Alias) data;
return represent(
ImmutableMap.of("alias", alias.alias(), "qualified_name", alias.qualifiedName()));
}
}

private final class RepresentExtensionConfig implements Represent {
@Override
public Node representData(Object data) {
Expand Down
Loading
Loading