// 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.InternalOptions.DesugarState;
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.StringDiagnostic;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.UncheckedApiLevel;
import com.android.tools.r8.utils.internal.FileUtils;
import com.android.tools.r8.utils.internal.ListUtils;
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 UncheckedApiLevel 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;
  private final Path apiDatabasePath;

  BaseCompilerCommand(boolean printHelp, boolean printVersion) {
    super(printHelp, printVersion);
    programConsumer = null;
    mainDexListConsumer = null;
    mode = null;
    minApiLevel = AndroidApiLevel.getDefault().asUnchecked();
    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;
    apiDatabasePath = null;
  }

  BaseCompilerCommand(
      AndroidApp app,
      CompilationMode mode,
      ProgramConsumer programConsumer,
      StringConsumer mainDexListConsumer,
      UncheckedApiLevel 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,
      Path apiDatabasePath) {
    super(app);
    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;
    this.apiDatabasePath = apiDatabasePath;
  }

  /**
   * 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.
   *
   * <p>Deprecation: Should not be used since it ignores minor versions.
   */
  @Deprecated
  public int getMinApiLevel() {
    return getUncheckedMinApiLevel().getMajor();
  }

  UncheckedApiLevel getUncheckedMinApiLevel() {
    return minApiLevel;
  }

  void dumpBaseCommandOptions(DumpOptions.Builder builder) {
    builder
        .setBackend(ProgramConsumerUtils.getBackend(programConsumer))
        .setCompilationMode(getMode())
        .setMinApi(getUncheckedMinApiLevel())
        .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;
  }

  /** Get the API database path. The default database will be used if null. */
  public Path getApiDatabasePath() {
    return apiDatabasePath;
  }

  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 UncheckedApiLevel minApiLevel = null;

    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;
    private Path apiDatabasePath = 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.
     *
     * <p>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).
     *
     * <p>Deprecation: Should not be used since it ignores minor versions.
     */
    @Deprecated
    public int getMinApiLevel() {
      return getUncheckedMinApiLevel().getMajor();
    }

    /** See {@link BaseCompilerCommandUtils#getUncheckedMinApiLevel} for a public bridge. */
    UncheckedApiLevel getUncheckedMinApiLevel() {
      if (isMinApiLevelSet()) {
        return minApiLevel;
      } else {
        var base = AndroidApiLevel.getDefault();
        return new UncheckedApiLevel(base.getMajor(), base.getMinor());
      }
    }

    boolean isMinApiLevelSet() {
      return minApiLevel != null;
    }

    /** Set the minimum required API level (aka SDK version). */
    public B setMinApiLevel(int major) {
      return setMinApiLevel(major, 0);
    }

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

    /**
     * Set the minimum required API level (aka SDK version).
     *
     * <p>See {@link BaseCompilerCommandUtils#setMinApiLevel} for a public bridge.
     */
    B setMinApiLevel(UncheckedApiLevel minApiLevel) {
      this.minApiLevel = minApiLevel;
      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,
          getUncheckedMinApiLevel());
    }

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

    /**
     * Set the API database path. The default database will be used if null.
     *
     * <p>This overrides any existing path set.
     */
    public B setApiDatabasePath(Path apiDatabasePath) {
      this.apiDatabasePath = apiDatabasePath;
      return self();
    }

    /** Get the API database path. The default database will be used if null. */
    public Path getApiDatabasePath() {
      return apiDatabasePath;
    }

    /**
     * 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, errorMessage -> reporter.error(new StringDiagnostic(errorMessage)));
      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());
      }
      UncheckedApiLevel apiLevel = getUncheckedMinApiLevel();
      if (apiLevel.isGreaterThan(AndroidApiLevel.LATEST.asUnchecked())) {
        if (!(apiLevel.equals(AndroidApiLevel.ANDROID_PLATFORM_CONSTANT))) {
          reporter.warning(
              new UnsupportedAndroidApiLevelDiagnostic(apiLevel.getMajor(), apiLevel.getMinor()));
        }
      }
      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()
          && getUncheckedMinApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.L.asUnchecked());
    }
  }
}
