Skip to content

Commit

Permalink
Move standard macro definitions from CelMacro to CelStandardMacro
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 598901986
  • Loading branch information
l46kok authored and copybara-github committed Jan 16, 2024
1 parent 8ff0918 commit 562ec94
Show file tree
Hide file tree
Showing 7 changed files with 352 additions and 376 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import dev.cel.common.types.SimpleType;
import dev.cel.compiler.CelCompiler;
import dev.cel.compiler.CelCompilerFactory;
import dev.cel.parser.CelMacro;
import dev.cel.parser.CelStandardMacro;
import dev.cel.runtime.CelRuntime;
import dev.cel.runtime.CelRuntime.CelFunctionBinding;
import dev.cel.runtime.CelRuntimeFactory;
Expand All @@ -39,7 +39,7 @@ public final class CelBindingsExtensionsTest {

private static final CelCompiler COMPILER =
CelCompilerFactory.standardCelCompilerBuilder()
.addMacros(CelMacro.STANDARD_MACROS)
.setStandardMacros(CelStandardMacro.STANDARD_MACROS)
.addLibraries(CelExtensions.bindings())
.build();

Expand Down
239 changes: 0 additions & 239 deletions parser/src/main/java/dev/cel/parser/CelMacro.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,70 +19,13 @@
import static com.google.common.base.Strings.isNullOrEmpty;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.errorprone.annotations.Immutable;
import dev.cel.common.CelIssue;
import dev.cel.common.ast.CelExpr;
import java.util.Optional;

/** Describes a function signature to match and the {@link CelMacroExpander} to apply. */
@AutoValue
@Immutable
public abstract class CelMacro implements Comparable<CelMacro> {

private static final String ACCUMULATOR_VAR = "__result__";

/** Field presence test macro */
public static final CelMacro HAS =
newGlobalMacro(Operator.HAS.getFunction(), 1, CelMacro::expandHasMacro);

/**
* Boolean comprehension which asserts that a predicate holds true for all elements in the input
* range.
*/
public static final CelMacro ALL =
newReceiverMacro(Operator.ALL.getFunction(), 2, CelMacro::expandAllMacro);

/**
* Boolean comprehension which asserts that a predicate holds true for at least one element in the
* input range.
*/
public static final CelMacro EXISTS =
newReceiverMacro(Operator.EXISTS.getFunction(), 2, CelMacro::expandExistsMacro);

/**
* Boolean comprehension which asserts that a predicate holds true for exactly one element in the
* input range.
*/
public static final CelMacro EXISTS_ONE =
newReceiverMacro(Operator.EXISTS_ONE.getFunction(), 2, CelMacro::expandExistsOneMacro);

/**
* Comprehension which applies a transform to each element in the input range and produces a list
* of equivalent size as output.
*/
public static final CelMacro MAP =
newReceiverMacro(Operator.MAP.getFunction(), 2, CelMacro::expandMapMacro);

/**
* Comprehension which conditionally applies a transform to elements in the list which satisfy the
* filter predicate.
*/
public static final CelMacro MAP_FILTER =
newReceiverMacro(Operator.MAP.getFunction(), 3, CelMacro::expandMapMacro);

/**
* Comprehension which produces a list containing elements in the input range which match the
* filter.
*/
public static final CelMacro FILTER =
newReceiverMacro(Operator.FILTER.getFunction(), 2, CelMacro::expandFilterMacro);

/** Set of all standard macros supported by the CEL spec. */
public static final ImmutableList<CelMacro> STANDARD_MACROS =
ImmutableList.of(HAS, ALL, EXISTS, EXISTS_ONE, MAP, MAP_FILTER, FILTER);

// Package-private default constructor to prevent extensions outside of the codebase.
CelMacro() {}

Expand Down Expand Up @@ -241,186 +184,4 @@ abstract static class Builder {
@CheckReturnValue
abstract CelMacro build();
}

// CelMacroExpander implementation for CEL's has() macro.
private static Optional<CelExpr> expandHasMacro(
CelMacroExprFactory exprFactory, CelExpr target, ImmutableList<CelExpr> arguments) {
checkNotNull(exprFactory);
checkNotNull(target);
checkArgument(arguments.size() == 1);
CelExpr arg = checkNotNull(arguments.get(0));
if (arg.exprKind().getKind() != CelExpr.ExprKind.Kind.SELECT) {
return Optional.of(exprFactory.reportError("invalid argument to has() macro"));
}
return Optional.of(exprFactory.newSelect(arg.select().operand(), arg.select().field(), true));
}

// CelMacroExpander implementation for CEL's all() macro.
private static Optional<CelExpr> expandAllMacro(
CelMacroExprFactory exprFactory, CelExpr target, ImmutableList<CelExpr> arguments) {
checkNotNull(exprFactory);
checkNotNull(target);
checkArgument(arguments.size() == 2);
CelExpr arg0 = checkNotNull(arguments.get(0));
if (arg0.exprKind().getKind() != CelExpr.ExprKind.Kind.IDENT) {
return Optional.of(reportArgumentError(exprFactory, arg0));
}
CelExpr arg1 = checkNotNull(arguments.get(1));
CelExpr accuInit = exprFactory.newBoolLiteral(true);
CelExpr condition =
exprFactory.newGlobalCall(
Operator.NOT_STRICTLY_FALSE.getFunction(), exprFactory.newIdentifier(ACCUMULATOR_VAR));
CelExpr step =
exprFactory.newGlobalCall(
Operator.LOGICAL_AND.getFunction(), exprFactory.newIdentifier(ACCUMULATOR_VAR), arg1);
CelExpr result = exprFactory.newIdentifier(ACCUMULATOR_VAR);
return Optional.of(
exprFactory.fold(
arg0.ident().name(), target, ACCUMULATOR_VAR, accuInit, condition, step, result));
}

// CelMacroExpander implementation for CEL's exists() macro.
private static Optional<CelExpr> expandExistsMacro(
CelMacroExprFactory exprFactory, CelExpr target, ImmutableList<CelExpr> arguments) {
checkNotNull(exprFactory);
checkNotNull(target);
checkArgument(arguments.size() == 2);
CelExpr arg0 = checkNotNull(arguments.get(0));
if (arg0.exprKind().getKind() != CelExpr.ExprKind.Kind.IDENT) {
return Optional.of(reportArgumentError(exprFactory, arg0));
}
CelExpr arg1 = checkNotNull(arguments.get(1));
CelExpr accuInit = exprFactory.newBoolLiteral(false);
CelExpr condition =
exprFactory.newGlobalCall(
Operator.NOT_STRICTLY_FALSE.getFunction(),
exprFactory.newGlobalCall(
Operator.LOGICAL_NOT.getFunction(), exprFactory.newIdentifier(ACCUMULATOR_VAR)));
CelExpr step =
exprFactory.newGlobalCall(
Operator.LOGICAL_OR.getFunction(), exprFactory.newIdentifier(ACCUMULATOR_VAR), arg1);
CelExpr result = exprFactory.newIdentifier(ACCUMULATOR_VAR);
return Optional.of(
exprFactory.fold(
arg0.ident().name(), target, ACCUMULATOR_VAR, accuInit, condition, step, result));
}

// CelMacroExpander implementation for CEL's exists_one() macro.
private static Optional<CelExpr> expandExistsOneMacro(
CelMacroExprFactory exprFactory, CelExpr target, ImmutableList<CelExpr> arguments) {
checkNotNull(exprFactory);
checkNotNull(target);
checkArgument(arguments.size() == 2);
CelExpr arg0 = checkNotNull(arguments.get(0));
if (arg0.exprKind().getKind() != CelExpr.ExprKind.Kind.IDENT) {
return Optional.of(reportArgumentError(exprFactory, arg0));
}
CelExpr arg1 = checkNotNull(arguments.get(1));
CelExpr zeroExpr = exprFactory.newIntLiteral(0);
CelExpr oneExpr = exprFactory.newIntLiteral(1);
CelExpr accuInit = zeroExpr;
CelExpr condition = exprFactory.newBoolLiteral(true);
CelExpr step =
exprFactory.newGlobalCall(
Operator.CONDITIONAL.getFunction(),
arg1,
exprFactory.newGlobalCall(
Operator.ADD.getFunction(), exprFactory.newIdentifier(ACCUMULATOR_VAR), oneExpr),
exprFactory.newIdentifier(ACCUMULATOR_VAR));
CelExpr result =
exprFactory.newGlobalCall(
Operator.EQUALS.getFunction(), exprFactory.newIdentifier(ACCUMULATOR_VAR), oneExpr);
return Optional.of(
exprFactory.fold(
arg0.ident().name(), target, ACCUMULATOR_VAR, accuInit, condition, step, result));
}

// CelMacroExpander implementation for CEL's map() macro.
private static Optional<CelExpr> expandMapMacro(
CelMacroExprFactory exprFactory, CelExpr target, ImmutableList<CelExpr> arguments) {
checkNotNull(exprFactory);
checkNotNull(target);
checkArgument(arguments.size() == 2 || arguments.size() == 3);
CelExpr arg0 = checkNotNull(arguments.get(0));
if (arg0.exprKind().getKind() != CelExpr.ExprKind.Kind.IDENT) {
return Optional.of(
exprFactory.reportError(
CelIssue.formatError(
exprFactory.getSourceLocation(arg0), "argument is not an identifier")));
}
CelExpr arg1;
CelExpr arg2;
if (arguments.size() == 3) {
arg2 = checkNotNull(arguments.get(1));
arg1 = checkNotNull(arguments.get(2));
} else {
arg1 = checkNotNull(arguments.get(1));
arg2 = null;
}
CelExpr accuInit = exprFactory.newList();
CelExpr condition = exprFactory.newBoolLiteral(true);
CelExpr step =
exprFactory.newGlobalCall(
Operator.ADD.getFunction(),
exprFactory.newIdentifier(ACCUMULATOR_VAR),
exprFactory.newList(arg1));
if (arg2 != null) {
step =
exprFactory.newGlobalCall(
Operator.CONDITIONAL.getFunction(),
arg2,
step,
exprFactory.newIdentifier(ACCUMULATOR_VAR));
}
return Optional.of(
exprFactory.fold(
arg0.ident().name(),
target,
ACCUMULATOR_VAR,
accuInit,
condition,
step,
exprFactory.newIdentifier(ACCUMULATOR_VAR)));
}

// CelMacroExpander implementation for CEL's filter() macro.
private static Optional<CelExpr> expandFilterMacro(
CelMacroExprFactory exprFactory, CelExpr target, ImmutableList<CelExpr> arguments) {
checkNotNull(exprFactory);
checkNotNull(target);
checkArgument(arguments.size() == 2);
CelExpr arg0 = checkNotNull(arguments.get(0));
if (arg0.exprKind().getKind() != CelExpr.ExprKind.Kind.IDENT) {
return Optional.of(reportArgumentError(exprFactory, arg0));
}
CelExpr arg1 = checkNotNull(arguments.get(1));
CelExpr accuInit = exprFactory.newList();
CelExpr condition = exprFactory.newBoolLiteral(true);
CelExpr step =
exprFactory.newGlobalCall(
Operator.ADD.getFunction(),
exprFactory.newIdentifier(ACCUMULATOR_VAR),
exprFactory.newList(arg0));
step =
exprFactory.newGlobalCall(
Operator.CONDITIONAL.getFunction(),
arg1,
step,
exprFactory.newIdentifier(ACCUMULATOR_VAR));
return Optional.of(
exprFactory.fold(
arg0.ident().name(),
target,
ACCUMULATOR_VAR,
accuInit,
condition,
step,
exprFactory.newIdentifier(ACCUMULATOR_VAR)));
}

private static CelExpr reportArgumentError(CelMacroExprFactory exprFactory, CelExpr argument) {
return exprFactory.reportError(
CelIssue.formatError(
exprFactory.getSourceLocation(argument), "The argument must be a simple name"));
}
}
Loading

0 comments on commit 562ec94

Please sign in to comment.