/**
  * 指定のスロットに対するエピローグ用のレデューサーを生成する。
  *
  * @param moduleId モジュール識別子
  * @param slots 対象のスロット一覧
  * @return 生成したクラス
  * @throws IOException 出力に失敗した場合
  * @throws IllegalArgumentException 引数に{@code null}が指定された場合
  */
 public CompiledType emit(String moduleId, List<ResolvedSlot> slots) throws IOException {
   LOG.debug("\"{}\"エピローグ用のレデューサーを生成します", moduleId);
   Engine engine = new Engine(environment, moduleId, slots);
   CompilationUnit source = engine.generate();
   environment.emit(source);
   Name packageName = source.getPackageDeclaration().getName();
   SimpleName simpleName = source.getTypeDeclarations().get(0).getName();
   Name name = environment.getModelFactory().newQualifiedName(packageName, simpleName);
   LOG.debug("エピローグ用レデューサーには{}が利用されます", name);
   return new CompiledType(name);
 }
 /**
  * 指定のモデルに対する値を表すクラスを生成し、生成したクラスの完全限定名を返す。
  *
  * @param model 対象のモデル
  * @return 生成したクラスの完全限定名
  * @throws IOException クラスの生成に失敗した場合
  * @throws IllegalArgumentException 引数に{@code null}が指定された場合
  */
 public Name emit(ShuffleModel model) throws IOException {
   Precondition.checkMustNotBeNull(model, "model"); // $NON-NLS-1$
   LOG.debug("start generating shuffle value class: {}", model.getStageBlock()); // $NON-NLS-1$
   Engine engine = new Engine(environment, model);
   CompilationUnit source = engine.generate();
   environment.emit(source);
   Name packageName = source.getPackageDeclaration().getName();
   SimpleName simpleName = source.getTypeDeclarations().get(0).getName();
   Name name = environment.getModelFactory().newQualifiedName(packageName, simpleName);
   LOG.debug(
       "finish generating shuffle value class: {} ({})",
       model.getStageBlock(),
       name); //$NON-NLS-1$
   return name;
 }
  /**
   * 指定のステージ内のCombinerに対するクラスを生成し、生成したクラスの完全限定名を返す。
   *
   * @param model 対象のステージ
   * @return 生成したクラスの完全限定名、不要の場合は{@code null}
   * @throws IOException クラスの生成に失敗した場合
   * @throws IllegalArgumentException 引数に{@code null}が指定された場合
   */
  public CompiledType emit(StageModel model) throws IOException {
    Precondition.checkMustNotBeNull(model, "model"); // $NON-NLS-1$
    if (canCombine(model) == false) {
      LOG.debug("{}に対してコンバイナークラスは不要です", model);
      return null;
    }
    LOG.debug("{}に対するコンバイナークラスを生成します", model);
    Engine engine = new Engine(environment, model);
    CompilationUnit source = engine.generate();
    environment.emit(source);
    Name packageName = source.getPackageDeclaration().getName();
    SimpleName simpleName = source.getTypeDeclarations().get(0).getName();

    QualifiedName name = environment.getModelFactory().newQualifiedName(packageName, simpleName);

    LOG.debug("{}のコンバイン処理には{}が利用されます", model, name);
    return new CompiledType(name);
  }