dev.cel.parser.CelMacro Maven / Gradle / Ivy
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package dev.cel.parser;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import com.google.auto.value.AutoValue;
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.errorprone.annotations.Immutable;
/** Describes a function signature to match and the {@link CelMacroExpander} to apply. */
@AutoValue
@Immutable
public abstract class CelMacro implements Comparable {
// Package-private default constructor to prevent extensions outside of the codebase.
CelMacro() {}
/** Returns the function name for this macro. */
public abstract String getFunction();
/** Returns the number of arguments this macro expects. For variadic macros, this is 0. */
public abstract int getArgumentCount();
abstract boolean getReceiverStyle();
/** True if this macro is receiver-style, false if it is global. */
public final boolean isReceiverStyle() {
return getReceiverStyle();
}
/** Returns the unique string used to identify this macro. */
public abstract String getKey();
abstract boolean getVariadic();
/** Returns true if this macro accepts any number of arguments, false otherwise. */
public final boolean isVariadic() {
return getVariadic();
}
/** Returns the expander for this macro. */
public abstract CelMacroExpander getExpander();
@Override
public final int compareTo(CelMacro other) {
if (other == null) {
return 1;
}
int diff = getFunction().compareTo(other.getFunction());
if (diff != 0) {
return diff;
}
diff = Boolean.compare(!isVariadic(), !other.isVariadic());
if (diff != 0) {
return diff;
}
if (!isVariadic()) {
diff = Integer.compare(getArgumentCount(), other.getArgumentCount());
if (diff != 0) {
return diff;
}
}
return Boolean.compare(isReceiverStyle(), other.isReceiverStyle());
}
@Override
public final String toString() {
return getKey();
}
@Override
public final int hashCode() {
return getKey().hashCode();
}
@Override
public final boolean equals(Object other) {
return other instanceof CelMacro && getKey().equals(((CelMacro) other).getKey());
}
static Builder newBuilder() {
return new AutoValue_CelMacro.Builder();
}
/** Creates a new global macro that accepts a fixed number of arguments. */
public static CelMacro newGlobalMacro(String function, int argCount, CelMacroExpander expander) {
checkArgument(!isNullOrEmpty(function));
checkArgument(argCount >= 0);
checkNotNull(expander);
return newBuilder()
.setFunction(function)
.setArgumentCount(argCount)
.setReceiverStyle(false)
.setKey(formatKey(function, argCount, false))
.setVariadic(false)
.setExpander(expander)
.build();
}
/** Creates a new global macro that accepts a variable number of arguments. */
public static CelMacro newGlobalVarArgMacro(String function, CelMacroExpander expander) {
checkArgument(!isNullOrEmpty(function));
checkNotNull(expander);
return newBuilder()
.setFunction(function)
.setArgumentCount(0)
.setReceiverStyle(false)
.setKey(formatVarArgKey(function, false))
.setVariadic(true)
.setExpander(expander)
.build();
}
/** Creates a new receiver-style macro that accepts a fixed number of arguments. */
public static CelMacro newReceiverMacro(
String function, int argCount, CelMacroExpander expander) {
checkArgument(!isNullOrEmpty(function));
checkArgument(argCount >= 0);
checkNotNull(expander);
return newBuilder()
.setFunction(function)
.setArgumentCount(argCount)
.setReceiverStyle(true)
.setKey(formatKey(function, argCount, true))
.setVariadic(false)
.setExpander(expander)
.build();
}
/** Creates a new receiver-style macro that accepts a variable number of arguments. */
public static CelMacro newReceiverVarArgMacro(String function, CelMacroExpander expander) {
checkArgument(!isNullOrEmpty(function));
checkNotNull(expander);
return newBuilder()
.setFunction(function)
.setArgumentCount(0)
.setReceiverStyle(true)
.setKey(formatVarArgKey(function, true))
.setVariadic(true)
.setExpander(expander)
.build();
}
static String formatKey(String function, int argCount, boolean receiverStyle) {
checkArgument(!isNullOrEmpty(function));
checkArgument(argCount >= 0);
return String.format("%s:%d:%s", function, argCount, receiverStyle);
}
static String formatVarArgKey(String function, boolean receiverStyle) {
checkArgument(!isNullOrEmpty(function));
return String.format("%s:*:%s", function, receiverStyle);
}
@AutoValue.Builder
abstract static class Builder {
abstract Builder setFunction(String function);
abstract Builder setArgumentCount(int argumentCount);
abstract Builder setReceiverStyle(boolean receiverStyle);
abstract Builder setKey(String key);
abstract Builder setVariadic(boolean variadic);
abstract Builder setExpander(CelMacroExpander expander);
@CheckReturnValue
abstract CelMacro build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy