// Copyright (c) 2018, 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.graph;

import com.android.build.shrinker.r8integration.R8ResourceShrinkerState;
import com.android.tools.r8.androidapi.AndroidApiLevelCompute;
import com.android.tools.r8.androidapi.ComputedApiLevel;
import com.android.tools.r8.classmerging.ClassMergerMode;
import com.android.tools.r8.contexts.CompilationContext;
import com.android.tools.r8.contexts.CompilationContext.ProcessorContext;
import com.android.tools.r8.errors.dontwarn.DontWarnConfiguration;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.analysis.InitializedClassesInInstanceMethodsAnalysis.InitializedClassesInInstanceMethods;
import com.android.tools.r8.graph.classmerging.MergedClassesCollection;
import com.android.tools.r8.graph.lens.AppliedGraphLens;
import com.android.tools.r8.graph.lens.ClearCodeRewritingGraphLens;
import com.android.tools.r8.graph.lens.GraphLens;
import com.android.tools.r8.graph.lens.InitClassLens;
import com.android.tools.r8.graph.lens.NonIdentityGraphLens;
import com.android.tools.r8.horizontalclassmerging.HorizontallyMergedClasses;
import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraintFactory;
import com.android.tools.r8.ir.analysis.proto.EnumLiteProtoShrinker;
import com.android.tools.r8.ir.analysis.proto.GeneratedExtensionRegistryShrinker;
import com.android.tools.r8.ir.analysis.proto.GeneratedMessageLiteBuilderShrinker;
import com.android.tools.r8.ir.analysis.proto.GeneratedMessageLiteShrinker;
import com.android.tools.r8.ir.analysis.proto.ProtoShrinker;
import com.android.tools.r8.ir.analysis.value.AbstractValueFactory;
import com.android.tools.r8.ir.analysis.value.AbstractValueJoiner.AbstractValueConstantPropagationJoiner;
import com.android.tools.r8.ir.analysis.value.AbstractValueJoiner.AbstractValueFieldJoiner;
import com.android.tools.r8.ir.analysis.value.AbstractValueJoiner.AbstractValueParameterJoiner;
import com.android.tools.r8.ir.desugar.TypeRewriter;
import com.android.tools.r8.ir.optimize.enums.EnumDataMap;
import com.android.tools.r8.ir.optimize.info.MethodResolutionOptimizationInfoCollection;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoFactory;
import com.android.tools.r8.ir.optimize.library.LibraryMemberOptimizer;
import com.android.tools.r8.ir.optimize.library.LibraryMethodSideEffectModelCollection;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.naming.SeedMapper;
import com.android.tools.r8.optimize.MemberRebindingIdentityLens;
import com.android.tools.r8.optimize.MemberRebindingIdentityLensFactory;
import com.android.tools.r8.optimize.argumentpropagation.ArgumentPropagator;
import com.android.tools.r8.optimize.compose.ComposeReferences;
import com.android.tools.r8.optimize.interfaces.collection.OpenClosedInterfacesCollection;
import com.android.tools.r8.profile.art.ArtProfileCollection;
import com.android.tools.r8.profile.startup.profile.StartupProfile;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.shaking.AssumeInfoCollection;
import com.android.tools.r8.shaking.KeepClassInfo;
import com.android.tools.r8.shaking.KeepFieldInfo;
import com.android.tools.r8.shaking.KeepInfo;
import com.android.tools.r8.shaking.KeepInfoCollection;
import com.android.tools.r8.shaking.KeepMemberInfo;
import com.android.tools.r8.shaking.KeepMethodInfo;
import com.android.tools.r8.shaking.LibraryModeledPredicate;
import com.android.tools.r8.shaking.MainDexInfo;
import com.android.tools.r8.shaking.ProguardCompatibilityActions;
import com.android.tools.r8.shaking.RootSetUtils.MainDexRootSet;
import com.android.tools.r8.shaking.RootSetUtils.RootSet;
import com.android.tools.r8.synthesis.SyntheticItems;
import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.TestingOptions;
import com.android.tools.r8.utils.OptionalBool;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.ResourceShrinkerUtils;
import com.android.tools.r8.utils.ThrowingConsumer;
import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.threads.ThreadTask;
import com.android.tools.r8.utils.threads.ThreadTaskUtils;
import com.android.tools.r8.verticalclassmerging.VerticallyMergedClasses;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class AppView<T extends AppInfo> implements DexDefinitionSupplier, LibraryModeledPredicate {

  public enum WholeProgramOptimizations {
    ON,
    OFF;

    public boolean isOn() {
      return this == ON;
    }
  }

  private T appInfo;
  private AppInfoWithClassHierarchy appInfoForDesugaring;
  private AppServices appServices;
  private ArtProfileCollection artProfileCollection;
  private AssumeInfoCollection assumeInfoCollection = AssumeInfoCollection.builder().build();
  private final DontWarnConfiguration dontWarnConfiguration;
  private final WholeProgramOptimizations wholeProgramOptimizations;
  private GraphLens codeLens = GraphLens.getIdentityLens();
  private GraphLens graphLens = GraphLens.getIdentityLens();
  private GraphLens genericSignaturesLens = GraphLens.getIdentityLens();
  private InitClassLens initClassLens;
  private GraphLens kotlinMetadataLens = GraphLens.getIdentityLens();
  private NamingLens namingLens = NamingLens.getIdentityLens();
  private ProguardCompatibilityActions proguardCompatibilityActions;
  private RootSet rootSet;
  private MethodResolutionOptimizationInfoCollection methodResolutionOptimizationInfoCollection =
      MethodResolutionOptimizationInfoCollection.empty();
  private MainDexRootSet mainDexRootSet = null;
  private StartupProfile startupProfile;

  // This should preferably always be obtained via AppInfoWithLiveness.
  // Currently however the liveness may be downgraded thus loosing the computed keep info.
  private KeepInfoCollection keepInfo = null;

  private ComposeReferences composeReferences = null;

  private final AbstractValueFactory abstractValueFactory;
  private final AbstractValueConstantPropagationJoiner abstractValueConstantPropagationJoiner;
  private final AbstractValueFieldJoiner abstractValueFieldJoiner;
  private final AbstractValueParameterJoiner abstractValueParameterJoiner;
  private final InstanceFieldInitializationInfoFactory instanceFieldInitializationInfoFactory =
      new InstanceFieldInitializationInfoFactory();
  private final SimpleInliningConstraintFactory simpleInliningConstraintFactory =
      new SimpleInliningConstraintFactory();

  // Desugaring.
  public final TypeRewriter typeRewriter;

  // Modeling.
  private final LibraryMethodSideEffectModelCollection libraryMethodSideEffectModelCollection;

  // Optimizations.
  private final ArgumentPropagator argumentPropagator;
  private final LibraryMemberOptimizer libraryMemberOptimizer;
  private final ProtoShrinker protoShrinker;

  // Optimization results.
  private boolean allCodeProcessed = false;
  private Predicate<DexType> classesEscapingIntoLibrary = Predicates.alwaysTrue();
  private InitializedClassesInInstanceMethods initializedClassesInInstanceMethods;
  private HorizontallyMergedClasses horizontallyMergedClasses = HorizontallyMergedClasses.empty();
  private VerticallyMergedClasses verticallyMergedClasses;
  private EnumDataMap unboxedEnums = null;
  private OpenClosedInterfacesCollection openClosedInterfacesCollection =
      OpenClosedInterfacesCollection.getDefault();
  // TODO(b/169115389): Remove
  private Set<DexMethod> cfByteCodePassThrough = ImmutableSet.of();
  private final Map<DexType, DexValueString> sourceDebugExtensions = new IdentityHashMap<>();
  private final Map<DexType, String> sourceFileForPrunedTypes = new IdentityHashMap<>();

  private SeedMapper applyMappingSeedMapper;

  private R8ResourceShrinkerState resourceShrinkerState = null;

  // When input has been (partially) desugared these are the classes which has been library
  // desugared. This information is populated in the IR converter.
  private Set<DexType> alreadyLibraryDesugared = null;

  private final CompilationContext context;

  private final Thread mainThread = Thread.currentThread();

  private final AndroidApiLevelCompute apiLevelCompute;
  private final ComputedApiLevel computedMinApiLevel;

  private AppView(
      T appInfo,
      ArtProfileCollection artProfileCollection,
      StartupProfile startupProfile,
      WholeProgramOptimizations wholeProgramOptimizations,
      TypeRewriter mapper) {
    this(
        appInfo,
        artProfileCollection,
        startupProfile,
        wholeProgramOptimizations,
        mapper,
        Timing.empty());
  }

  private AppView(
      T appInfo,
      ArtProfileCollection artProfileCollection,
      StartupProfile startupProfile,
      WholeProgramOptimizations wholeProgramOptimizations,
      TypeRewriter mapper,
      Timing timing) {
    assert appInfo != null;
    this.appInfo = appInfo;
    this.context =
        timing.time(
            "Compilation context", () -> CompilationContext.createInitialContext(options()));
    this.wholeProgramOptimizations = wholeProgramOptimizations;
    abstractValueFactory = new AbstractValueFactory();
    abstractValueConstantPropagationJoiner = new AbstractValueConstantPropagationJoiner(this);
    if (enableWholeProgramOptimizations()) {
      abstractValueFieldJoiner = new AbstractValueFieldJoiner(withClassHierarchy());
      abstractValueParameterJoiner = new AbstractValueParameterJoiner(withClassHierarchy());
    } else {
      abstractValueFieldJoiner = null;
      abstractValueParameterJoiner = null;
    }
    this.artProfileCollection = artProfileCollection;
    this.startupProfile = startupProfile;
    this.dontWarnConfiguration =
        timing.time(
            "Dont warn config",
            () -> DontWarnConfiguration.create(options().getProguardConfiguration()));
    this.initClassLens = timing.time("Init class lens", InitClassLens::getThrowingInstance);
    this.typeRewriter = mapper;
    timing.begin("Create argument propagator");
    if (enableWholeProgramOptimizations() && options().callSiteOptimizationOptions().isEnabled()) {
      this.argumentPropagator = new ArgumentPropagator(withLiveness());
    } else {
      this.argumentPropagator = null;
    }
    if (enableWholeProgramOptimizations() && options().isOptimizedResourceShrinking()) {
      resourceShrinkerState = ResourceShrinkerUtils.createResourceShrinkerState(this);
    }
    timing.end();
    this.libraryMethodSideEffectModelCollection =
        timing.time("Library side-effects", () -> new LibraryMethodSideEffectModelCollection(this));
    this.libraryMemberOptimizer =
        timing.time("Library optimizer", () -> new LibraryMemberOptimizer(this, timing));
    this.protoShrinker = timing.time("Proto shrinker", () -> ProtoShrinker.create(withLiveness()));
    this.apiLevelCompute =
        timing.time("ApiLevel compute", () -> AndroidApiLevelCompute.create(this));
    this.computedMinApiLevel =
        timing.time(
            "ApiLevel computed", () -> apiLevelCompute.computeInitialMinApiLevel(options()));
  }

  public boolean verifyMainThread() {
    assert mainThread == Thread.currentThread();
    return true;
  }

  @Override
  public boolean isModeled(DexType type) {
    return libraryMemberOptimizer.isModeled(type);
  }

  private static <T extends AppInfo> TypeRewriter defaultTypeRewriter(T appInfo) {
    InternalOptions options = appInfo.options();
    return options.getTypeRewriter();
  }

  public static <T extends AppInfo> AppView<T> createForD8(T appInfo) {
    return new AppView<>(
        appInfo,
        ArtProfileCollection.createInitialArtProfileCollection(appInfo, appInfo.options()),
        StartupProfile.empty(),
        WholeProgramOptimizations.OFF,
        defaultTypeRewriter(appInfo));
  }

  public static AppView<AppInfoWithClassHierarchy> createForSimulatingR8InD8(
      DirectMappedDexApplication application, MainDexInfo mainDexInfo) {
    ClassToFeatureSplitMap classToFeatureSplitMap =
        ClassToFeatureSplitMap.createInitialClassToFeatureSplitMap(application.options);
    AppInfoWithClassHierarchy appInfo =
        AppInfoWithClassHierarchy.createInitialAppInfoWithClassHierarchy(
            application,
            classToFeatureSplitMap,
            mainDexInfo,
            GlobalSyntheticsStrategy.forSingleOutputMode());
    return new AppView<>(
        appInfo,
        ArtProfileCollection.empty(),
        StartupProfile.empty(),
        WholeProgramOptimizations.ON,
        defaultTypeRewriter(appInfo));
  }

  public static <T extends AppInfo> AppView<T> createForD8(
      T appInfo, TypeRewriter mapper, Timing timing) {
    return new AppView<>(
        appInfo,
        ArtProfileCollection.createInitialArtProfileCollection(appInfo, appInfo.options()),
        StartupProfile.empty(),
        WholeProgramOptimizations.OFF,
        mapper,
        timing);
  }

  public static AppView<AppInfoWithClassHierarchy> createForR8(DexApplication application) {
    return createForR8(application, MainDexInfo.none());
  }

  public static AppView<AppInfoWithClassHierarchy> createForR8(
      DexApplication application, MainDexInfo mainDexInfo) {
    ClassToFeatureSplitMap classToFeatureSplitMap =
        ClassToFeatureSplitMap.createInitialClassToFeatureSplitMap(application.options);
    AppInfoWithClassHierarchy appInfo =
        AppInfoWithClassHierarchy.createInitialAppInfoWithClassHierarchy(
            application,
            classToFeatureSplitMap,
            mainDexInfo,
            GlobalSyntheticsStrategy.forSingleOutputMode());
    return new AppView<>(
        appInfo,
        ArtProfileCollection.createInitialArtProfileCollection(appInfo, appInfo.options()),
        StartupProfile.createInitialStartupProfileForR8(application),
        WholeProgramOptimizations.ON,
        defaultTypeRewriter(appInfo));
  }

  public static <T extends AppInfo> AppView<T> createForL8(T appInfo, TypeRewriter mapper) {
    return new AppView<>(
        appInfo,
        ArtProfileCollection.createInitialArtProfileCollection(appInfo, appInfo.options()),
        StartupProfile.empty(),
        WholeProgramOptimizations.OFF,
        mapper);
  }

  public static <T extends AppInfo> AppView<T> createForRelocator(T appInfo) {
    return new AppView<>(
        appInfo,
        ArtProfileCollection.empty(),
        StartupProfile.empty(),
        WholeProgramOptimizations.OFF,
        defaultTypeRewriter(appInfo));
  }

  public static AppView<AppInfoWithClassHierarchy> createForTracer(
      AppInfoWithClassHierarchy appInfo) {
    return new AppView<>(
        appInfo,
        ArtProfileCollection.empty(),
        StartupProfile.empty(),
        WholeProgramOptimizations.ON,
        defaultTypeRewriter(appInfo));
  }

  public AbstractValueFactory abstractValueFactory() {
    return abstractValueFactory;
  }

  public AbstractValueConstantPropagationJoiner getAbstractValueConstantPropagationJoiner() {
    return abstractValueConstantPropagationJoiner;
  }

  public AbstractValueFieldJoiner getAbstractValueFieldJoiner() {
    return abstractValueFieldJoiner;
  }

  public AbstractValueParameterJoiner getAbstractValueParameterJoiner() {
    return abstractValueParameterJoiner;
  }

  public void clearMethodResolutionOptimizationInfoCollection() {
    methodResolutionOptimizationInfoCollection = MethodResolutionOptimizationInfoCollection.empty();
  }

  public MethodResolutionOptimizationInfoCollection
      getMethodResolutionOptimizationInfoCollection() {
    return methodResolutionOptimizationInfoCollection;
  }

  public void setMethodResolutionOptimizationInfoCollection(
      MethodResolutionOptimizationInfoCollection getMethodResolutionOptimizationInfoCollection) {
    this.methodResolutionOptimizationInfoCollection = getMethodResolutionOptimizationInfoCollection;
  }

  public InstanceFieldInitializationInfoFactory instanceFieldInitializationInfoFactory() {
    return instanceFieldInitializationInfoFactory;
  }

  public SimpleInliningConstraintFactory simpleInliningConstraintFactory() {
    return simpleInliningConstraintFactory;
  }

  public DexApplication app() {
    return appInfo().app();
  }

  public T appInfo() {
    assert !appInfo.hasClassHierarchy() || enableWholeProgramOptimizations();
    return appInfo;
  }

  public AppInfoWithClassHierarchy appInfoWithClassHierarchy() {
    return hasClassHierarchy() ? appInfo.withClassHierarchy() : null;
  }

  public AppInfoWithLiveness appInfoWithLiveness() {
    return hasLiveness() ? appInfo.withLiveness() : null;
  }

  public AppInfoWithClassHierarchy appInfoForDesugaring() {
    if (enableWholeProgramOptimizations()) {
      assert appInfo.hasClassHierarchy();
      return appInfo.withClassHierarchy();
    }
    assert !appInfo.hasClassHierarchy();
    if (appInfoForDesugaring == null) {
      appInfoForDesugaring = AppInfoWithClassHierarchy.createForDesugaring(appInfo());
    }
    return appInfoForDesugaring;
  }

  private void unsetAppInfoForDesugaring() {
    appInfoForDesugaring = null;
  }

  public <U extends T> AppView<U> setAppInfo(U appInfo) {
    assert !appInfo.isObsolete();
    AppInfo previous = this.appInfo;
    this.appInfo = appInfo;
    unsetAppInfoForDesugaring();
    if (appInfo != previous) {
      previous.markObsolete();
    }
    if (appInfo.hasLiveness()) {
      keepInfo = appInfo.withLiveness().getKeepInfo();
    }
    @SuppressWarnings("unchecked")
    AppView<U> appViewWithSpecializedAppInfo = (AppView<U>) this;
    return appViewWithSpecializedAppInfo;
  }

  public boolean isAllCodeProcessed() {
    return allCodeProcessed;
  }

  public void setAllCodeProcessed() {
    allCodeProcessed = true;
  }

  public void clearCodeRewritings(ExecutorService executorService, Timing timing)
      throws ExecutionException {
    timing.begin("Clear code rewritings");
    setGraphLens(new ClearCodeRewritingGraphLens(withClassHierarchy()));

    MemberRebindingIdentityLens memberRebindingIdentityLens =
        MemberRebindingIdentityLensFactory.create(withClassHierarchy(), executorService);
    setGraphLens(memberRebindingIdentityLens);
    timing.end();
  }

  public void flattenGraphLenses() {
    GraphLens graphLens = graphLens();
    setGraphLens(GraphLens.getIdentityLens());
    setGraphLens(new AppliedGraphLens(withClassHierarchy(), graphLens));
  }

  public AppServices appServices() {
    return appServices;
  }

  public void setAppServices(AppServices appServices) {
    this.appServices = appServices;
  }

  public ArtProfileCollection getArtProfileCollection() {
    return artProfileCollection;
  }

  public void setArtProfileCollection(ArtProfileCollection artProfileCollection) {
    this.artProfileCollection = artProfileCollection;
  }

  public StartupProfile getStartupProfile() {
    return startupProfile;
  }

  public void setStartupProfile(StartupProfile startupProfile) {
    this.startupProfile = startupProfile;
  }

  public AssumeInfoCollection getAssumeInfoCollection() {
    return assumeInfoCollection;
  }

  public void setAssumeInfoCollection(AssumeInfoCollection assumeInfoCollection) {
    this.assumeInfoCollection = assumeInfoCollection;
  }

  public DontWarnConfiguration getDontWarnConfiguration() {
    return dontWarnConfiguration;
  }

  public boolean isClassEscapingIntoLibrary(DexType type) {
    assert type.isClassType();
    return classesEscapingIntoLibrary.test(type);
  }

  public void setClassesEscapingIntoLibrary(Predicate<DexType> classesEscapingIntoLibrary) {
    this.classesEscapingIntoLibrary = classesEscapingIntoLibrary;
  }

  public void setSourceDebugExtensionForType(DexClass clazz, DexValueString sourceDebugExtension) {
    sourceDebugExtensions.put(clazz.type, sourceDebugExtension);
  }

  public DexValueString getSourceDebugExtensionForType(DexClass clazz) {
    return sourceDebugExtensions.get(clazz.type);
  }

  @Override
  public ClassResolutionResult contextIndependentDefinitionForWithResolutionResult(DexType type) {
    return appInfo().contextIndependentDefinitionForWithResolutionResult(type);
  }

  @Override
  public final DexClass definitionFor(DexType type) {
    return appInfo().definitionFor(type);
  }

  public OptionalBool isInterface(DexType type) {
    assert type.isClassType();
    // Without whole program information we should not assume anything about any other class than
    // the current holder in a given context.
    if (enableWholeProgramOptimizations()) {
      DexClass clazz = definitionFor(type);
      if (clazz == null) {
        return OptionalBool.unknown();
      }
      return OptionalBool.of(clazz.isInterface());
    }
    return OptionalBool.unknown();
  }

  @Override
  public DexItemFactory dexItemFactory() {
    return appInfo.dexItemFactory();
  }

  public ComposeReferences getComposeReferences() {
    assert options().getJetpackComposeOptions().isAnyOptimizationsEnabled();
    if (composeReferences == null) {
      composeReferences = new ComposeReferences(dexItemFactory());
    }
    return composeReferences;
  }

  public boolean enableWholeProgramOptimizations() {
    return wholeProgramOptimizations == WholeProgramOptimizations.ON;
  }

  public WholeProgramOptimizations getWholeProgramOptimizations() {
    return wholeProgramOptimizations;
  }

  /**
   * Create a new processor context.
   *
   * <p>The order of processor contexts for a compilation must be deterministic so this is required
   * to be called on the main thread only.
   */
  public ProcessorContext createProcessorContext() {
    assert verifyMainThread();
    return context.createProcessorContext();
  }

  public SyntheticItems getSyntheticItems() {
    return appInfo.getSyntheticItems();
  }

  public <E extends Throwable> void withArgumentPropagator(
      ThrowingConsumer<ArgumentPropagator, E> consumer) throws E {
    if (argumentPropagator != null) {
      consumer.accept(argumentPropagator);
    }
  }

  public LibraryMemberOptimizer libraryMethodOptimizer() {
    return libraryMemberOptimizer;
  }

  public LibraryMethodSideEffectModelCollection getLibraryMethodSideEffectModelCollection() {
    return libraryMethodSideEffectModelCollection;
  }

  public ProtoShrinker protoShrinker() {
    return protoShrinker;
  }

  public <E extends Throwable> void withProtoShrinker(ThrowingConsumer<ProtoShrinker, E> consumer)
      throws E {
    if (protoShrinker != null) {
      consumer.accept(protoShrinker);
    }
  }

  public <U> U withProtoShrinker(Function<ProtoShrinker, U> consumer, U defaultValue) {
    if (protoShrinker != null) {
      return consumer.apply(protoShrinker);
    }
    return defaultValue;
  }

  public <U> U withProtoEnumShrinker(Function<EnumLiteProtoShrinker, U> fn, U defaultValue) {
    if (protoShrinker != null && options().protoShrinking().isEnumLiteProtoShrinkingEnabled()) {
      return fn.apply(protoShrinker.enumLiteProtoShrinker);
    }
    return defaultValue;
  }

  public <E extends Throwable> void withGeneratedExtensionRegistryShrinker(
      ThrowingConsumer<GeneratedExtensionRegistryShrinker, E> consumer) throws E {
    if (protoShrinker != null && protoShrinker.generatedExtensionRegistryShrinker != null) {
      consumer.accept(protoShrinker.generatedExtensionRegistryShrinker);
    }
  }

  public <U> U withGeneratedExtensionRegistryShrinker(
      Function<GeneratedExtensionRegistryShrinker, U> fn, U defaultValue) {
    if (protoShrinker != null && protoShrinker.generatedExtensionRegistryShrinker != null) {
      return fn.apply(protoShrinker.generatedExtensionRegistryShrinker);
    }
    return defaultValue;
  }

  public <E extends Throwable> void withGeneratedMessageLiteShrinker(
      ThrowingConsumer<GeneratedMessageLiteShrinker, E> consumer) throws E {
    if (protoShrinker != null && protoShrinker.generatedMessageLiteShrinker != null) {
      consumer.accept(protoShrinker.generatedMessageLiteShrinker);
    }
  }

  public <E extends Throwable> void withGeneratedMessageLiteBuilderShrinker(
      ThrowingConsumer<GeneratedMessageLiteBuilderShrinker, E> consumer) throws E {
    if (protoShrinker != null && protoShrinker.generatedMessageLiteBuilderShrinker != null) {
      consumer.accept(protoShrinker.generatedMessageLiteBuilderShrinker);
    }
  }

  public <U> U withGeneratedMessageLiteShrinker(
      Function<GeneratedMessageLiteShrinker, U> fn, U defaultValue) {
    if (protoShrinker != null && protoShrinker.generatedMessageLiteShrinker != null) {
      return fn.apply(protoShrinker.generatedMessageLiteShrinker);
    }
    return defaultValue;
  }

  public <U> U withGeneratedMessageLiteBuilderShrinker(
      Function<GeneratedMessageLiteBuilderShrinker, U> fn, U defaultValue) {
    if (protoShrinker != null && protoShrinker.generatedMessageLiteBuilderShrinker != null) {
      return fn.apply(protoShrinker.generatedMessageLiteBuilderShrinker);
    }
    return defaultValue;
  }

  public GraphLens codeLens() {
    return codeLens;
  }

  public void setCodeLens(GraphLens codeLens) {
    this.codeLens = codeLens;
  }

  public GraphLens graphLens() {
    return graphLens;
  }

  /** @return true if the graph lens changed, otherwise false. */
  public boolean setGraphLens(GraphLens graphLens) {
    if (graphLens != this.graphLens) {
      this.graphLens = graphLens;

      // TODO(b/202368283): Currently, we always set an applied lens or a clear code rewriting lens
      //  when the graph lens has been fully applied to all code. Therefore, we implicitly update
      //  the code lens when these lenses are set. Now that we have an explicit code lens, the clear
      //  code rewriting lens is redundant and could be removed.
      if (graphLens.isAppliedLens() || graphLens.isClearCodeRewritingLens()) {
        setCodeLens(graphLens);
      }
      return true;
    }
    return false;
  }

  public GraphLens getGenericSignaturesLens() {
    return genericSignaturesLens;
  }

  public void setGenericSignaturesLens(GraphLens genericSignaturesLens) {
    this.genericSignaturesLens = genericSignaturesLens;
  }

  private boolean disallowFurtherInitClassUses = false;

  public void dissallowFurtherInitClassUses() {
    disallowFurtherInitClassUses = true;
  }

  public boolean canUseInitClass() {
    return !disallowFurtherInitClassUses && options().isShrinking();
  }

  public InitClassLens initClassLens() {
    return initClassLens;
  }

  public boolean hasInitClassLens() {
    return initClassLens != null;
  }

  public void setInitClassLens(InitClassLens initClassLens) {
    this.initClassLens = initClassLens;
  }

  public GraphLens getKotlinMetadataLens() {
    return kotlinMetadataLens;
  }

  public void setKotlinMetadataLens(GraphLens kotlinMetadataLens) {
    this.kotlinMetadataLens = kotlinMetadataLens;
  }

  public boolean hasInitializedClassesInInstanceMethods() {
    return initializedClassesInInstanceMethods != null;
  }

  public InitializedClassesInInstanceMethods getInitializedClassesInInstanceMethods() {
    return initializedClassesInInstanceMethods;
  }

  public void setInitializedClassesInInstanceMethods(
      InitializedClassesInInstanceMethods initializedClassesInInstanceMethods) {
    this.initializedClassesInInstanceMethods = initializedClassesInInstanceMethods;
  }

  public void setCfByteCodePassThrough(Set<DexMethod> cfByteCodePassThrough) {
    assert options().enableCfByteCodePassThrough;
    this.cfByteCodePassThrough = cfByteCodePassThrough;
  }

  public <U> U withInitializedClassesInInstanceMethods(
      Function<InitializedClassesInInstanceMethods, U> fn, U defaultValue) {
    if (initializedClassesInInstanceMethods != null) {
      return fn.apply(initializedClassesInInstanceMethods);
    }
    return defaultValue;
  }

  public InternalOptions options() {
    return appInfo.options();
  }

  public Reporter reporter() {
    return options().reporter;
  }

  public TestingOptions testing() {
    return options().testing;
  }

  public boolean hasRootSet() {
    return rootSet != null;
  }

  public RootSet rootSet() {
    return rootSet;
  }

  public void setRootSet(RootSet rootSet) {
    this.rootSet = rootSet;
  }

  public void setMainDexRootSet(MainDexRootSet mainDexRootSet) {
    assert mainDexRootSet != null : "Root set should never be recomputed";
    this.mainDexRootSet = mainDexRootSet;
  }

  public boolean hasMainDexRootSet() {
    return mainDexRootSet != null;
  }

  public MainDexRootSet getMainDexRootSet() {
    return mainDexRootSet;
  }

  public boolean hasKeepInfo() {
    return keepInfo != null;
  }

  public KeepInfoCollection getKeepInfo() {
    assert hasKeepInfo();
    return keepInfo;
  }

  public KeepInfo<?, ?> getKeepInfo(ProgramDefinition definition) {
    return definition
        .getReference()
        .apply(
            clazz -> getKeepInfo(definition.asProgramClass()),
            field -> getKeepInfo(definition.asProgramField()),
            method -> getKeepInfo(definition.asProgramMethod()));
  }

  public KeepClassInfo getKeepInfo(DexProgramClass clazz) {
    return getKeepInfo().getClassInfo(clazz);
  }

  public KeepClassInfo getKeepInfoOrDefault(DexProgramClass clazz, KeepClassInfo defaultValue) {
    return hasKeepInfo() ? getKeepInfo().getClassInfo(clazz) : defaultValue;
  }

  public KeepFieldInfo getKeepInfo(ProgramField field) {
    return getKeepInfo().getFieldInfo(field);
  }

  public KeepMemberInfo<?, ?> getKeepInfo(ProgramMember<?, ?> member) {
    return member.isField()
        ? getKeepInfo(member.asProgramField())
        : getKeepInfo(member.asProgramMethod());
  }

  public KeepMethodInfo getKeepInfo(ProgramMethod method) {
    return getKeepInfo().getMethodInfo(method);
  }

  public NamingLens getNamingLens() {
    return namingLens;
  }

  public void setNamingLens(NamingLens namingLens) {
    this.namingLens = namingLens;
  }

  public boolean hasProguardCompatibilityActions() {
    return proguardCompatibilityActions != null;
  }

  public ProguardCompatibilityActions getProguardCompatibilityActions() {
    return proguardCompatibilityActions;
  }

  public void setProguardCompatibilityActions(
      ProguardCompatibilityActions proguardCompatibilityActions) {
    assert options().forceProguardCompatibility;
    this.proguardCompatibilityActions = proguardCompatibilityActions;
  }

  public MergedClassesCollection allMergedClasses() {
    MergedClassesCollection collection = new MergedClassesCollection();
    if (hasHorizontallyMergedClasses()) {
      collection.add(horizontallyMergedClasses);
    }
    if (verticallyMergedClasses != null) {
      collection.add(verticallyMergedClasses);
    }
    return collection;
  }

  public boolean hasHorizontallyMergedClasses() {
    return !horizontallyMergedClasses.isEmpty();
  }

  /**
   * Get the result of horizontal class merging. Returns null if horizontal class merging has not
   * been run.
   */
  public HorizontallyMergedClasses horizontallyMergedClasses() {
    return horizontallyMergedClasses;
  }

  public void setHorizontallyMergedClasses(HorizontallyMergedClasses horizontallyMergedClasses) {
    assert !hasHorizontallyMergedClasses();
    this.horizontallyMergedClasses = horizontallyMergedClasses;
    testing().horizontallyMergedClassesConsumer.accept(this, horizontallyMergedClasses);
  }

  public boolean hasVerticallyMergedClasses() {
    return verticallyMergedClasses != null;
  }

  /**
   * Get the result of vertical class merging. Returns null if vertical class merging has not been
   * run.
   */
  public VerticallyMergedClasses getVerticallyMergedClasses() {
    return verticallyMergedClasses;
  }

  public void setVerticallyMergedClasses(
      VerticallyMergedClasses verticallyMergedClasses, ClassMergerMode mode) {
    if (mode.isInitial()) {
      assert this.verticallyMergedClasses == null;
      this.verticallyMergedClasses = verticallyMergedClasses;
      testing().verticallyMergedClassesConsumer.accept(dexItemFactory(), verticallyMergedClasses);
    } else {
      assert this.verticallyMergedClasses != null;
    }
  }

  public OpenClosedInterfacesCollection getOpenClosedInterfacesCollection() {
    return openClosedInterfacesCollection;
  }

  public void setOpenClosedInterfacesCollection(
      OpenClosedInterfacesCollection openClosedInterfacesCollection) {
    this.openClosedInterfacesCollection = openClosedInterfacesCollection;
  }

  public boolean hasUnboxedEnums() {
    return unboxedEnums != null;
  }

  public EnumDataMap unboxedEnums() {
    return hasUnboxedEnums() ? unboxedEnums : EnumDataMap.empty();
  }

  public void setUnboxedEnums(EnumDataMap unboxedEnums) {
    assert !hasUnboxedEnums();
    this.unboxedEnums = unboxedEnums;
    testing().unboxedEnumsConsumer.accept(dexItemFactory(), unboxedEnums);
  }

  public R8ResourceShrinkerState getResourceShrinkerState() {
    return resourceShrinkerState;
  }

  public boolean validateUnboxedEnumsHaveBeenPruned() {
    for (DexType unboxedEnum : unboxedEnums.computeAllUnboxedEnums()) {
      assert appInfo.definitionForWithoutExistenceAssert(unboxedEnum) == null
          : "Enum " + unboxedEnum + " has been unboxed but is still in the program.";
      assert appInfo().withLiveness().wasPruned(unboxedEnum)
          : "Enum " + unboxedEnum + " has been unboxed but was not pruned.";
    }
    return true;
  }

  public boolean hasClassHierarchy() {
    return appInfo().hasClassHierarchy();
  }

  @SuppressWarnings("unchecked")
  public AppView<AppInfoWithClassHierarchy> withClassHierarchy() {
    return appInfo.hasClassHierarchy()
        ? (AppView<AppInfoWithClassHierarchy>) this
        : null;
  }

  @SuppressWarnings("unchecked")
  public AppView<AppInfo> withoutClassHierarchy() {
    assert !hasClassHierarchy();
    return (AppView<AppInfo>) this;
  }

  public boolean hasLiveness() {
    return appInfo().hasLiveness();
  }

  public AppView<AppInfoWithLiveness> withLiveness() {
    @SuppressWarnings("unchecked")
    AppView<AppInfoWithLiveness> appViewWithLiveness = (AppView<AppInfoWithLiveness>) this;
    return appViewWithLiveness;
  }

  @SuppressWarnings("ReferenceEquality")
  public OptionalBool isSubtype(DexType subtype, DexType supertype) {
    // Even if we can compute isSubtype by having class hierarchy we may not be allowed to ask the
    // question for all code paths in D8. Having the check for liveness ensure that we are in R8
    // territory.
    if (hasClassHierarchy()) {
      return OptionalBool.of(appInfo().withClassHierarchy().isSubtype(subtype, supertype));
    }
    if (subtype == supertype || supertype == dexItemFactory().objectType) {
      return OptionalBool.TRUE;
    }
    return OptionalBool.unknown();
  }

  public boolean isCfByteCodePassThrough(DexEncodedMethod method) {
    if (!options().enableCfByteCodePassThrough) {
      return false;
    }
    assert options().isGeneratingClassFiles();
    if (cfByteCodePassThrough.contains(method.getReference())) {
      return true;
    }
    return options().testing.cfByteCodePassThrough != null
        && options().testing.cfByteCodePassThrough.test(method.getReference());
  }

  public boolean hasCfByteCodePassThroughMethods() {
    return !cfByteCodePassThrough.isEmpty();
  }

  public void pruneItems(PrunedItems prunedItems, ExecutorService executorService, Timing timing)
      throws ExecutionException {
    if (prunedItems.isEmpty()) {
      assert appInfo().app() == prunedItems.getPrunedApp();
      return;
    }
    timing.begin("Prune AppView");
    if (appInfo.hasLiveness()) {
      AppView<AppInfoWithLiveness> self = withLiveness();
      self.setAppInfo(self.appInfo().prunedCopyFrom(prunedItems, executorService, timing));
    } else if (appInfo.hasClassHierarchy()) {
      AppView<AppInfoWithClassHierarchy> self = withClassHierarchy();
      self.setAppInfo(self.appInfo().prunedCopyFrom(prunedItems, executorService, timing));
    } else {
      pruneAppInfo(prunedItems, this, executorService, timing);
    }
    if (appServices() != null) {
      setAppServices(appServices().prunedCopy(prunedItems, timing));
    }
    setArtProfileCollection(getArtProfileCollection().withoutPrunedItems(prunedItems, timing));
    setAssumeInfoCollection(getAssumeInfoCollection().withoutPrunedItems(prunedItems, timing));
    if (hasProguardCompatibilityActions()) {
      setProguardCompatibilityActions(
          getProguardCompatibilityActions().withoutPrunedItems(prunedItems, timing));
    }
    if (hasRootSet()) {
      rootSet.pruneItems(prunedItems, timing);
    }
    setStartupProfile(
        getStartupProfile().withoutPrunedItems(prunedItems, getSyntheticItems(), timing));
    if (hasMainDexRootSet()) {
      setMainDexRootSet(mainDexRootSet.withoutPrunedItems(prunedItems, timing));
    }
    setOpenClosedInterfacesCollection(
        openClosedInterfacesCollection.withoutPrunedItems(prunedItems, timing));
    timing.end();
  }

  @SuppressWarnings("unchecked")
  private static void pruneAppInfo(
      PrunedItems prunedItems, AppView<?> appView, ExecutorService executorService, Timing timing)
      throws ExecutionException {
    ((AppView<AppInfo>) appView)
        .setAppInfo(appView.appInfo().prunedCopyFrom(prunedItems, executorService, timing));
  }

  public void rewriteWithLens(
      NonIdentityGraphLens lens, ExecutorService executorService, Timing timing)
      throws ExecutionException {
    rewriteWithLensAndApplication(lens, app().asDirect(), executorService, timing);
  }

  public void rewriteWithLensAndApplication(
      NonIdentityGraphLens lens,
      DirectMappedDexApplication application,
      ExecutorService executorService,
      Timing timing)
      throws ExecutionException {
    rewriteWithLensAndApplication(
        lens, application, executorService, timing, withClassHierarchy(), lens.getPrevious());
    assert verifyMovedMethodsHaveOriginalMethodPosition();
  }

  private static void rewriteWithLensAndApplication(
      NonIdentityGraphLens lens,
      DirectMappedDexApplication application,
      ExecutorService executorService,
      Timing timing,
      AppView<? extends AppInfoWithClassHierarchy> appView,
      GraphLens appliedLens)
      throws ExecutionException {
    assert lens != null;
    assert application != null;

    timing.begin("Rewrite AppView");

    boolean changed = appView.setGraphLens(lens);

    // Verify that the lens changed, except in the horizontal class merger case, where we install
    // the lens prior to lens rewriting AppView.
    assert changed || lens.isHorizontalClassMergerGraphLens();
    assert application.verifyWithLens(appView.appInfo().app().asDirect(), lens);

    // The application has already been rewritten with the given applied lens. Therefore, we
    // temporarily replace that lens with a lens that does not have any rewritings to avoid the
    // overhead of traversing the entire lens chain upon each lookup during the rewriting.
    NonIdentityGraphLens firstUnappliedLens = computeFirstUnappliedLens(appView, lens, appliedLens);

    // Insert a member rebinding lens above the first unapplied lens.
    // TODO(b/182129249): Once the member rebinding phase has been removed, the MemberRebindingLens
    //  should be removed and all uses of FieldRebindingIdentityLens should be replaced by
    //  MemberRebindingIdentityLens.
    GraphLens newMemberRebindingLens =
        computeNewMemberRebindingLens(appView, appliedLens, firstUnappliedLens, timing);
    firstUnappliedLens.withAlternativeParentLens(
        newMemberRebindingLens,
        () -> {
          GraphLens appliedLensInModifiedLens = GraphLens.getIdentityLens();
          ThreadTaskUtils.processTasks(
              executorService,
              appView.options(),
              timing
                  .beginMerger("Rewrite AppView concurrently", executorService)
                  .disableSlowestReporting(),
              new ThreadTask() {

                private AppInfoWithClassHierarchy result;

                @Override
                public void run(Timing timing) {
                  if (appView.hasLiveness()) {
                    result =
                        appView
                            .appInfoWithLiveness()
                            .rewrittenWithLens(
                                application, lens, appliedLensInModifiedLens, timing);
                  } else {
                    assert appView.hasClassHierarchy();
                    AppView<AppInfoWithClassHierarchy> appViewWithClassHierarchy =
                        appView.withClassHierarchy();
                    AppInfoWithClassHierarchy appInfo = appViewWithClassHierarchy.appInfo();
                    MainDexInfo rewrittenMainDexInfo =
                        appInfo
                            .getMainDexInfo()
                            .rewrittenWithLens(appView.getSyntheticItems(), lens, timing);
                    result = appInfo.rebuildWithMainDexInfo(rewrittenMainDexInfo);
                  }
                }

                @Override
                public void onJoin() {
                  appView.withClassHierarchy().setAppInfo(result);
                }
              },
              new ThreadTask() {
                @Override
                public void run(Timing threadTiming) {
                  appView.setAppServices(
                      appView.appServices().rewrittenWithLens(lens, threadTiming));
                }

                @Override
                public boolean shouldRun() {
                  return !appView.appServices().isEmpty();
                }
              },
              new ThreadTask() {
                @Override
                public void run(Timing threadTiming) {
                  appView.setArtProfileCollection(
                      appView
                          .getArtProfileCollection()
                          .rewrittenWithLens(appView, lens, threadTiming));
                }

                @Override
                public boolean shouldRun() {
                  return !appView.getArtProfileCollection().isEmpty();
                }
              },
              new ThreadTask() {
                @Override
                public void run(Timing threadTiming) {
                  appView.setAssumeInfoCollection(
                      appView
                          .getAssumeInfoCollection()
                          .rewrittenWithLens(
                              appView, lens, appliedLensInModifiedLens, threadTiming));
                }

                @Override
                public boolean shouldRun() {
                  return !appView.getAssumeInfoCollection().isEmpty();
                }
              },
              new ThreadTask() {
                @Override
                public void run(Timing threadTiming) {
                  appView.setInitClassLens(
                      appView.initClassLens().rewrittenWithLens(lens, threadTiming));
                }

                @Override
                public boolean shouldRun() {
                  return appView.hasInitClassLens();
                }
              },
              new ThreadTask() {
                @Override
                public void run(Timing threadTiming) {
                  appView.setProguardCompatibilityActions(
                      appView
                          .getProguardCompatibilityActions()
                          .rewrittenWithLens(lens, threadTiming));
                }

                @Override
                public boolean shouldRun() {
                  return appView.hasProguardCompatibilityActions()
                      && !appView.getProguardCompatibilityActions().isEmpty();
                }
              },
              new ThreadTask() {
                @Override
                public void run(Timing threadTiming) {
                  appView.setMainDexRootSet(
                      appView.getMainDexRootSet().rewrittenWithLens(lens, threadTiming));
                }

                @Override
                public boolean shouldRun() {
                  return appView.hasMainDexRootSet();
                }
              },
              new ThreadTask() {
                @Override
                public void run(Timing threadTiming) {
                  appView.setOpenClosedInterfacesCollection(
                      appView
                          .getOpenClosedInterfacesCollection()
                          .rewrittenWithLens(lens, threadTiming));
                }

                @Override
                public boolean shouldRun() {
                  return !appView.getOpenClosedInterfacesCollection().isEmpty();
                }
              },
              new ThreadTask() {
                @Override
                public void run(Timing threadTiming) {
                  appView.setRootSet(appView.rootSet().rewrittenWithLens(lens, threadTiming));
                }

                @Override
                public boolean shouldRun() {
                  return appView.hasRootSet();
                }
              },
              new ThreadTask() {
                @Override
                public void run(Timing threadTiming) {
                  appView.setStartupProfile(
                      appView.getStartupProfile().rewrittenWithLens(lens, threadTiming));
                }

                @Override
                public boolean shouldRun() {
                  return !appView.getStartupProfile().isEmpty();
                }
              },
              new ThreadTask() {
                @Override
                public void run(Timing timing) {
                  ImmutableSet.Builder<DexMethod> cfByteCodePassThroughBuilder =
                      ImmutableSet.builder();
                  for (DexMethod method : appView.cfByteCodePassThrough) {
                    cfByteCodePassThroughBuilder.add(
                        lens.getRenamedMethodSignature(method, appliedLensInModifiedLens));
                  }
                  appView.cfByteCodePassThrough = cfByteCodePassThroughBuilder.build();
                }

                @Override
                public boolean shouldRun() {
                  return !appView.cfByteCodePassThrough.isEmpty();
                }
              },
              new ThreadTask() {
                @Override
                public void run(Timing timing) {
                  appView.setInitializedClassesInInstanceMethods(
                      appView
                          .getInitializedClassesInInstanceMethods()
                          .rewrittenWithLens(lens, appliedLens));
                }

                @Override
                public boolean shouldRun() {
                  return appView.hasInitializedClassesInInstanceMethods();
                }
              });
        });

    timing.end(); // Rewrite AppView
  }

  private static NonIdentityGraphLens computeFirstUnappliedLens(
      AppView<? extends AppInfoWithClassHierarchy> appView,
      NonIdentityGraphLens lens,
      GraphLens appliedLens) {
    NonIdentityGraphLens firstUnappliedLens = lens;
    while (firstUnappliedLens.getPrevious() != appliedLens) {
      GraphLens previousLens = firstUnappliedLens.getPrevious();
      assert previousLens.isNonIdentityLens();
      assert previousLens != appView.codeLens();
      firstUnappliedLens = previousLens.asNonIdentityLens();
    }
    return firstUnappliedLens;
  }

  private static GraphLens computeNewMemberRebindingLens(
      AppView<? extends AppInfoWithClassHierarchy> appView,
      GraphLens appliedLens,
      NonIdentityGraphLens firstUnappliedLens,
      Timing timing) {
    timing.begin("Compute new member rebinding lens");
    GraphLens newMemberRebindingLens = GraphLens.getIdentityLens();
    if (!firstUnappliedLens.isMemberRebindingLens()
        && !firstUnappliedLens.isMemberRebindingIdentityLens()) {
      NonIdentityGraphLens appliedMemberRebindingLens =
          firstUnappliedLens.findPrevious(GraphLens::isMemberRebindingIdentityLens);
      if (appliedMemberRebindingLens != null) {
        newMemberRebindingLens =
            appliedMemberRebindingLens
                .asMemberRebindingIdentityLens()
                .toRewrittenMemberRebindingIdentityLens(
                    appView, appliedLens, appliedMemberRebindingLens);
      }
    }
    timing.end();
    return newMemberRebindingLens;
  }

  public void rewriteWithD8Lens(NonIdentityGraphLens lens, Timing timing) {
    rewriteWithD8Lens(lens, timing, withoutClassHierarchy());
  }

  private static void rewriteWithD8Lens(
      NonIdentityGraphLens lens, Timing timing, AppView<AppInfo> appView) {
    boolean changed = appView.setGraphLens(lens);

    // Verify that the lens changed, except in the horizontal class merger case, where we install
    // the lens prior to lens rewriting AppView.
    assert changed || lens.isHorizontalClassMergerGraphLens();

    appView.setArtProfileCollection(
        appView.getArtProfileCollection().rewrittenWithLens(appView, lens, timing));
  }

  public void setAlreadyLibraryDesugared(Set<DexType> alreadyLibraryDesugared) {
    assert this.alreadyLibraryDesugared == null;
    this.alreadyLibraryDesugared = alreadyLibraryDesugared;
  }

  /**
   * Called when an optimization that changes the app has finished. This allows easier diagnosing
   * some failures, e.g., finding which optimization pass that adds/removes a given method.
   */
  public void notifyOptimizationFinishedForTesting() {
    // Intentionally empty.
  }

  public boolean isAlreadyLibraryDesugared(DexProgramClass clazz) {
    if (!options().desugarSpecificOptions().allowAllDesugaredInput) {
      return false;
    }
    assert alreadyLibraryDesugared != null;
    return alreadyLibraryDesugared.contains(clazz.getType());
  }

  public void loadApplyMappingSeedMapper() throws IOException {
    if (options().getProguardConfiguration().hasApplyMappingFile()) {
      applyMappingSeedMapper =
          SeedMapper.seedMapperFromFile(
              options().reporter, options().getProguardConfiguration().getApplyMappingFile());
    }
  }

  public SeedMapper getApplyMappingSeedMapper() {
    return applyMappingSeedMapper;
  }

  public void clearApplyMappingSeedMapper() {
    applyMappingSeedMapper = null;
  }

  public boolean checkForTesting(Supplier<Boolean> test) {
    return testing().enableTestAssertions ? test.get() : true;
  }

  public AndroidApiLevelCompute apiLevelCompute() {
    return apiLevelCompute;
  }

  public ComputedApiLevel computedMinApiLevel() {
    return computedMinApiLevel;
  }

  public void addPrunedClassSourceFile(DexType prunedType, String sourceFile) {
    sourceFileForPrunedTypes.put(prunedType, sourceFile);
  }

  public String getPrunedClassSourceFileInfo(DexType dexType) {
    return sourceFileForPrunedTypes.get(dexType);
  }

  public boolean verifyMovedMethodsHaveOriginalMethodPosition() {
    DirectMappedDexApplication application = app().asDirect();
    application
        .classesWithDeterministicOrder()
        .forEach(
            clazz ->
                clazz.forEachProgramMethod(
                    method -> {
                      assert verifyOriginalMethodInPosition(method);
                    }));
    return true;
  }

  private static boolean verifyOriginalMethodInPosition(ProgramMethod context) {
    Code code = context.getDefinition().getCode();
    if (code == null) {
      return true;
    }
    DexMethod thisMethod = context.getReference();
    code.forEachPosition(
        context.getReference(),
        context.getDefinition().isD8R8Synthesized(),
        position -> {
          DexMethod outerCaller = position.getOutermostCaller().getMethod();
          assert thisMethod.isIdenticalTo(outerCaller);
        });
    return true;
  }
}
