// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;

import static com.android.tools.r8.BaseCompilerCommandUtils.createProgramOutputConsumer;

import com.android.tools.r8.dump.DumpOptions;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.UnsupportedAndroidApiLevelDiagnostic;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.inspector.Inspector;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecificationParser;
import com.android.tools.r8.keepanno.annotations.KeepForApi;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.profile.art.ArtProfileConsumer;
import com.android.tools.r8.profile.art.ArtProfileForRewriting;
import com.android.tools.r8.profile.art.ArtProfileProvider;
import com.android.tools.r8.startup.StartupProfileProvider;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DumpInputFlags;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions.DesugarState;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.MapConsumerUtils;
import com.android.tools.r8.utils.PartitionMapZipContainer;
import com.android.tools.r8.utils.ProgramConsumerUtils;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.ThreadUtils;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * Base class for commands and command builders for compiler applications/tools which besides an
 * Android application (and optional main-dex list) also configure compilation output, compilation
 * mode and min API level.
 *
 * <p>For concrete builders, see for example {@link D8Command.Builder} and {@link
 * R8Command.Builder}.
 */
@KeepForApi
public abstract class BaseCompilerCommand extends BaseCommand {

  private final CompilationMode mode;
  private final ProgramConsumer programConsumer;
  private final StringConsumer mainDexListConsumer;
  private final int minApiLevel;
  private final Reporter reporter;
  private final DesugarState desugarState;
  private final boolean includeClassesChecksum;
  private final boolean optimizeMultidexForLinearAlloc;
  private final BiPredicate<String, Long> dexClassChecksumFilter;
  private final List<AssertionsConfiguration> assertionsConfiguration;
  private final List<Consumer<Inspector>> outputInspections;
  private final int threadCount;
  private final DumpInputFlags dumpInputFlags;
  private final MapIdProvider mapIdProvider;
  private final SourceFileProvider sourceFileProvider;
  private final boolean isAndroidPlatformBuild;
  private final List<ArtProfileForRewriting> artProfilesForRewriting;
  private final List<StartupProfileProvider> startupProfileProviders;
  private final ClassConflictResolver classConflictResolver;
  private final CancelCompilationChecker cancelCompilationChecker;
  final boolean enableVerboseSyntheticNames;

  BaseCompilerCommand(boolean printHelp, boolean printVersion) {
    super(printHelp, printVersion);
    programConsumer = null;
    mainDexListConsumer = null;
    mode = null;
    minApiLevel = 0;
    reporter = new Reporter();
    desugarState = DesugarState.ON;
    includeClassesChecksum = false;
    optimizeMultidexForLinearAlloc = false;
    dexClassChecksumFilter = (name, checksum) -> true;
    assertionsConfiguration = new ArrayList<>();
    outputInspections = null;
    threadCount = ThreadUtils.NOT_SPECIFIED;
    dumpInputFlags = DumpInputFlags.noDump();
    mapIdProvider = null;
    sourceFileProvider = null;
    isAndroidPlatformBuild = false;
    artProfilesForRewriting = null;
    startupProfileProviders = null;
    classConflictResolver = null;
    cancelCompilationChecker = null;
    enableVerboseSyntheticNames = false;
  }

  BaseCompilerCommand(
      AndroidApp app,
      CompilationMode mode,
      ProgramConsumer programConsumer,
      StringConsumer mainDexListConsumer,
      int minApiLevel,
      Reporter reporter,
      DesugarState desugarState,
      boolean optimizeMultidexForLinearAlloc,
      boolean includeClassesChecksum,
      BiPredicate<String, Long> dexClassChecksumFilter,
      List<AssertionsConfiguration> assertionsConfiguration,
      List<Consumer<Inspector>> outputInspections,
      int threadCount,
      DumpInputFlags dumpInputFlags,
      MapIdProvider mapIdProvider,
      SourceFileProvider sourceFileProvider,
      boolean isAndroidPlatformBuild,
      List<ArtProfileForRewriting> artProfilesForRewriting,
      List<StartupProfileProvider> startupProfileProviders,
      ClassConflictResolver classConflictResolver,
      CancelCompilationChecker cancelCompilationChecker,
      boolean enableVerboseSyntheticNames) {
    super(app);
    assert minApiLevel > 0;
    assert mode != null;
    this.mode = mode;
    this.programConsumer = programConsumer;
    this.mainDexListConsumer = mainDexListConsumer;
    this.minApiLevel = minApiLevel;
    this.reporter = reporter;
    this.desugarState = desugarState;
    this.optimizeMultidexForLinearAlloc = optimizeMultidexForLinearAlloc;
    this.includeClassesChecksum = includeClassesChecksum;
    this.dexClassChecksumFilter = dexClassChecksumFilter;
    this.assertionsConfiguration = assertionsConfiguration;
    this.outputInspections = outputInspections;
    this.threadCount = threadCount;
    this.dumpInputFlags = dumpInputFlags;
    this.mapIdProvider = mapIdProvider;
    this.sourceFileProvider = sourceFileProvider;
    this.isAndroidPlatformBuild = isAndroidPlatformBuild;
    this.artProfilesForRewriting = artProfilesForRewriting;
    this.startupProfileProviders = startupProfileProviders;
    this.classConflictResolver = classConflictResolver;
    this.cancelCompilationChecker = cancelCompilationChecker;
    this.enableVerboseSyntheticNames = enableVerboseSyntheticNames;
  }

  /**
   * Get the compilation mode, e.g., {@link CompilationMode#DEBUG} or {@link
   * CompilationMode#RELEASE}.
   */
  public CompilationMode getMode() {
    return mode;
  }

  /** Get the minimum API level to compile against. */
  public int getMinApiLevel() {
    return minApiLevel;
  }

  void dumpBaseCommandOptions(DumpOptions.Builder builder) {
    builder
        .setBackend(ProgramConsumerUtils.getBackend(programConsumer))
        .setCompilationMode(getMode())
        .setMinApi(getMinApiLevel())
        .setOptimizeMultidexForLinearAlloc(isOptimizeMultidexForLinearAlloc())
        .setThreadCount(getThreadCount())
        .setDesugarState(getDesugarState())
        .setArtProfileProviders(
            ListUtils.map(
                getArtProfilesForRewriting(), ArtProfileForRewriting::getArtProfileProvider))
        .setStartupProfileProviders(getStartupProfileProviders());
    if (getAndroidPlatformBuild()) {
      builder.setAndroidPlatformBuild(true);
    }
  }

  /**
   * Get the program consumer that will receive the compilation output.
   *
   * <p>Note that the concrete consumer reference is final, the consumer itself is likely stateful.
   */
  public ProgramConsumer getProgramConsumer() {
    return programConsumer;
  }

  /**
   * Get the main dex list consumer that will receive the final complete main dex list.
   */
  public StringConsumer getMainDexListConsumer() {
    return mainDexListConsumer;
  }

  /** Get the use-desugaring state. True if enabled, false otherwise. */
  public boolean getEnableDesugaring() {
    return desugarState == DesugarState.ON;
  }

  DesugarState getDesugarState() {
    return desugarState;
  }

  public MapIdProvider getMapIdProvider() {
    return mapIdProvider;
  }

  public SourceFileProvider getSourceFileProvider() {
    return sourceFileProvider;
  }

  /** True if the output dex files has checksum information encoded in it. False otherwise. */
  public boolean getIncludeClassesChecksum() {
    return includeClassesChecksum;
  }

  /** Filter used to skip parsing of certain class in a dex file. */
  public BiPredicate<String, Long> getDexClassChecksumFilter() {
    return dexClassChecksumFilter;
  }

  /**
   * If true, legacy multidex partitioning will be optimized to reduce LinearAlloc usage during
   * Dalvik DexOpt.
   */
  public boolean isOptimizeMultidexForLinearAlloc() {
    return optimizeMultidexForLinearAlloc;
  }

  public List<AssertionsConfiguration> getAssertionsConfiguration() {
    return Collections.unmodifiableList(assertionsConfiguration);
  }

  public Collection<Consumer<Inspector>> getOutputInspections() {
    return Collections.unmodifiableList(outputInspections);
  }

  /** Get the number of threads to use for the compilation. */
  public int getThreadCount() {
    return threadCount;
  }

  public boolean getAndroidPlatformBuild() {
    return isAndroidPlatformBuild;
  }

  List<ArtProfileForRewriting> getArtProfilesForRewriting() {
    return artProfilesForRewriting;
  }

  List<StartupProfileProvider> getStartupProfileProviders() {
    return startupProfileProviders;
  }

  ClassConflictResolver getClassConflictResolver() {
    return classConflictResolver;
  }

  public CancelCompilationChecker getCancelCompilationChecker() {
    return cancelCompilationChecker;
  }

  DumpInputFlags getDumpInputFlags() {
    return dumpInputFlags;
  }

  Reporter getReporter() {
    return reporter;
  }

  /**
   * Base builder for compilation commands.
   *
   * @param <C> Command the builder is building, e.g., {@link R8Command} or {@link D8Command}.
   * @param <B> Concrete builder extending this base, e.g., {@link R8Command.Builder} or {@link
   *     D8Command.Builder}.
   */
  @KeepForApi
  public abstract static class Builder<C extends BaseCompilerCommand, B extends Builder<C, B>>
      extends BaseCommand.Builder<C, B> {

    private ProgramConsumer programConsumer = null;
    private StringConsumer mainDexListConsumer = null;
    private Path outputPath = null;
    // TODO(b/70656566): Remove default output mode when deprecated API is removed.
    private OutputMode outputMode = OutputMode.DexIndexed;

    private CompilationMode mode;
    private int minMajorApiLevel = 0;

    @SuppressWarnings("UnusedVariable")
    private int minMinorApiLevel = 0;

    private int threadCount = ThreadUtils.NOT_SPECIFIED;
    protected DesugarState desugarState = DesugarState.ON;
    boolean enableVerboseSyntheticNames = false;
    private final List<StringResource> desugaredLibrarySpecificationResources = new ArrayList<>();
    private boolean includeClassesChecksum = false;
    private boolean optimizeMultidexForLinearAlloc = false;
    private BiPredicate<String, Long> dexClassChecksumFilter = (name, checksum) -> true;
    private final List<AssertionsConfiguration> assertionsConfiguration = new ArrayList<>();
    private final List<Consumer<Inspector>> outputInspections = new ArrayList<>();
    protected MapConsumer proguardMapConsumer = null;
    protected PartitionMapConsumer partitionMapConsumer = null;
    private DumpInputFlags dumpInputFlags = DumpInputFlags.getDefault();
    private MapIdProvider mapIdProvider = null;
    private SourceFileProvider sourceFileProvider;
    private boolean isAndroidPlatformBuild = false;
    private final List<ArtProfileForRewriting> artProfilesForRewriting = new ArrayList<>();
    private final List<StartupProfileProvider> startupProfileProviders = new ArrayList<>();
    private ClassConflictResolver classConflictResolver = null;
    private CancelCompilationChecker cancelCompilationChecker = null;

    abstract CompilationMode defaultCompilationMode();

    Builder(DiagnosticsHandler diagnosticsHandler) {
      super(diagnosticsHandler);
      mode = defaultCompilationMode();
    }

    // Internal constructor for testing.
    Builder(AndroidApp app) {
      super(AndroidApp.builder(app));
      mode = defaultCompilationMode();
    }

    // Internal constructor for testing.
    Builder(AndroidApp app, DiagnosticsHandler diagnosticsHandler) {
      super(AndroidApp.builder(app, new Reporter(diagnosticsHandler)));
      mode = defaultCompilationMode();
    }

    /**
     * Get current compilation mode.
     */
    public CompilationMode getMode() {
      return mode;
    }

    /**
     * Set compilation mode.
     */
    public B setMode(CompilationMode mode) {
      assert mode != null;
      this.mode = mode;
      return self();
    }

    /**
     * Get the output path.
     *
     * @return Current output path, null if no output path-and-mode have been set.
     * @see #setOutput(Path, OutputMode)
     */
    public Path getOutputPath() {
      return outputPath;
    }

    /**
     * Get the output mode.
     *
     * @return Currently set output mode, null if no output path-and-mode have been set.
     * @see #setOutput(Path, OutputMode)
     */
    public OutputMode getOutputMode() {
      return outputMode;
    }

    /**
     * Get the program consumer.
     *
     * @return The currently set program consumer, null if no program consumer or output
     *     path-and-mode is set, e.g., neither {@link #setProgramConsumer} nor {@link #setOutput}
     *     have been called.
     */
    public ProgramConsumer getProgramConsumer() {
      return programConsumer;
    }

    /**
     * Set an output destination to which proguard-map content should be written.
     *
     * <p>This is a short-hand for setting a {@link MapConsumer.FileConsumer} using {@link
     * #setProguardMapConsumer}. Note that any subsequent call to this method or {@link
     * #setProguardMapConsumer} will override the previous setting.
     *
     * @param proguardMapOutput File-system path to write output at.
     */
    B setProguardMapOutputPath(Path proguardMapOutput) {
      assert proguardMapOutput != null;
      return setProguardMapConsumer(new MapConsumer.FileConsumer(proguardMapOutput));
    }

    /**
     * Set a consumer for receiving the proguard-map content.
     *
     * <p>It is possible to also retrieve the map id by passing an instance of {@link
     * com.android.tools.r8.MapConsumer}.
     *
     * <p>Note that any subsequent call to this method or {@link #setProguardMapOutputPath} will
     * override the previous setting.
     *
     * @param proguardMapConsumer Consumer to receive the content once produced.
     */
    B setProguardMapConsumer(StringConsumer proguardMapConsumer) {
      this.proguardMapConsumer = MapConsumerUtils.createFromStringConsumer(proguardMapConsumer);
      return self();
    }

    /** Get the consumer for receiving the proguard-map content or null if unset. */
    public StringConsumer getProguardMapConsumer() {
      return proguardMapConsumer;
    }

    /**
     * Set an output destination to which partition-map content should be written.
     *
     * <p>This is a short-hand for setting a {@link PartitionMapConsumer} using {@link
     * #setPartitionMapConsumer}. Note that any subsequent call to this method or {@link
     * #setPartitionMapConsumer} will override the previous setting.
     *
     * @param partitionMapOutput File-system path to write output at.
     */
    public B setPartitionMapOutputPath(Path partitionMapOutput) {
      assert partitionMapOutput != null;
      return setPartitionMapConsumer(
          PartitionMapZipContainer.createPartitionMapZipContainerConsumer(partitionMapOutput));
    }

    /**
     * Set a consumer for receiving the partition map content.
     *
     * <p>Note that any subsequent call to this method or {@link #setPartitionMapOutputPath} will
     * override the previous setting.
     *
     * @param partitionMapConsumer Consumer to receive the content once produced.
     */
    public B setPartitionMapConsumer(PartitionMapConsumer partitionMapConsumer) {
      this.partitionMapConsumer = partitionMapConsumer;
      return self();
    }

    /**
     * Get the main dex list consumer that will receive the final complete main dex list.
     */
    public StringConsumer getMainDexListConsumer() {
      return mainDexListConsumer;
    }

    /**
     * Filter used to skip parsing of certain class in a dex file.
     */
    public BiPredicate<String, Long> getDexClassChecksumFilter() {
      return dexClassChecksumFilter;
    }

    /**
     * If set to true, legacy multidex partitioning will be optimized to reduce LinearAlloc usage
     * during Dalvik DexOpt. Has no effect when compiling for a target with native multidex support
     * or without main dex list specification.
     */
    public B setOptimizeMultidexForLinearAlloc(boolean optimizeMultidexForLinearAlloc) {
      this.optimizeMultidexForLinearAlloc = optimizeMultidexForLinearAlloc;
      return self();
    }

    /**
     * If true, legacy multidex partitioning will be optimized to reduce LinearAlloc usage during
     * Dalvik DexOpt.
     */
    protected boolean isOptimizeMultidexForLinearAlloc() {
      return optimizeMultidexForLinearAlloc;
    }

    /**
     * Set the program consumer.
     *
     * <p>Setting the program consumer will override any previous set consumer or any previous set
     * output path & mode.
     *
     * @param programConsumer Program consumer to set as current. A null argument will clear the
     *     program consumer / output.
     */
    public B setProgramConsumer(ProgramConsumer programConsumer) {
      // Setting an explicit program consumer resets any output-path/mode setup.
      outputPath = null;
      outputMode = null;
      this.programConsumer = programConsumer;
      return self();
    }

    /**
     * Set an output destination to which main-dex-list content should be written.
     *
     * <p>This is a short-hand for setting a {@link StringConsumer.FileConsumer} using {@link
     * #setMainDexListConsumer}. Note that any subsequent call to this method or {@link
     * #setMainDexListConsumer} will override the previous setting.
     *
     * @param mainDexListOutputPath File-system path to write output at.
     */
    public B setMainDexListOutputPath(Path mainDexListOutputPath) {
      mainDexListConsumer = new StringConsumer.FileConsumer(mainDexListOutputPath);
      return self();
    }

    /**
     * Set a consumer for receiving the main-dex-list content.
     *
     * <p>Note that any subsequent call to this method or {@link #setMainDexListOutputPath} will
     * override the previous setting.
     *
     * @param mainDexListConsumer Consumer to receive the content once produced.
     */
    public B setMainDexListConsumer(StringConsumer mainDexListConsumer) {
      this.mainDexListConsumer = mainDexListConsumer;
      return self();
    }

    /**
     * Set the output path-and-mode.
     *
     * <p>Setting the output path-and-mode will override any previous set consumer or any previous
     * output path-and-mode, and implicitly sets the appropriate program consumer to write the
     * output.
     *
     * @param outputPath Path to write the output to. Must be an archive or and existing directory.
     * @param outputMode Mode in which to write the output.
     */
    public B setOutput(Path outputPath, OutputMode outputMode) {
      return setOutput(outputPath, outputMode, false);
    }

    // This is only public in R8Command.
    protected B setOutput(Path outputPath, OutputMode outputMode, boolean includeDataResources) {
      assert outputPath != null;
      assert outputMode != null;
      this.outputPath = outputPath;
      this.outputMode = outputMode;
      programConsumer = createProgramOutputConsumer(outputPath, outputMode, includeDataResources);
      return self();
    }

    /**
     * Setting a dex class filter.
     *
     * A filter is a function that given a name of a class and a checksum can return false the user
     * decides to skip parsing and ignore that class in the dex file.
     */
    public B setDexClassChecksumFilter(BiPredicate<String, Long> filter) {
      assert filter != null;
      this.dexClassChecksumFilter = filter;
      return self();
    }

    /** Get the minimum API level (aka SDK version). */
    public int getMinApiLevel() {
      return isMinApiLevelSet() ? minMajorApiLevel : AndroidApiLevel.getDefault().getLevel();
    }

    boolean isMinApiLevelSet() {
      return minMajorApiLevel != 0;
    }

    /** Set the minimum required API level (aka SDK version). */
    public B setMinApiLevel(int minMajorApiLevel) {
      if (minMajorApiLevel <= 0) {
        getReporter().error("Invalid minApiLevel: " + minMajorApiLevel);
        return self();
      }
      return setMinApiLevel(minMajorApiLevel, 0);
    }

    /** Set the minimum required API level (aka SDK version). */
    public B setMinApiLevel(int minMajorApiLevel, int minMinorApiLevel) {
      if (minMajorApiLevel <= 0 || minMinorApiLevel < 0) {
        getReporter().error("Invalid minApiLevel: " + minMajorApiLevel + "." + minMinorApiLevel);
      } else {
        this.minMajorApiLevel = minMajorApiLevel;
        this.minMinorApiLevel = minMinorApiLevel;
      }
      return self();
    }

    @Deprecated
    public B setEnableDesugaring(boolean enableDesugaring) {
      this.desugarState = enableDesugaring ? DesugarState.ON : DesugarState.OFF;
      return self();
    }

    /**
     * Force disable desugaring.
     *
     * <p>There are a few use cases where it makes sense to force disable desugaring, such as:
     * <ul>
     * <li>if all inputs are known to be at most Java 7; or
     * <li>if a separate desugar tool has been used prior to compiling with D8.
     * </ul>
     *
     * <p>Note that even for API 27, desugaring is still required for closures support on ART.
     */
    public B setDisableDesugaring(boolean disableDesugaring) {
      this.desugarState = disableDesugaring ? DesugarState.OFF : DesugarState.ON;
      return self();
    }

    /** Is desugaring forcefully disabled. */
    public boolean getDisableDesugaring() {
      return desugarState == DesugarState.OFF;
    }

    DesugarState getDesugaringState() {
      return desugarState;
    }

    /**
     * By default, the compiler uses the same naming scheme for synthetic classes as javac uses for
     * anonymous inner classes. By enabling verbose synthetic names, the synthetic classes will
     * include a "$$ExternalSynthetic" marker, which includes the synthetic kind (e.g., "Lambda").
     */
    B setEnableVerboseSyntheticNames(boolean enableVerboseSyntheticNames) {
      this.enableVerboseSyntheticNames = enableVerboseSyntheticNames;
      return self();
    }

    /** Set a custom provider for defining the map id for the build. */
    public B setMapIdProvider(MapIdProvider mapIdProvider) {
      this.mapIdProvider = mapIdProvider;
      return self();
    }

    public MapIdProvider getMapIdProvider() {
      return mapIdProvider;
    }

    /** Set a custom provider for defining source-file attributes for classes. */
    public B setSourceFileProvider(SourceFileProvider sourceFileProvider) {
      this.sourceFileProvider = sourceFileProvider;
      return self();
    }

    public SourceFileProvider getSourceFileProvider() {
      return sourceFileProvider;
    }

    @Deprecated
    @SuppressWarnings("InlineMeSuggester")
    public B addSpecialLibraryConfiguration(String configuration) {
      return addDesugaredLibraryConfiguration(configuration);
    }

    /** Desugared library configuration */
    // Configuration "default" is for testing only and support will be dropped.
    public B addDesugaredLibraryConfiguration(String configuration) {
      this.desugaredLibrarySpecificationResources.add(
          StringResource.fromString(configuration, Origin.unknown()));
      return self();
    }

    /** Desugared library configuration */
    public B addDesugaredLibraryConfiguration(StringResource configuration) {
      this.desugaredLibrarySpecificationResources.add(configuration);
      return self();
    }

    DesugaredLibrarySpecification getDesugaredLibraryConfiguration(
        DexItemFactory factory, boolean libraryCompilation) {
      if (desugaredLibrarySpecificationResources.isEmpty()) {
        return DesugaredLibrarySpecification.empty();
      }
      if (desugaredLibrarySpecificationResources.size() > 1) {
        throw new CompilationError("Only one desugared library configuration is supported.");
      }
      StringResource desugaredLibrarySpecificationResource =
          desugaredLibrarySpecificationResources.get(0);
      return DesugaredLibrarySpecificationParser.parseDesugaredLibrarySpecification(
          desugaredLibrarySpecificationResource,
          factory,
          getReporter(),
          libraryCompilation,
          getMinApiLevel());
    }

    boolean hasDesugaredLibraryConfiguration() {
      return !desugaredLibrarySpecificationResources.isEmpty();
    }

    /** Encodes checksum for each class when generating dex files. */
    public B setIncludeClassesChecksum(boolean enabled) {
      this.includeClassesChecksum = enabled;
      return self();
    }

    /** Set the number of threads to use for the compilation */
    B setThreadCount(int threadCount) {
      if (threadCount <= 0) {
        getReporter().error("Invalid threadCount: " + threadCount);
      } else {
        this.threadCount = threadCount;
      }
      return self();
    }

    int getThreadCount() {
      return threadCount;
    }

    /** Encodes the checksums into the dex output. */
    public boolean getIncludeClassesChecksum() {
      return includeClassesChecksum;
    }

    List<AssertionsConfiguration> getAssertionsConfiguration() {
      return assertionsConfiguration;
    }

    /** Configure compile time assertion enabling through a {@link AssertionsConfiguration}. */
    public B addAssertionsConfiguration(
        Function<AssertionsConfiguration.Builder, AssertionsConfiguration>
            assertionsConfigurationGenerator) {
      assertionsConfiguration.add(
          assertionsConfigurationGenerator.apply(AssertionsConfiguration.builder(getReporter())));
      return self();
    }

    /**
     * Configure the present build as a "Android platform build".
     *
     * <p>A platform build, is a build where the runtime "bootclasspath" is known at compile time.
     * In other words, the specified <i>min-api</i> is also known to be the <i>max-api</i>. In this
     * mode the compiler will disable various features that provide support for newer runtimes as
     * well as disable workarounds for older runtimes.
     */
    public B setAndroidPlatformBuild(boolean isAndroidPlatformBuild) {
      this.isAndroidPlatformBuild = isAndroidPlatformBuild;
      return self();
    }

    public boolean getAndroidPlatformBuild() {
      return isAndroidPlatformBuild;
    }

    /**
     * Add an ART profiles that should be rewritten to match the residual application. The ART
     * profile is given to the compiler by the {@link ArtProfileProvider} and passed back to the
     * {@link ArtProfileConsumer} at the end of compilation when the ART profile has been fully
     * rewritten to match the residual application.
     */
    public B addArtProfileForRewriting(
        ArtProfileProvider artProfileProvider, ArtProfileConsumer residualArtProfileConsumer) {
      return addArtProfileForRewriting(
          new ArtProfileForRewriting(artProfileProvider, residualArtProfileConsumer));
    }

    B addArtProfileForRewriting(ArtProfileForRewriting artProfileForRewriting) {
      artProfilesForRewriting.add(artProfileForRewriting);
      return self();
    }

    List<ArtProfileForRewriting> getArtProfilesForRewriting() {
      return artProfilesForRewriting;
    }

    B addStartupProfileProviders(StartupProfileProvider... startupProfileProviders) {
      return addStartupProfileProviders(Arrays.asList(startupProfileProviders));
    }

    B addStartupProfileProviders(Collection<StartupProfileProvider> startupProfileProviders) {
      this.startupProfileProviders.addAll(startupProfileProviders);
      return self();
    }

    List<StartupProfileProvider> getStartupProfileProviders() {
      return startupProfileProviders;
    }

    /**
     * Set a cancellation checker.
     *
     * <p>The cancellation checker will be periodically called to check if the compilation should be
     * cancelled before completion.
     */
    public B setCancelCompilationChecker(CancelCompilationChecker checker) {
      this.cancelCompilationChecker = checker;
      return self();
    }

    public CancelCompilationChecker getCancelCompilationChecker() {
      return cancelCompilationChecker;
    }

    /**
     * Allow to skip to dump into file and dump into directory instruction, this is primarily used
     * for chained compilation in L8 so there are no duplicated dumps.
     */
    B skipDump() {
      dumpInputFlags = DumpInputFlags.noDump();
      return self();
    }

    B dumpInputToFile(Path file) {
      dumpInputFlags = DumpInputFlags.dumpToFile(file);
      return self();
    }

    B dumpInputToDirectory(Path directory) {
      dumpInputFlags = DumpInputFlags.dumpToDirectory(directory);
      return self();
    }

    DumpInputFlags getDumpInputFlags() {
      return dumpInputFlags;
    }

    @Override
    void validate() {
      Reporter reporter = getReporter();
      if (mode == null) {
        reporter.error("Expected valid compilation mode, was null");
      }
      FileUtils.validateOutputFile(outputPath, reporter);
      if (getProgramConsumer() == null) {
        // This is never the case for a command-line parse, so we report using API references.
        reporter.error("A ProgramConsumer or Output is required for compilation");
      }
      List<Class> programConsumerClasses = new ArrayList<>(3);
      if (programConsumer instanceof DexIndexedConsumer) {
        programConsumerClasses.add(DexIndexedConsumer.class);
      }
      if (programConsumer instanceof DexFilePerClassFileConsumer) {
        programConsumerClasses.add(DexFilePerClassFileConsumer.class);
      }
      if (programConsumer instanceof ClassFileConsumer) {
        programConsumerClasses.add(ClassFileConsumer.class);
      }
      if (programConsumerClasses.size() > 1) {
        StringBuilder builder = new StringBuilder()
            .append("Invalid program consumer.")
            .append(" A program consumer can implement at most one consumer type but ")
            .append(programConsumer.getClass().getName())
            .append(" implements types:");
        for (Class clazz : programConsumerClasses) {
          builder.append(" ").append(clazz.getName());
        }
        reporter.error(builder.toString());
      }
      if (getMinApiLevel() > AndroidApiLevel.LATEST.getLevel()) {
        if (getMinApiLevel() != AndroidApiLevel.ANDROID_PLATFORM_CONSTANT) {
          reporter.warning(new UnsupportedAndroidApiLevelDiagnostic(getMinApiLevel(), 0));
        }
      }
      if (hasDesugaredLibraryConfiguration() && getAndroidPlatformBuild()) {
        reporter.error("Android platform builds cannot use desugared library");
      }
      super.validate();
    }

    /**
     * Add an inspection of the output program.
     *
     * <p>On a successful compilation the inspection is guaranteed to be called with inspectors that
     * combined cover all of the output program. The inspections may be called multiple times with
     * inspectors that have overlapping content (eg, classes synthesized based on multiple inputs
     * can lead to this). Any overlapping content will be consistent, e.g., the inspection of type T
     * will be the same (equality, not identify) as any other inspection of type T.
     *
     * <p>There is no guarantee of the order inspections are called or on which thread they are
     * called.
     *
     * <p>The validity of an {@code Inspector} and all of its sub-inspectors, eg,
     * {@MethodInspector}, is that of the callback. If any inspector object escapes the scope of the
     * callback, the behavior of that inspector is undefined.
     *
     * @param inspection Inspection callback receiving inspectors denoting parts of the output.
     */
    public B addOutputInspection(Consumer<Inspector> inspection) {
      outputInspections.add(inspection);
      return self();
    }

    List<Consumer<Inspector>> getOutputInspections() {
      return outputInspections;
    }

    /**
     * Set a conflict resolver to determine which class definition to use in case of duplicates.
     *
     * <p>If no resolver is set, the compiler will fail compilation in case of duplicates.
     *
     * @param resolver Resolver for choosing between duplicate classes.
     */
    public B setClassConflictResolver(ClassConflictResolver resolver) {
      this.classConflictResolver = resolver;
      return self();
    }

    ClassConflictResolver getClassConflictResolver() {
      return classConflictResolver;
    }

    boolean hasNativeMultidex() {
      return isMinApiLevelSet() && getMinApiLevel() >= AndroidApiLevel.L.getLevel();
    }
  }
}
