code: package io.ray.runtime.util.generator;
  
  import java.io.File;
  import java.io.IOException;
  import java.nio.charset.Charset;
  import org.apache.commons.io.FileUtils;
  
  /** A util class that generates all the RayFuncX classes under io.ray.api.function package. */
  public class RayFuncGenerator extends BaseGenerator {
  
    private String generate(int numParameters, boolean hasReturn) {
      sb = new StringBuilder();
  
      String genericTypes = "";
      String paramList = "";
      for (int i = 0; i < numParameters; i++) {
        genericTypes += "T" + i + ", ";
        if (i > 0) {
          paramList += ", ";
        }
        paramList += String.format("T%d t%d", i, i);
      }
      if (hasReturn) {
        genericTypes += "R, ";
      }
      if (!genericTypes.isEmpty()) {
        // Remove trailing ", ".
        genericTypes = genericTypes.substring(0, genericTypes.length() - 2);
        genericTypes = "<" + genericTypes + ">";
      }
  
      newLine("// generated automatically, do not modify.");
      newLine("");
      newLine("package io.ray.api.function;");
      newLine("");
      newLine("/**");
      String comment =
          String.format(
              " * Functional interface for a remote function that has %d parameter%s.",
              numParameters, numParameters > 1 ? "s" : "");
      newLine(comment);
      newLine(" */");
      newLine("@FunctionalInterface");
      String className = "RayFunc" + (hasReturn ? "" : "Void") + numParameters;
      newLine(
          String.format(
              "public interface %s%s extends %s {",
              className, genericTypes, hasReturn ? "RayFuncR<R>" : "RayFuncVoid"));
      newLine("");
      indents(1);
      newLine(String.format("%s apply(%s) throws Exception;", hasReturn ? "R" : "void", paramList));
      newLine("}");
  
      return sb.toString();
    }
  
    public static void main(String[] args) throws IOException {
      String root = System.getProperty("user.dir") + "/api/src/main/java/io/ray/api/function/";
      RayFuncGenerator generator = new RayFuncGenerator();
      for (int i = 0; i <= MAX_PARAMETERS; i++) {
        // Functions that have return.
        String content = generator.generate(i, true);
        FileUtils.write(new File(root + "RayFunc" + i + ".java"), content, Charset.defaultCharset());
        // Functions that don't have return.
        content = generator.generate(i, false);
        FileUtils.write(
            new File(root + "RayFuncVoid" + i + ".java"), content, Charset.defaultCharset());
      }
    }
  }
  