public FunctionCall transpileFunctionCall()

in transpiler/src/main/java/com/google/cloud/verticals/foundations/dataharmonization/Signature.java [95:172]


  public FunctionCall transpileFunctionCall(
      Transpiler transpiler,
      FunctionReference ref,
      List<ExpressionContext> givenArgs,
      ParserRuleContext sourceContext) {
    FunctionCall.Builder call = FunctionCall.newBuilder();
    call.setReference(ref);
    for (int i = 0; i < givenArgs.size(); i++) {

      // skip null arguments; selectors without accompanying expressions or
      // variable defaults to having null as argument.
      if (givenArgs.get(i) == null) {
        continue;
      }
      if (i >= args.length && !isVariadic) {
        // TODO(rpolyano): Use sourceContext.addErrorNode() ?
        throw new IllegalArgumentException(
            String.format(
                "Too many parameters for %s::%s: want %d, got %d: %s",
                ref.getPackage(),
                ref.getName(),
                args.length,
                givenArgs.size(),
                givenArgs.stream()
                    .map(ExpressionContext::getText)
                    .collect(Collectors.joining(", "))));
      }

      // The type of argument we want:
      Argument argType = args.length > 0 ? args[Math.min(i, args.length - 1)] : Argument.value();

      ValueSource argVs;
      // Depending on the type of arg we want, we transpile the expression in different ways:
      if (argType.isClosure()) {
        // If we want a closure, we transpile to a lambda closure.

        // If the closure is variadic then we want one free param for each remaining
        // expression/argument.
        Signature closureSig = argType.getClosureSignature();
        if (closureSig.isVariadic) {
          int numArgs = givenArgs.size() - i - 1;
          closureSig =
              Signature.of(
                  IntStream.range(1, numArgs + 1)
                      .mapToObj(j -> Argument.free(numArgs == 1 ? "$" : String.format("$%d", j)))
                      .toArray(Argument[]::new));
        }

        argVs =
            ValueSource.newBuilder()
                .setFunctionCall(
                    LambdaHelper.lambda(
                        transpiler,
                        closureSig,
                        givenArgs.get(i),
                        argType.lambdaPrefix,
                        argType.lambdaType))
                .build();
      } else if (argType.isFreeParam()) {
        // If we want a free param, we ignore the expression value (the caller will need to deal
        // with separately).
        argVs = ValueSource.newBuilder().setFreeParameter(argType.getFreeParamName()).build();
      } else {
        // Otherwise we just want a regular value so we transpile it directly.
        argVs = (ValueSource) givenArgs.get(i).accept(transpiler);
      }
      call.addArgs(argVs);
    }

    Meta.Builder meta = Meta.newBuilder();
    meta.putEntries(SOURCE_META_KEY, Any.pack(buildSource(sourceContext)));
    if (sourceContext instanceof FunctionCallContext) {
      meta = SymbolHelper.withSymbol(meta, (FunctionCallContext) sourceContext);
    }

    call.setMeta(meta);
    return call.build();
  }