All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.cel.common.ast.CelExprFactory Maven / Gradle / Ivy

// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dev.cel.common.ast;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;

import com.google.common.primitives.UnsignedLong;
import com.google.protobuf.ByteString;
import dev.cel.common.annotations.Internal;
import java.util.Arrays;

/** Factory for generating expression nodes. */
@Internal
public class CelExprFactory {

  private final CelExprIdGeneratorFactory.ExprIdGenerator idGenerator;

  public static CelExprFactory newInstance() {
    return new CelExprFactory();
  }

  public static CelExprFactory newInstance(
      CelExprIdGeneratorFactory.ExprIdGenerator exprIdGenerator) {
    return new CelExprFactory(exprIdGenerator);
  }

  /** Create a new constant expression. */
  public final CelExpr newConstant(CelConstant constant) {
    return CelExpr.newBuilder().setId(nextExprId()).setConstant(constant).build();
  }

  /** Creates a new constant {@link CelExpr} for a bool value. */
  public final CelExpr newBoolLiteral(boolean value) {
    return newConstant(CelConstant.ofValue(value));
  }

  /** Creates a new constant {@link CelExpr} for a bytes value. */
  public final CelExpr newBytesLiteral(ByteString value) {
    return newConstant(CelConstant.ofValue(value));
  }

  /** Creates a new constant {@link CelExpr} for a bytes value. */
  public final CelExpr newBytesLiteral(byte[] value) {
    return newBytesLiteral(value, 0, value.length);
  }

  /** Creates a new constant {@link CelExpr} for a bytes value. */
  public final CelExpr newBytesLiteral(byte[] value, int offset, int size) {
    return newBytesLiteral(ByteString.copyFrom(value, offset, size));
  }

  /** Creates a new constant {@link CelExpr} for a bytes value. */
  public final CelExpr newBytesLiteral(String value) {
    return newBytesLiteral(ByteString.copyFromUtf8(value));
  }

  /** Creates a new constant {@link CelExpr} for a double value. */
  public final CelExpr newDoubleLiteral(double value) {
    return newConstant(CelConstant.ofValue(value));
  }

  /** Creates a new constant {@link CelExpr} for an int value. */
  public final CelExpr newIntLiteral(long value) {
    return newConstant(CelConstant.ofValue(value));
  }

  /** Creates a new constant {@link CelExpr} for a string value. */
  public final CelExpr newStringLiteral(String value) {
    return newConstant(CelConstant.ofValue(value));
  }

  /** Creates a new constant {@link CelExpr} for a uint value. */
  public final CelExpr newUintLiteral(long value) {
    return newConstant(CelConstant.ofValue(UnsignedLong.fromLongBits(value)));
  }

  /** Creates a new list {@link CelExpr} comprised of the elements. */
  public final CelExpr newList(CelExpr... elements) {
    return newList(Arrays.asList(elements));
  }

  /** Creates a new list {@link CelExpr} comprised of the elements. */
  public final CelExpr newList(Iterable elements) {
    return CelExpr.newBuilder()
        .setId(nextExprId())
        .setCreateList(CelExpr.CelCreateList.newBuilder().addElements(elements).build())
        .build();
  }

  /** Creates a new map {@link CelExpr} comprised of the entries. */
  public final CelExpr newMap(CelExpr.CelCreateMap.Entry... entries) {
    return newMap(Arrays.asList(entries));
  }

  /** Creates a new map {@link CelExpr} comprised of the entries. */
  public final CelExpr newMap(Iterable entries) {
    return CelExpr.newBuilder()
        .setId(nextExprId())
        .setCreateMap(CelExpr.CelCreateMap.newBuilder().addEntries(entries).build())
        .build();
  }

  /**
   * Creates a new map {@link CelExpr.CelCreateStruct.Entry} comprised of the given key and value.
   */
  public final CelExpr.CelCreateMap.Entry newMapEntry(CelExpr key, CelExpr value) {
    return CelExpr.CelCreateMap.Entry.newBuilder()
        .setId(nextExprId())
        .setKey(key)
        .setValue(value)
        .build();
  }

  /** Creates a new message {@link CelExpr} of the given type comprised of the given fields. */
  public final CelExpr newMessage(String typeName, CelExpr.CelCreateStruct.Entry... fields) {
    return newMessage(typeName, Arrays.asList(fields));
  }

  /** Creates a new message {@link CelExpr} of the given type comprised of the given fields. */
  public final CelExpr newMessage(String typeName, Iterable fields) {
    checkArgument(!isNullOrEmpty(typeName));
    return CelExpr.newBuilder()
        .setId(nextExprId())
        .setCreateStruct(
            CelExpr.CelCreateStruct.newBuilder()
                .setMessageName(typeName)
                .addEntries(fields)
                .build())
        .build();
  }

  /**
   * Creates a new message {@link CelExpr.CelCreateStruct.Entry} comprised of the given field and
   * value.
   */
  public final CelExpr.CelCreateStruct.Entry newMessageField(String field, CelExpr value) {
    checkArgument(!isNullOrEmpty(field));
    return CelExpr.CelCreateStruct.Entry.newBuilder()
        .setId(nextExprId())
        .setFieldKey(field)
        .setValue(value)
        .build();
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr condition,
      CelExpr step,
      CelExpr result) {
    checkArgument(!isNullOrEmpty(iterVar));
    checkArgument(!isNullOrEmpty(accuVar));
    return CelExpr.newBuilder()
        .setId(nextExprId())
        .setComprehension(
            CelExpr.CelComprehension.newBuilder()
                .setIterVar(iterVar)
                .setIterRange(iterRange)
                .setAccuVar(accuVar)
                .setAccuInit(accuInit)
                .setLoopCondition(condition)
                .setLoopStep(step)
                .setResult(result)
                .build())
        .build();
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr condition,
      CelExpr step,
      CelExpr result) {
    return fold(iterVar, iterRange.build(), accuVar, accuInit, condition, step, result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr iterRange,
      String accuVar,
      CelExpr.Builder accuInit,
      CelExpr condition,
      CelExpr step,
      CelExpr result) {
    return fold(iterVar, iterRange, accuVar, accuInit.build(), condition, step, result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr.Builder condition,
      CelExpr step,
      CelExpr result) {
    return fold(iterVar, iterRange, accuVar, accuInit, condition.build(), step, result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr condition,
      CelExpr.Builder step,
      CelExpr result) {
    return fold(iterVar, iterRange, accuVar, accuInit, condition, step.build(), result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr condition,
      CelExpr step,
      CelExpr.Builder result) {
    return fold(iterVar, iterRange, accuVar, accuInit, condition, step, result.build());
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr.Builder accuInit,
      CelExpr condition,
      CelExpr step,
      CelExpr result) {
    return fold(iterVar, iterRange.build(), accuVar, accuInit.build(), condition, step, result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr.Builder condition,
      CelExpr step,
      CelExpr result) {
    return fold(iterVar, iterRange.build(), accuVar, accuInit, condition.build(), step, result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr condition,
      CelExpr.Builder step,
      CelExpr result) {
    return fold(iterVar, iterRange.build(), accuVar, accuInit, condition, step.build(), result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr condition,
      CelExpr step,
      CelExpr.Builder result) {
    return fold(iterVar, iterRange.build(), accuVar, accuInit, condition, step, result.build());
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr iterRange,
      String accuVar,
      CelExpr.Builder accuInit,
      CelExpr.Builder condition,
      CelExpr step,
      CelExpr result) {
    return fold(iterVar, iterRange, accuVar, accuInit.build(), condition.build(), step, result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr iterRange,
      String accuVar,
      CelExpr.Builder accuInit,
      CelExpr condition,
      CelExpr.Builder step,
      CelExpr result) {
    return fold(iterVar, iterRange, accuVar, accuInit.build(), condition, step.build(), result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr iterRange,
      String accuVar,
      CelExpr.Builder accuInit,
      CelExpr condition,
      CelExpr step,
      CelExpr.Builder result) {
    return fold(iterVar, iterRange, accuVar, accuInit.build(), condition, step, result.build());
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr.Builder condition,
      CelExpr.Builder step,
      CelExpr result) {
    return fold(iterVar, iterRange, accuVar, accuInit, condition.build(), step.build(), result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr.Builder condition,
      CelExpr step,
      CelExpr.Builder result) {
    return fold(iterVar, iterRange, accuVar, accuInit, condition.build(), step, result.build());
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr condition,
      CelExpr.Builder step,
      CelExpr.Builder result) {
    return fold(iterVar, iterRange, accuVar, accuInit, condition, step.build(), result.build());
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr.Builder condition,
      CelExpr.Builder step,
      CelExpr result) {
    return fold(
        iterVar, iterRange.build(), accuVar, accuInit, condition.build(), step.build(), result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr.Builder condition,
      CelExpr step,
      CelExpr.Builder result) {
    return fold(
        iterVar, iterRange.build(), accuVar, accuInit, condition.build(), step, result.build());
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr.Builder accuInit,
      CelExpr.Builder condition,
      CelExpr.Builder step,
      CelExpr result) {
    return fold(
        iterVar,
        iterRange.build(),
        accuVar,
        accuInit.build(),
        condition.build(),
        step.build(),
        result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr.Builder accuInit,
      CelExpr condition,
      CelExpr step,
      CelExpr.Builder result) {
    return fold(
        iterVar, iterRange.build(), accuVar, accuInit.build(), condition, step, result.build());
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr.Builder accuInit,
      CelExpr condition,
      CelExpr.Builder step,
      CelExpr result) {
    return fold(
        iterVar, iterRange.build(), accuVar, accuInit.build(), condition, step.build(), result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr.Builder accuInit,
      CelExpr.Builder condition,
      CelExpr step,
      CelExpr result) {
    return fold(
        iterVar, iterRange.build(), accuVar, accuInit.build(), condition.build(), step, result);
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr accuInit,
      CelExpr.Builder condition,
      CelExpr.Builder step,
      CelExpr.Builder result) {
    return fold(
        iterVar,
        iterRange.build(),
        accuVar,
        accuInit,
        condition.build(),
        step.build(),
        result.build());
  }

  /** Fold creates a fold comprehension instruction. */
  public final CelExpr fold(
      String iterVar,
      CelExpr.Builder iterRange,
      String accuVar,
      CelExpr.Builder accuInit,
      CelExpr.Builder condition,
      CelExpr.Builder step,
      CelExpr.Builder result) {
    return fold(
        iterVar,
        iterRange.build(),
        accuVar,
        accuInit.build(),
        condition.build(),
        step.build(),
        result.build());
  }

  /** Creates an identifier {@link CelExpr} for the given name. */
  public final CelExpr newIdentifier(String name) {
    checkArgument(!isNullOrEmpty(name));
    return CelExpr.newBuilder()
        .setId(nextExprId())
        .setIdent(CelExpr.CelIdent.newBuilder().setName(name).build())
        .build();
  }

  /** Creates a global (free) function call {@link CelExpr} for the given function and arguments. */
  public final CelExpr newGlobalCall(String function, CelExpr... arguments) {
    return newGlobalCall(function, Arrays.asList(arguments));
  }

  /** Creates a global (free) function call {@link CelExpr} for the given function and arguments. */
  public final CelExpr newGlobalCall(String function, Iterable arguments) {
    checkArgument(!isNullOrEmpty(function));
    return CelExpr.newBuilder()
        .setId(nextExprId())
        .setCall(CelExpr.CelCall.newBuilder().setFunction(function).addArgs(arguments).build())
        .build();
  }

  /**
   * Creates a receiver-style function call {@link CelExpr} for the given function, target, and
   * arguments.
   */
  public final CelExpr newReceiverCall(String function, CelExpr target, CelExpr... arguments) {
    return newReceiverCall(function, target, Arrays.asList(arguments));
  }

  /**
   * Creates a receiver-style function call {@link CelExpr} for the given function, target, and
   * arguments.
   */
  public final CelExpr newReceiverCall(
      String function, CelExpr target, Iterable arguments) {
    checkArgument(!isNullOrEmpty(function));
    return CelExpr.newBuilder()
        .setId(nextExprId())
        .setCall(
            CelExpr.CelCall.newBuilder()
                .setFunction(function)
                .setTarget(target)
                .addArgs(arguments)
                .build())
        .build();
  }

  /**
   * Creates a field traversal or field presence test {@link CelExpr} for the given operand and
   * field.
   */
  public final CelExpr newSelect(CelExpr operand, String field, boolean testOnly) {
    checkArgument(!isNullOrEmpty(field));
    return CelExpr.newBuilder()
        .setId(nextExprId())
        .setSelect(
            CelExpr.CelSelect.newBuilder()
                .setOperand(operand)
                .setField(field)
                .setTestOnly(testOnly)
                .build())
        .build();
  }

  /** Returns the next unique expression ID. */
  protected long nextExprId() {
    return idGenerator.generate(
        /* exprId= */ -1); // Unconditionally generate next unique ID (i.e: no renumbering).
  }

  protected CelExprFactory() {
    this(CelExprIdGeneratorFactory.newMonotonicIdGenerator(0));
  }

  private CelExprFactory(CelExprIdGeneratorFactory.MonotonicIdGenerator idGenerator) {
    this((unused) -> idGenerator.nextExprId());
  }

  private CelExprFactory(CelExprIdGeneratorFactory.ExprIdGenerator exprIdGenerator) {
    idGenerator = exprIdGenerator;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy