// Copyright (c) 2021, 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.ir.desugar.itf;


import com.android.tools.r8.cf.CfVersion;
import com.android.tools.r8.cf.code.CfInitClass;
import com.android.tools.r8.cf.code.CfReturnVoid;
import com.android.tools.r8.cf.code.CfStackInstruction;
import com.android.tools.r8.cf.code.CfStackInstruction.Opcode;
import com.android.tools.r8.cf.code.CfStaticFieldRead;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.ClasspathOrLibraryClass;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexClasspathClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue.DexValueInt;
import com.android.tools.r8.graph.FieldAccessFlags;
import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
import com.android.tools.r8.graph.InvalidCode;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.MethodResolutionResult;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ThrowNullCode;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.DerivedMethod;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedInterfaceDescriptor;
import com.android.tools.r8.ir.desugar.itf.EmulatedInterfaceSynthesizerEventConsumer.ClasspathEmulatedInterfaceSynthesizerEventConsumer;
import com.android.tools.r8.synthesis.SyntheticClassBuilder;
import com.android.tools.r8.synthesis.SyntheticItems.SyntheticKindSelector;
import com.android.tools.r8.synthesis.SyntheticMethodBuilder;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.structural.Ordered;
import com.google.common.collect.ImmutableList;
import java.util.function.Predicate;

public class InterfaceDesugaringSyntheticHelper {

  // Any interface method desugared code can be version 1.7 at the most.
  // Note: we always desugar both default/static (v1.8) and private (v9) when targeting api < N.
  public static final CfVersion MAX_INTERFACE_DESUGARED_CF_VERSION = CfVersion.V1_7;

  public static CfVersion getInterfaceDesugaredCfVersion(CfVersion existing) {
    return Ordered.min(existing, MAX_INTERFACE_DESUGARED_CF_VERSION);
  }

  // Use InterfaceDesugaringForTesting for public accesses in tests.
  static final String COMPANION_CLASS_NAME_SUFFIX = "$-CC";
  static final String DEFAULT_METHOD_PREFIX = "$default$";
  static final String PRIVATE_METHOD_PREFIX = "$private$";

  private final AppView<?> appView;
  private final Predicate<DexType> shouldIgnoreFromReportsPredicate;

  public InterfaceDesugaringSyntheticHelper(AppView<?> appView) {
    this.appView = appView;
    this.shouldIgnoreFromReportsPredicate = getShouldIgnoreFromReportsPredicate(appView);
  }

  boolean isEmulatedInterface(DexType itf) {
    return appView
        .options()
        .machineDesugaredLibrarySpecification
        .getEmulatedInterfaces()
        .containsKey(itf);
  }

  boolean isRewrittenEmulatedInterface(DexType itf) {
    return appView
        .options()
        .machineDesugaredLibrarySpecification
        .isEmulatedInterfaceRewrittenType(itf);
  }

  DexType getEmulatedInterface(DexType type) {
    EmulatedInterfaceDescriptor interfaceDescriptor =
        appView.options().machineDesugaredLibrarySpecification.getEmulatedInterfaces().get(type);
    return interfaceDescriptor == null ? null : interfaceDescriptor.getRewrittenType();
  }

  boolean isInDesugaredLibrary(DexClass clazz) {
    assert clazz.isLibraryClass() || appView.options().isDesugaredLibraryCompilation();
    if (isEmulatedInterface(clazz.type)) {
      return true;
    }
    return appView.typeRewriter.hasRewrittenType(clazz.type, appView);
  }

  final boolean isCompatibleDefaultMethod(DexEncodedMethod method) {
    assert !method.accessFlags.isConstructor();
    assert !method.accessFlags.isStatic();

    if (method.accessFlags.isAbstract()) {
      return false;
    }
    if (method.accessFlags.isNative()) {
      throw new Unimplemented("Native default interface methods are not yet supported.");
    }
    if (!method.accessFlags.isPublic()) {
      // NOTE: even though the class is allowed to have non-public interface methods
      // with code, for example private methods, all such methods we are aware of are
      // created by the compiler for stateful lambdas and they must be converted into
      // static methods by lambda desugaring by this time.
      throw new Unimplemented("Non public default interface methods are not yet supported.");
    }
    return true;
  }

  public boolean verifyKind(DerivedMethod method, SyntheticKindSelector kindSelector) {
    SyntheticKind kind = kindSelector.select(appView.getSyntheticItems().getNaming());
    assert method.getHolderKind().equals(kind);
    return true;
  }

  DexMethod emulatedInterfaceDispatchMethod(DerivedMethod method, DexType holder) {
    assert verifyKind(method, kinds -> kinds.EMULATED_INTERFACE_CLASS);
    DexProto newProto = appView.dexItemFactory().prependHolderToProto(method.getMethod());
    return appView.dexItemFactory().createMethod(holder, newProto, method.getName());
  }

  DexMethod emulatedInterfaceInterfaceMethod(DerivedMethod method) {
    assert method.getHolderKind() == null;
    return method.getMethod();
  }

  public static String getCompanionClassDescriptor(String descriptor) {
    return descriptor.substring(0, descriptor.length() - 1) + COMPANION_CLASS_NAME_SUFFIX + ";";
  }

  // Gets the companion class for the interface `type`.
  public static DexType getCompanionClassType(DexType type, DexItemFactory factory) {
    assert type.isClassType();
    String descriptor = type.descriptor.toString();
    String ccTypeDescriptor = getCompanionClassDescriptor(descriptor);
    return factory.createSynthesizedType(ccTypeDescriptor);
  }

  // Checks if `type` is a companion class.
  public static boolean isCompanionClassType(DexType type) {
    return type.descriptor.toString().endsWith(COMPANION_CLASS_NAME_SUFFIX + ";");
  }

  // Gets the interface class for a companion class `type`.
  DexType getInterfaceClassType(DexType type) {
    return getInterfaceClassType(type, appView.dexItemFactory());
  }

  // Gets the interface class for a companion class `type`.
  public static DexType getInterfaceClassType(DexType type, DexItemFactory factory) {
    assert isCompanionClassType(type);
    String descriptor = type.descriptor.toString();
    String interfaceTypeDescriptor =
        descriptor.substring(0, descriptor.length() - 1 - COMPANION_CLASS_NAME_SUFFIX.length())
            + ";";
    return factory.createType(interfaceTypeDescriptor);
  }

  // TODO(b/198273164): This should take the context class and not just a type.
  DexClasspathClass ensureEmulatedInterfaceMarkerInterface(DexType type) {
    return appView
        .getSyntheticItems()
        .ensureFixedClasspathClassFromType(
            kinds -> kinds.EMULATED_INTERFACE_MARKER_CLASS,
            type,
            appView,
            SyntheticClassBuilder::setInterface,
            ignored -> {});
  }

  DexClassAndMethod lookupMaximallySpecificIncludingSelf(
      DexClass initialResolutionHolder, DexClassAndMethod method) {
    assert method.getHolderType().isClassType();
    if (method.getHolder().isInterface()) {
      return method;
    }
    return appView
        .appInfoForDesugaring()
        .lookupMaximallySpecificMethod(initialResolutionHolder, method.getReference());
  }

  EmulatedDispatchMethodDescriptor getEmulatedDispatchDescriptor(
      DexClass initialResolutionHolder, DexClassAndMethod method) {
    if (method == null) {
      return null;
    }
    assert initialResolutionHolder != null;
    if (!requiresEmulatedDispatch(method)) {
      return null;
    }
    DexClassAndMethod maximallySpecificMethod =
        lookupMaximallySpecificIncludingSelf(initialResolutionHolder, method);
    if (maximallySpecificMethod == null) {
      return null;
    }
    return appView
        .options()
        .machineDesugaredLibrarySpecification
        .getEmulatedInterfaceEmulatedDispatchMethodDescriptor(
            maximallySpecificMethod.getReference());
  }

  private boolean requiresEmulatedDispatch(DexClassAndMethod method) {
    return method.isLibraryMethod()
        || isEmulatedInterface(method.getHolderType())
        || appView
            .options()
            .machineDesugaredLibrarySpecification
            .getEmulatedVirtualRetargetThroughEmulatedInterface()
            .containsKey(method.getReference());
  }

  DerivedMethod computeEmulatedInterfaceDispatchMethod(MethodResolutionResult resolutionResult) {
    EmulatedDispatchMethodDescriptor descriptor =
        getEmulatedDispatchDescriptor(
            resolutionResult.getInitialResolutionHolder(), resolutionResult.getResolutionPair());
    return descriptor == null ? null : descriptor.getEmulatedDispatchMethod();
  }

  DerivedMethod computeEmulatedInterfaceForwardingMethod(
      DexClass initialResolutionHolder, DexClassAndMethod method) {
    if (method == null) {
      return null;
    }
    DexMethod retarget =
        appView
            .options()
            .machineDesugaredLibrarySpecification
            .getEmulatedVirtualRetargetThroughEmulatedInterface()
            .get(method.getReference());
    if (retarget != null) {
      return new DerivedMethod(retarget);
    }
    EmulatedDispatchMethodDescriptor descriptor =
        getEmulatedDispatchDescriptor(initialResolutionHolder, method);
    return descriptor == null ? null : descriptor.getForwardingMethod();
  }

  DexMethod ensureEmulatedInterfaceForwardingMethod(DerivedMethod method) {
    if (method.getHolderKind() == null) {
      return method.getMethod();
    }
    assert verifyKind(method, kinds -> kinds.COMPANION_CLASS);
    DexClassAndMethod resolvedMethod =
        appView.appInfoForDesugaring().resolveMethod(method.getMethod(), true).getResolutionPair();
    return ensureDefaultAsMethodOfCompanionClassStub(resolvedMethod).getReference();
  }

  DexClassAndMethod ensureEmulatedInterfaceDispatchMethod(
      DerivedMethod emulatedDispatchMethod,
      ClasspathEmulatedInterfaceSynthesizerEventConsumer eventConsumer) {
    assert verifyKind(emulatedDispatchMethod, kinds -> kinds.EMULATED_INTERFACE_CLASS);
    DexClassAndMethod method =
        appView
            .appInfoForDesugaring()
            .resolveMethod(emulatedDispatchMethod.getMethod(), true)
            .getResolutionPair();
    assert verifyKind(emulatedDispatchMethod, kinds -> kinds.EMULATED_INTERFACE_CLASS);
    if (method.isProgramMethod()) {
      assert appView.options().isDesugaredLibraryCompilation();
      DexProgramClass emulatedInterface =
          appView
              .getSyntheticItems()
              .getExistingFixedClass(
                  kinds -> kinds.EMULATED_INTERFACE_CLASS,
                  method.asProgramMethod().getHolder(),
                  appView);
      DexMethod emulatedInterfaceMethod =
          emulatedInterfaceDispatchMethod(emulatedDispatchMethod, emulatedInterface.type);
      assert emulatedInterface.lookupProgramMethod(emulatedInterfaceMethod) != null;
      return emulatedInterface.lookupProgramMethod(emulatedInterfaceMethod);
    }
    // The holder is not used.
    DexMethod emulatedInterfaceMethod =
        emulatedInterfaceDispatchMethod(
            emulatedDispatchMethod, appView.dexItemFactory().objectType);
    return appView
        .getSyntheticItems()
        .ensureFixedClasspathClassMethod(
            emulatedInterfaceMethod.getName(),
            emulatedInterfaceMethod.getProto(),
            kinds -> kinds.EMULATED_INTERFACE_CLASS,
            method.getHolder().asClasspathOrLibraryClass(),
            appView,
            classBuilder -> {},
            eventConsumer::acceptClasspathEmulatedInterface,
            methodBuilder ->
                methodBuilder
                    .setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
                    .setCode(ignore -> ThrowNullCode.get()));
  }

  DexClassAndMethod ensureDefaultAsMethodOfCompanionClassStub(DexClassAndMethod method) {
    if (method.isProgramMethod()) {
      return ensureDefaultAsMethodOfProgramCompanionClassStub(method.asProgramMethod());
    }
    ClasspathOrLibraryClass context = method.getHolder().asClasspathOrLibraryClass();
    DexMethod companionMethodReference =
        defaultAsMethodOfCompanionClass(method.getReference(), appView.dexItemFactory());
    return ensureMethodOfClasspathCompanionClassStub(companionMethodReference, context, appView);
  }

  DexClassAndMethod ensureStaticAsMethodOfCompanionClassStub(
      DexClassAndMethod method, CfInstructionDesugaringEventConsumer eventConsumer) {
    if (method.isProgramMethod()) {
      return ensureStaticAsMethodOfProgramCompanionClassStub(
          method.asProgramMethod(), eventConsumer);
    } else {
      ClasspathOrLibraryClass context = method.getHolder().asClasspathOrLibraryClass();
      DexMethod companionMethodReference = staticAsMethodOfCompanionClass(method);
      return ensureMethodOfClasspathCompanionClassStub(companionMethodReference, context, appView);
    }
  }

  ProgramMethod ensureDefaultAsMethodOfProgramCompanionClassStub(ProgramMethod method) {
    DexEncodedMethod virtual = method.getDefinition();
    DexMethod companionMethod =
        defaultAsMethodOfCompanionClass(method.getReference(), appView.dexItemFactory());
    return InterfaceProcessor.ensureCompanionMethod(
        method.getHolder(),
        companionMethod.getName(),
        companionMethod.getProto(),
        appView,
        methodBuilder -> {
          MethodAccessFlags newFlags = method.getAccessFlags().copy();
          newFlags.promoteToStatic();
          methodBuilder
              .setAccessFlags(newFlags)
              .setGenericSignature(MethodTypeSignature.noSignature())
              // Will be traced by the enqueuer.
              .disableAndroidApiLevelCheck()
              .setAnnotations(
                  virtual
                      .annotations()
                      .methodParametersWithFakeThisArguments(appView.dexItemFactory()))
              .setParameterAnnotationsList(
                  virtual.getParameterAnnotations().withFakeThisParameter())
              .setCode(ignored -> InvalidCode.getInstance());
        },
        ignored -> {});
  }

  ProgramMethod ensurePrivateAsMethodOfProgramCompanionClassStub(ProgramMethod method) {
    DexMethod companionMethod =
        privateAsMethodOfCompanionClass(method.getReference(), appView.dexItemFactory());
    DexEncodedMethod definition = method.getDefinition();
    return InterfaceProcessor.ensureCompanionMethod(
        method.getHolder(),
        companionMethod.getName(),
        companionMethod.getProto(),
        appView,
        methodBuilder -> {
          MethodAccessFlags newFlags = definition.getAccessFlags().copy();
          assert newFlags.isPrivate();
          newFlags.promoteToPublic();
          newFlags.promoteToStatic();
          methodBuilder
              .setAccessFlags(newFlags)
              .setGenericSignature(definition.getGenericSignature())
              .setAnnotations(definition.annotations())
              // Will be traced by the enqueuer.
              .disableAndroidApiLevelCheck()
              // TODO(b/200938394): Should this not also be updating with a fake 'this'
              .setParameterAnnotationsList(definition.getParameterAnnotations())
              .setCode(ignored -> InvalidCode.getInstance());
        },
        ignored -> {});
  }

  // Represent a static interface method as a method of companion class.
  private DexMethod staticAsMethodOfCompanionClass(DexClassAndMethod method) {
    DexItemFactory dexItemFactory = appView.dexItemFactory();
    DexType companionClassType = getCompanionClassType(method.getHolderType(), dexItemFactory);
    DexMethod rewritten = method.getReference().withHolder(companionClassType, dexItemFactory);
    return rewritten;
  }

  private static DexMethod instanceAsMethodOfCompanionClass(
      DexMethod method, String prefix, DexItemFactory factory) {
    // Add an implicit argument to represent the receiver.
    DexType[] params = method.proto.parameters.values;
    DexType[] newParams = new DexType[params.length + 1];
    newParams[0] = method.holder;
    System.arraycopy(params, 0, newParams, 1, params.length);

    // Add prefix to avoid name conflicts.
    return factory.createMethod(
        getCompanionClassType(method.holder, factory),
        factory.createProto(method.proto.returnType, newParams),
        factory.createString(prefix + method.name.toString()));
  }

  // Represent a default interface method as a method of companion class.
  public static DexMethod defaultAsMethodOfCompanionClass(
      DexMethod method, DexItemFactory factory) {
    return instanceAsMethodOfCompanionClass(method, DEFAULT_METHOD_PREFIX, factory);
  }

  // Represent a private instance interface method as a method of companion class.
  static DexMethod privateAsMethodOfCompanionClass(DexMethod method, DexItemFactory factory) {
    // Add an implicit argument to represent the receiver.
    return instanceAsMethodOfCompanionClass(method, PRIVATE_METHOD_PREFIX, factory);
  }

  DexMethod privateAsMethodOfCompanionClass(DexClassAndMethod method) {
    return privateAsMethodOfCompanionClass(method.getReference(), appView.dexItemFactory());
  }

  private static DexClassAndMethod ensureMethodOfClasspathCompanionClassStub(
      DexMethod companionMethodReference, ClasspathOrLibraryClass context, AppView<?> appView) {
    return appView
        .getSyntheticItems()
        .ensureFixedClasspathClassMethod(
            companionMethodReference.getName(),
            companionMethodReference.getProto(),
            kinds -> kinds.COMPANION_CLASS,
            context,
            appView,
            classBuilder -> {},
            ignored -> {},
            methodBuilder ->
                methodBuilder
                    .setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
                    .setCode(ignore -> ThrowNullCode.get()));
  }

  ProgramMethod ensureStaticAsMethodOfProgramCompanionClassStub(
      ProgramMethod method, InterfaceMethodDesugaringBaseEventConsumer eventConsumer) {
    assert !method.getDefinition().isClassInitializer();
    if (method.getHolder().hasClassInitializer()) {
      ensureCompanionClassInitializesInterface(method.getHolder(), eventConsumer);
    }
    DexMethod companionMethodReference = staticAsMethodOfCompanionClass(method);
    DexEncodedMethod definition = method.getDefinition();
    return InterfaceProcessor.ensureCompanionMethod(
        method.getHolder(),
        companionMethodReference.getName(),
        companionMethodReference.getProto(),
        appView,
        methodBuilder -> {
          MethodAccessFlags newFlags = definition.getAccessFlags().copy();
          newFlags.promoteToPublic();
          methodBuilder
              .setAccessFlags(newFlags)
              .setGenericSignature(definition.getGenericSignature())
              .setAnnotations(definition.annotations())
              .setParameterAnnotationsList(definition.getParameterAnnotations())
              // Will be traced by the enqueuer.
              .disableAndroidApiLevelCheck()
              .setCode(ignored -> InvalidCode.getInstance());
        },
        companion -> eventConsumer.acceptCompanionMethod(method, companion));
  }

  public ProgramMethod ensureMethodOfProgramCompanionClassStub(
      ProgramMethod method, InterfaceMethodDesugaringBaseEventConsumer eventConsumer) {
    DexEncodedMethod definition = method.getDefinition();
    assert method.getHolder().isInterface();
    assert definition.isNonAbstractNonNativeMethod();
    assert definition.getCode() != null;
    assert !InvalidCode.isInvalidCode(definition.getCode());
    if (definition.isStatic()) {
      return ensureStaticAsMethodOfProgramCompanionClassStub(method, eventConsumer);
    }
    if (definition.isPrivate()) {
      return ensurePrivateAsMethodOfProgramCompanionClassStub(method);
    }
    return ensureDefaultAsMethodOfProgramCompanionClassStub(method);
  }

  private void ensureCompanionClassInitializesInterface(
      DexProgramClass iface, InterfaceMethodDesugaringBaseEventConsumer eventConsumer) {
    assert hasStaticMethodThatTriggersNonTrivialClassInitializer(iface);
    InterfaceProcessor.ensureCompanionMethod(
        iface,
        appView.dexItemFactory().classConstructorMethodName,
        appView.dexItemFactory().createProto(appView.dexItemFactory().voidType),
        appView,
        methodBuilder -> createCompanionClassInitializer(iface, methodBuilder),
        eventConsumer::acceptCompanionClassClinit);
  }

  private DexEncodedField ensureStaticClinitFieldToTriggerInterfaceInitialization(
      DexProgramClass iface) {
    DexEncodedField clinitField =
        findExistingStaticClinitFieldToTriggerInterfaceInitialization(iface);
    if (clinitField == null) {
      clinitField = createStaticClinitFieldToTriggerInterfaceInitialization(iface);
      iface.appendStaticField(clinitField);
    }
    return clinitField;
  }

  private boolean hasStaticMethodThatTriggersNonTrivialClassInitializer(DexProgramClass iface) {
    return iface.hasClassInitializer()
        && iface
            .getMethodCollection()
            .hasDirectMethods(method -> method.isStatic() && !method.isClassInitializer());
  }

  private DexEncodedField findExistingStaticClinitFieldToTriggerInterfaceInitialization(
      DexProgramClass iface) {
    // Don't select a field that has been marked dead, since we'll assert later that these fields
    // have been dead code eliminated.
    for (DexEncodedField field :
        iface.staticFields(field -> !field.isPrivate() && !field.getOptimizationInfo().isDead())) {
      return field;
    }
    return null;
  }

  private DexEncodedField createStaticClinitFieldToTriggerInterfaceInitialization(
      DexProgramClass iface) {
    DexItemFactory dexItemFactory = appView.dexItemFactory();
    DexField clinitFieldReference =
        dexItemFactory.createFreshFieldNameWithoutHolder(
            iface.getType(),
            dexItemFactory.intType,
            "$desugar$clinit",
            candidate -> iface.lookupField(candidate) == null);
    return DexEncodedField.syntheticBuilder()
        .setField(clinitFieldReference)
        .setAccessFlags(
            FieldAccessFlags.builder().setPackagePrivate().setStatic().setSynthetic().build())
        .setStaticValue(DexValueInt.DEFAULT)
        // The api level is computed when tracing.
        .disableAndroidApiLevelCheck()
        .build();
  }

  private void createCompanionClassInitializer(
      DexProgramClass iface, SyntheticMethodBuilder methodBuilder) {
    methodBuilder
        .setAccessFlags(
            MethodAccessFlags.builder().setConstructor().setPackagePrivate().setStatic().build())
        .setClassFileVersion(getInterfaceDesugaredCfVersion(iface.getInitialClassFileVersion()))
        .setCode(
            method -> {
              if (appView.canUseInitClass()) {
                return new CfCode(
                    method.holder,
                    1,
                    0,
                    ImmutableList.of(
                        new CfInitClass(iface.getType()),
                        new CfStackInstruction(Opcode.Pop),
                        new CfReturnVoid()));
              }
              DexEncodedField clinitField =
                  ensureStaticClinitFieldToTriggerInterfaceInitialization(iface);
              boolean isWide = clinitField.getType().isWideType();
              return new CfCode(
                  method.holder,
                  isWide ? 2 : 1,
                  0,
                  ImmutableList.of(
                      new CfStaticFieldRead(clinitField.getReference(), clinitField.getReference()),
                      isWide
                          ? new CfStackInstruction(Opcode.Pop2)
                          : new CfStackInstruction(Opcode.Pop),
                      new CfReturnVoid()));
            });
  }

  private Predicate<DexType> getShouldIgnoreFromReportsPredicate(AppView<?> appView) {
    DexItemFactory dexItemFactory = appView.dexItemFactory();
    InternalOptions options = appView.options();
    DexString companionClassNameDescriptorSuffix =
        dexItemFactory.createString(
            InterfaceDesugaringSyntheticHelper.COMPANION_CLASS_NAME_SUFFIX + ";");

    return type -> {
      DexString descriptor = type.getDescriptor();
      return appView.typeRewriter.hasRewrittenType(type, appView)
          || descriptor.endsWith(companionClassNameDescriptorSuffix)
          || isRewrittenEmulatedInterface(type)
          || options.machineDesugaredLibrarySpecification.isCustomConversionRewrittenType(type)
          || appView.getDontWarnConfiguration().matches(type);
    };
  }

  boolean shouldIgnoreFromReports(DexType missing) {
    return shouldIgnoreFromReportsPredicate.test(missing);
  }

  public void warnMissingInterface(
      DexClass classToDesugar, DexClass implementing, DexType missing) {
    // We use contains() on non hashed collection, but we know it's a 8 cases collection.
    // j$ interfaces won't be missing, they are in the desugared library.
    if (shouldIgnoreFromReports(missing)) {
      return;
    }
    appView.options().warningMissingInterfaceForDesugar(classToDesugar, implementing, missing);
  }
}
