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();
}