<commit_before>package net.zerobuilder.compiler.generate;

import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.TypeSpec;
import net.zerobuilder.compiler.generate.DtoContext.BuildersContext;
import net.zerobuilder.compiler.generate.DtoGeneratorOutput.BuilderMethod;
import net.zerobuilder.compiler.generate.DtoGeneratorOutput.GeneratorOutput;
import net.zerobuilder.compiler.generate.DtoGoalContext.AbstractGoalContext;
import net.zerobuilder.compiler.generate.DtoModule.Module;
import net.zerobuilder.compiler.generate.DtoModuleOutput.AbstractModuleOutput;
import net.zerobuilder.compiler.generate.GeneratorInput.AbstractGoalInput;
import net.zerobuilder.compiler.generate.GeneratorInput.DescriptionInput;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collector;

import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static net.zerobuilder.compiler.generate.DtoContext.BuilderLifecycle.REUSE_INSTANCES;
import static net.zerobuilder.compiler.generate.DtoModule.goalInputCases;
import static net.zerobuilder.compiler.generate.DtoModuleOutput.moduleOutputCases;
import static net.zerobuilder.compiler.generate.GoalContextFactory.prepare;
import static net.zerobuilder.compiler.generate.Utilities.listCollector;

public final class Generator {

  /**
   * Entry point for code generation.
   *
   * @param generatorInput Goal descriptions
   * @return a GeneratorOutput
   */
  public static GeneratorOutput generate(GeneratorInput generatorInput) {
    List<DescriptionInput> goals = generatorInput.goals;
    BuildersContext context = generatorInput.context;
    return goals.stream()
        .map(prepare(context))
        .map(process)
        .collect(collectOutput(context));
  }

  private static Collector<TmpOutput, List<TmpOutput>, GeneratorOutput> collectOutput(BuildersContext context) {
    return listCollector(tmpOutputs -> {
      List<BuilderMethod> methods = new ArrayList<>(tmpOutputs.size());
      List<TypeSpec> types = new ArrayList<>();
      List<FieldSpec> fields = new ArrayList<>();
      if (context.lifecycle == REUSE_INSTANCES) {
        fields.add(context.cache.get());
      }
      for (TmpOutput tmp : tmpOutputs) {
        methods.add(tmp.output.method);
        if (tmp.goal.context().lifecycle == REUSE_INSTANCES) {
          fields.add(tmp.module.cacheField(tmp.goal));
        }
        types.addAll(nestedTypes.apply(tmp.output));
      }
      return new GeneratorOutput(methods, types, fields,
          context.generatedType, context.lifecycle);
    });
  }

  private static final Function<AbstractGoalInput, TmpOutput> process =
      goalInputCases(
          (simple, goal) -> new TmpOutput(simple, goal, simple.process(goal)),
          (contract, goal) -> new TmpOutput(contract, goal, contract.process(goal)));

  private static final Function<AbstractModuleOutput, List<TypeSpec>> nestedTypes =
      moduleOutputCases(
          simple -> singletonList(simple.impl),
          contract -> asList(contract.impl, contract.contract));<commit_msg>refactoring<commit_after>package net.zerobuilder.compiler.generate;

import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.TypeSpec;
import net.zerobuilder.compiler.generate.DtoContext.BuildersContext;
import net.zerobuilder.compiler.generate.DtoGeneratorOutput.BuilderMethod;
import net.zerobuilder.compiler.generate.DtoGeneratorOutput.GeneratorOutput;
import net.zerobuilder.compiler.generate.DtoGoalContext.AbstractGoalContext;
import net.zerobuilder.compiler.generate.DtoModule.Module;
import net.zerobuilder.compiler.generate.DtoModuleOutput.AbstractModuleOutput;
import net.zerobuilder.compiler.generate.GeneratorInput.AbstractGoalInput;
import net.zerobuilder.compiler.generate.GeneratorInput.DescriptionInput;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collector;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static net.zerobuilder.compiler.generate.DtoContext.BuilderLifecycle.NEW_INSTANCE;
import static net.zerobuilder.compiler.generate.DtoModule.goalInputCases;
import static net.zerobuilder.compiler.generate.DtoModuleOutput.moduleOutputCases;
import static net.zerobuilder.compiler.generate.GoalContextFactory.prepare;
import static net.zerobuilder.compiler.generate.Utilities.flatList;
import static net.zerobuilder.compiler.generate.Utilities.listCollector;
import static net.zerobuilder.compiler.generate.Utilities.transform;

public final class Generator {

  /**
   * Entry point for code generation.
   *
   * @param generatorInput Goal descriptions
   * @return a GeneratorOutput
   */
  public static GeneratorOutput generate(GeneratorInput generatorInput) {
    List<DescriptionInput> goals = generatorInput.goals;
    BuildersContext context = generatorInput.context;
    return goals.stream()
        .map(prepare(context))
        .map(process)
        .collect(collectOutput(context));
  }

  private static Collector<TmpOutput, List<TmpOutput>, GeneratorOutput> collectOutput(BuildersContext context) {
    return listCollector(tmpOutputs ->
        new GeneratorOutput(
            methods(tmpOutputs),
            types(tmpOutputs),
            fields(context, tmpOutputs),
            context.generatedType,
            context.lifecycle));
  }

  private static List<BuilderMethod> methods(List<TmpOutput> tmpOutputs) {
    return transform(tmpOutputs, tmp -> tmp.output.method);
  }

  private static List<TypeSpec> types(List<TmpOutput> tmpOutputs) {
    return tmpOutputs.stream()
        .map(tmp -> nestedTypes.apply(tmp.output))
        .collect(flatList());
  }

  private static List<FieldSpec> fields(BuildersContext context, List<TmpOutput> tmpOutputs) {
    if (context.lifecycle == NEW_INSTANCE) {
      return emptyList();
    }
    List<FieldSpec> fields = new ArrayList<>(tmpOutputs.size() + 1);
    fields.add(context.cache.get());
    for (TmpOutput tmp : tmpOutputs) {
      fields.add(tmp.module.cacheField(tmp.goal));
    }
    return fields;
  }

  private static final Function<AbstractGoalInput, TmpOutput> process =
      goalInputCases(
          (simple, goal) -> new TmpOutput(simple, goal, simple.process(goal)),
          (contract, goal) -> new TmpOutput(contract, goal, contract.process(goal)));

  private static final Function<AbstractModuleOutput, List<TypeSpec>> nestedTypes =
      moduleOutputCases(
          simple -> singletonList(simple.impl),
          contract -> asList(contract.impl, contract.contract));
{'fraction_non_alphanumeric': 0.1006731488406881, 'fraction_numerical': 0.00014958863126402394, 'mean_word_length': 4.576313594662219, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7391753', 'n_tokens_mistral': 1869, 'n_tokens_neox': 1896, 'n_words': 339}