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

import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotation.AnnotatedKind;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.FieldAccessInfo;
import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.shaking.Enqueuer.FieldAccessKind;
import com.android.tools.r8.shaking.Enqueuer.FieldAccessMetadata;
import com.android.tools.r8.shaking.GraphReporter.KeepReasonWitness;
import com.android.tools.r8.utils.Action;
import com.android.tools.r8.utils.InternalOptions;
import java.util.Collection;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

public abstract class EnqueuerWorklist {

  public abstract static class EnqueuerAction {
    public abstract void run(Enqueuer enqueuer);
  }

  static class AssertAction extends EnqueuerAction {
    private final Action assertion;

    AssertAction(Action assertion) {
      this.assertion = assertion;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      assertion.execute();
    }
  }

  static class MarkReachableDirectAction extends EnqueuerAction {
    private final DexMethod target;
    // TODO(b/175854431): Avoid pushing context on worklist.
    private final ProgramDefinition context;
    private final KeepReason reason;

    MarkReachableDirectAction(DexMethod target, ProgramDefinition context, KeepReason reason) {
      this.target = target;
      this.context = context;
      this.reason = reason;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.markNonStaticDirectMethodAsReachable(target, context, reason);
    }
  }

  static class MarkReachableSuperAction extends EnqueuerAction {
    private final DexMethod target;
    // TODO(b/175854431): Avoid pushing context on worklist.
    private final ProgramMethod context;

    public MarkReachableSuperAction(DexMethod target, ProgramMethod context) {
      this.target = target;
      this.context = context;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.markSuperMethodAsReachable(target, context);
    }
  }

  static class MarkFieldAsReachableAction extends EnqueuerAction {
    private final ProgramField field;
    // TODO(b/175854431): Avoid pushing context on worklist.
    private final ProgramDefinition context;
    private final KeepReason reason;

    public MarkFieldAsReachableAction(
        ProgramField field, ProgramDefinition context, KeepReason reason) {
      this.field = field;
      this.context = context;
      this.reason = reason;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.markFieldAsReachable(field, context, reason);
    }
  }

  static class MarkInstantiatedAction extends EnqueuerAction {
    private final DexProgramClass target;
    // TODO(b/175854431): Avoid pushing context on worklist.
    private final ProgramMethod context;
    private final InstantiationReason instantiationReason;
    private final KeepReason keepReason;

    public MarkInstantiatedAction(
        DexProgramClass target,
        ProgramMethod context,
        InstantiationReason instantiationReason,
        KeepReason keepReason) {
      this.target = target;
      this.context = context;
      this.instantiationReason = instantiationReason;
      this.keepReason = keepReason;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.processNewlyInstantiatedClass(target, context, instantiationReason, keepReason);
    }
  }

  static class MarkAnnotationInstantiatedAction extends EnqueuerAction {
    private final DexProgramClass target;
    private final KeepReasonWitness reason;

    public MarkAnnotationInstantiatedAction(DexProgramClass target, KeepReasonWitness reason) {
      this.target = target;
      this.reason = reason;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.markAnnotationAsInstantiated(target, reason);
    }
  }

  static class MarkInterfaceInstantiatedAction extends EnqueuerAction {
    private final DexProgramClass target;
    private final KeepReasonWitness reason;

    public MarkInterfaceInstantiatedAction(DexProgramClass target, KeepReasonWitness reason) {
      this.target = target;
      this.reason = reason;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.markInterfaceAsInstantiated(target, reason);
    }
  }

  static class MarkMethodLiveAction extends EnqueuerAction {
    private final ProgramMethod method;
    // TODO(b/175854431): Avoid pushing context on worklist.
    private final ProgramDefinition context;

    public MarkMethodLiveAction(ProgramMethod method, ProgramDefinition context) {
      this.method = method;
      this.context = context;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.markMethodAsLive(method, context);
    }
  }

  static class MarkMethodKeptAction extends EnqueuerAction {
    private final ProgramMethod target;
    private final KeepReason reason;

    public MarkMethodKeptAction(ProgramMethod target, KeepReason reason) {
      this.target = target;
      this.reason = reason;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.markMethodAsKept(target, reason);
    }
  }

  static class MarkFieldKeptAction extends EnqueuerAction {
    private final ProgramField field;
    private final KeepReasonWitness witness;

    public MarkFieldKeptAction(ProgramField field, KeepReasonWitness witness) {
      this.field = field;
      this.witness = witness;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.markFieldAsKept(field, witness);
    }
  }

  static class TraceAnnotationAction extends EnqueuerAction {
    private final ProgramDefinition annotatedItem;
    private final DexAnnotation annotation;
    private final AnnotatedKind annotatedKind;

    TraceAnnotationAction(
        ProgramDefinition annotatedItem, DexAnnotation annotation, AnnotatedKind annotatedKind) {
      this.annotatedItem = annotatedItem;
      this.annotation = annotation;
      this.annotatedKind = annotatedKind;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.processAnnotation(annotatedItem, annotation, annotatedKind);
    }
  }

  static class TraceCodeAction extends EnqueuerAction {
    private final ProgramMethod method;

    TraceCodeAction(ProgramMethod method) {
      this.method = method;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.traceCode(method);
    }
  }

  static class TraceConstClassAction extends EnqueuerAction {
    private final DexType type;
    // TODO(b/175854431): Avoid pushing context on worklist.
    private final ProgramMethod context;
    private final boolean ignoreCompatRules;

    TraceConstClassAction(DexType type, ProgramMethod context, boolean ignoreCompatRules) {
      this.type = type;
      this.context = context;
      this.ignoreCompatRules = ignoreCompatRules;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.traceConstClass(type, context, null, ignoreCompatRules);
    }
  }

  static class TraceDirectAndIndirectClassInitializers extends EnqueuerAction {
    private final DexProgramClass clazz;

    TraceDirectAndIndirectClassInitializers(DexProgramClass clazz) {
      this.clazz = clazz;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.markDirectAndIndirectClassInitializersAsLive(clazz);
    }
  }

  static class TraceInvokeDirectAction extends EnqueuerAction {
    private final DexMethod invokedMethod;
    // TODO(b/175854431): Avoid pushing context on worklist.
    private final ProgramMethod context;

    TraceInvokeDirectAction(DexMethod invokedMethod, ProgramMethod context) {
      this.invokedMethod = invokedMethod;
      this.context = context;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.traceInvokeDirect(invokedMethod, context);
    }
  }

  static class TraceInvokeStaticAction extends EnqueuerAction {
    private final DexMethod invokedMethod;
    // TODO(b/175854431): Avoid pushing context on worklist.
    private final ProgramMethod context;

    TraceInvokeStaticAction(DexMethod invokedMethod, ProgramMethod context) {
      this.invokedMethod = invokedMethod;
      this.context = context;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.traceInvokeStatic(invokedMethod, context);
    }
  }

  static class TraceMethodDefinitionExcludingCodeAction extends EnqueuerAction {
    private final ProgramMethod method;

    TraceMethodDefinitionExcludingCodeAction(ProgramMethod method) {
      this.method = method;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.traceMethodDefinitionExcludingCode(method);
    }
  }

  static class TraceNewInstanceAction extends EnqueuerAction {
    private final DexType type;
    // TODO(b/175854431): Avoid pushing context on worklist.
    private final ProgramMethod context;

    TraceNewInstanceAction(DexType type, ProgramMethod context) {
      this.type = type;
      this.context = context;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.traceNewInstance(type, context);
    }
  }

  static class TraceReflectiveFieldAccessAction extends EnqueuerAction {
    private final ProgramField field;
    private final ProgramMethod context;
    private final FieldAccessKind kind;

    TraceReflectiveFieldAccessAction(ProgramField field, ProgramMethod context) {
      this(field, context, null);
    }

    TraceReflectiveFieldAccessAction(
        ProgramField field, ProgramMethod context, FieldAccessKind kind) {
      this.field = field;
      this.context = context;
      this.kind = kind;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      if (kind != null) {
        if (kind.isRead()) {
          enqueuer.traceReflectiveFieldRead(field, context);
        } else {
          enqueuer.traceReflectiveFieldWrite(field, context);
        }
      } else {
        enqueuer.traceReflectiveFieldAccess(field, context);
      }
    }
  }

  static class TraceTypeReferenceAction extends EnqueuerAction {
    private final DexProgramClass clazz;
    private final KeepReason reason;

    TraceTypeReferenceAction(DexProgramClass clazz, KeepReason reason) {
      this.clazz = clazz;
      this.reason = reason;
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.markTypeAsLive(clazz, reason);
    }
  }

  abstract static class TraceFieldAccessAction extends EnqueuerAction {
    protected final DexField field;
    // TODO(b/175854431): Avoid pushing context on worklist.
    protected final ProgramMethod context;
    protected final FieldAccessMetadata metadata;

    TraceFieldAccessAction(DexField field, ProgramMethod context, FieldAccessMetadata metadata) {
      this.field = field;
      this.context = context;
      this.metadata = metadata;
    }

    protected boolean baseEquals(TraceFieldAccessAction action) {
      return field == action.field
          && context.isStructurallyEqualTo(action.context)
          && metadata.equals(action.metadata);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null || getClass() != obj.getClass()) {
        return false;
      }
      TraceFieldAccessAction action = (TraceFieldAccessAction) obj;
      return baseEquals(action);
    }

    @Override
    public int hashCode() {
      return Objects.hash(field, context.getReference(), metadata);
    }
  }

  static class TraceInstanceFieldReadAction extends TraceFieldAccessAction {

    TraceInstanceFieldReadAction(
        DexField field, ProgramMethod context, FieldAccessMetadata metadata) {
      super(field, context, metadata);
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.traceInstanceFieldRead(field, context, metadata);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null || getClass() != obj.getClass()) {
        return false;
      }
      TraceInstanceFieldReadAction action = (TraceInstanceFieldReadAction) obj;
      return baseEquals(action);
    }

    @Override
    public int hashCode() {
      return Objects.hash(field, context.getReference(), metadata);
    }
  }

  static class TraceInstanceFieldWriteAction extends TraceFieldAccessAction {

    TraceInstanceFieldWriteAction(
        DexField field, ProgramMethod context, FieldAccessMetadata metadata) {
      super(field, context, metadata);
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.traceInstanceFieldWrite(field, context, metadata);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null || getClass() != obj.getClass()) {
        return false;
      }
      TraceInstanceFieldWriteAction action = (TraceInstanceFieldWriteAction) obj;
      return baseEquals(action);
    }

    @Override
    public int hashCode() {
      return Objects.hash(field, context.getReference(), metadata);
    }
  }

  static class TraceStaticFieldReadAction extends TraceFieldAccessAction {

    TraceStaticFieldReadAction(
        DexField field, ProgramMethod context, FieldAccessMetadata metadata) {
      super(field, context, metadata);
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.traceStaticFieldRead(field, context, metadata);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null || getClass() != obj.getClass()) {
        return false;
      }
      TraceStaticFieldReadAction action = (TraceStaticFieldReadAction) obj;
      return baseEquals(action);
    }
  }

  static class TraceStaticFieldWriteAction extends TraceFieldAccessAction {

    TraceStaticFieldWriteAction(
        DexField field, ProgramMethod context, FieldAccessMetadata metadata) {
      super(field, context, metadata);
    }

    @Override
    public void run(Enqueuer enqueuer) {
      enqueuer.traceStaticFieldWrite(field, context, metadata);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null || getClass() != obj.getClass()) {
        return false;
      }
      TraceStaticFieldWriteAction action = (TraceStaticFieldWriteAction) obj;
      return baseEquals(action);
    }

    @Override
    public int hashCode() {
      return Objects.hash(field, context.getReference(), metadata);
    }
  }

  final Enqueuer enqueuer;
  final Queue<EnqueuerAction> queue;

  public static EnqueuerWorklist createWorklist(Enqueuer enqueuer) {
    return new PushableEnqueuerWorkList(enqueuer);
  }

  private EnqueuerWorklist(Enqueuer enqueuer, Queue<EnqueuerAction> queue) {
    this.enqueuer = enqueuer;
    this.queue = queue;
  }

  public boolean isEmpty() {
    return queue.isEmpty();
  }

  public EnqueuerAction poll() {
    return queue.poll();
  }

  abstract EnqueuerWorklist nonPushable();

  final void enqueueAll(Collection<? extends EnqueuerAction> actions) {
    actions.forEach(this::enqueue);
  }

  abstract void enqueue(EnqueuerAction action);

  abstract boolean enqueueAssertAction(Action assertion);

  abstract void enqueueMarkReachableDirectAction(
      DexMethod method, ProgramDefinition context, KeepReason reason);

  abstract void enqueueMarkReachableSuperAction(DexMethod method, ProgramMethod from);

  public abstract void enqueueMarkFieldAsReachableAction(
      ProgramField field, ProgramDefinition context, KeepReason reason);

  public abstract void enqueueMarkInstantiatedAction(
      DexProgramClass clazz,
      ProgramMethod context,
      InstantiationReason instantiationReason,
      KeepReason keepReason);

  abstract void enqueueMarkAnnotationInstantiatedAction(
      DexProgramClass clazz, KeepReasonWitness reason);

  abstract void enqueueMarkInterfaceInstantiatedAction(
      DexProgramClass clazz, KeepReasonWitness reason);

  abstract boolean enqueueMarkMethodLiveAction(
      ProgramMethod method, ProgramDefinition context, KeepReason reason);

  abstract void enqueueMarkMethodKeptAction(ProgramMethod method, KeepReason reason);

  abstract void enqueueMarkFieldKeptAction(ProgramField field, KeepReasonWitness witness);

  abstract void enqueueTraceAnnotationAction(
      ProgramDefinition annotatedItem, DexAnnotation annotation, AnnotatedKind annotatedKind);

  public abstract void enqueueTraceCodeAction(ProgramMethod method);

  public abstract void enqueueTraceConstClassAction(
      DexType type, ProgramMethod context, boolean ignoreCompatRules);

  public abstract void enqueueTraceDirectAndIndirectClassInitializers(DexProgramClass clazz);

  public abstract void enqueueTraceInvokeDirectAction(
      DexMethod invokedMethod, ProgramMethod context);

  public abstract void enqueueTraceInvokeStaticAction(
      DexMethod invokedMethod, ProgramMethod context);

  public abstract void enqueueTraceNewInstanceAction(DexType type, ProgramMethod context);

  public abstract void enqueueTraceReflectiveFieldAccessAction(
      ProgramField field, ProgramMethod context);

  public abstract void enqueueTraceReflectiveFieldReadAction(
      ProgramField field, ProgramMethod context);

  public abstract void enqueueTraceReflectiveFieldWriteAction(
      ProgramField field, ProgramMethod context);

  public abstract void enqueueTraceStaticFieldRead(DexField field, ProgramMethod context);

  public abstract void enqueueTraceTypeReferenceAction(DexProgramClass clazz, KeepReason reason);

  static class PushableEnqueuerWorkList extends EnqueuerWorklist {

    PushableEnqueuerWorkList(Enqueuer enqueuer) {
      super(enqueuer, new ConcurrentLinkedQueue<>());
    }

    @Override
    EnqueuerWorklist nonPushable() {
      return new NonPushableEnqueuerWorklist(this);
    }

    @Override
    void enqueue(EnqueuerAction action) {
      queue.add(action);
    }

    @Override
    boolean enqueueAssertAction(Action assertion) {
      if (InternalOptions.assertionsEnabled()) {
        queue.add(new AssertAction(assertion));
      }
      return true;
    }

    @Override
    void enqueueMarkReachableDirectAction(
        DexMethod method, ProgramDefinition context, KeepReason reason) {
      queue.add(new MarkReachableDirectAction(method, context, reason));
    }

    @Override
    void enqueueMarkReachableSuperAction(DexMethod method, ProgramMethod from) {
      queue.add(new MarkReachableSuperAction(method, from));
    }

    @Override
    public void enqueueMarkFieldAsReachableAction(
        ProgramField field, ProgramDefinition context, KeepReason reason) {
      queue.add(new MarkFieldAsReachableAction(field, context, reason));
    }

    // TODO(b/142378367): Context is the containing method that is cause of the instantiation.
    // Consider updating call sites with the context information to increase precision where
    // possible.
    @Override
    public void enqueueMarkInstantiatedAction(
        DexProgramClass clazz,
        ProgramMethod context,
        InstantiationReason instantiationReason,
        KeepReason keepReason) {
      assert !clazz.isAnnotation();
      assert !clazz.isInterface();
      queue.add(new MarkInstantiatedAction(clazz, context, instantiationReason, keepReason));
    }

    @Override
    void enqueueMarkAnnotationInstantiatedAction(DexProgramClass clazz, KeepReasonWitness reason) {
      assert clazz.isAnnotation();
      assert clazz.isInterface();
      queue.add(new MarkAnnotationInstantiatedAction(clazz, reason));
    }

    @Override
    void enqueueMarkInterfaceInstantiatedAction(DexProgramClass clazz, KeepReasonWitness reason) {
      assert !clazz.isAnnotation();
      assert clazz.isInterface();
      queue.add(new MarkInterfaceInstantiatedAction(clazz, reason));
    }

    @Override
    boolean enqueueMarkMethodLiveAction(
        ProgramMethod method, ProgramDefinition context, KeepReason reason) {
      if (enqueuer.addLiveMethod(method, reason)) {
        queue.add(new MarkMethodLiveAction(method, context));
        if (!enqueuer.isMethodTargeted(method)) {
          queue.add(new TraceMethodDefinitionExcludingCodeAction(method));
        }
        return true;
      }
      return false;
    }

    @Override
    void enqueueMarkMethodKeptAction(ProgramMethod method, KeepReason reason) {
      queue.add(new MarkMethodKeptAction(method, reason));
    }

    @Override
    void enqueueMarkFieldKeptAction(ProgramField field, KeepReasonWitness witness) {
      queue.add(new MarkFieldKeptAction(field, witness));
    }

    @Override
    void enqueueTraceAnnotationAction(
        ProgramDefinition annotatedItem, DexAnnotation annotation, AnnotatedKind annotatedKind) {
      queue.add(new TraceAnnotationAction(annotatedItem, annotation, annotatedKind));
    }

    @Override
    public void enqueueTraceCodeAction(ProgramMethod method) {
      queue.add(new TraceCodeAction(method));
    }

    @Override
    public void enqueueTraceConstClassAction(
        DexType type, ProgramMethod context, boolean ignoreCompatRules) {
      queue.add(new TraceConstClassAction(type, context, ignoreCompatRules));
    }

    @Override
    public void enqueueTraceDirectAndIndirectClassInitializers(DexProgramClass clazz) {
      queue.add(new TraceDirectAndIndirectClassInitializers(clazz));
    }

    @Override
    public void enqueueTraceInvokeDirectAction(DexMethod invokedMethod, ProgramMethod context) {
      queue.add(new TraceInvokeDirectAction(invokedMethod, context));
    }

    @Override
    public void enqueueTraceInvokeStaticAction(DexMethod invokedMethod, ProgramMethod context) {
      queue.add(new TraceInvokeStaticAction(invokedMethod, context));
    }

    @Override
    public void enqueueTraceNewInstanceAction(DexType type, ProgramMethod context) {
      queue.add(new TraceNewInstanceAction(type, context));
    }

    @Override
    public void enqueueTraceReflectiveFieldAccessAction(ProgramField field, ProgramMethod context) {
      FieldAccessInfo info = enqueuer.getFieldAccessInfoCollection().get(field.getReference());
      if (info == null || !info.hasReflectiveAccess()) {
        queue.add(new TraceReflectiveFieldAccessAction(field, context));
      }
    }

    @Override
    public void enqueueTraceReflectiveFieldReadAction(ProgramField field, ProgramMethod context) {
      FieldAccessInfo info = enqueuer.getFieldAccessInfoCollection().get(field.getReference());
      if (info == null || !info.hasReflectiveRead()) {
        queue.add(
            new TraceReflectiveFieldAccessAction(
                field,
                context,
                field.getAccessFlags().isStatic()
                    ? FieldAccessKind.STATIC_READ
                    : FieldAccessKind.INSTANCE_READ));
      }
    }

    @Override
    public void enqueueTraceReflectiveFieldWriteAction(ProgramField field, ProgramMethod context) {
      FieldAccessInfo info = enqueuer.getFieldAccessInfoCollection().get(field.getReference());
      if (info == null || !info.hasReflectiveWrite()) {
        queue.add(
            new TraceReflectiveFieldAccessAction(
                field,
                context,
                field.getAccessFlags().isStatic()
                    ? FieldAccessKind.STATIC_WRITE
                    : FieldAccessKind.INSTANCE_WRITE));
      }
    }

    @Override
    public void enqueueTraceStaticFieldRead(DexField field, ProgramMethod context) {
      queue.add(new TraceStaticFieldReadAction(field, context, FieldAccessMetadata.DEFAULT));
    }

    @Override
    public void enqueueTraceTypeReferenceAction(DexProgramClass clazz, KeepReason reason) {
      queue.add(new TraceTypeReferenceAction(clazz, reason));
    }
  }

  public static class NonPushableEnqueuerWorklist extends EnqueuerWorklist {

    private NonPushableEnqueuerWorklist(PushableEnqueuerWorkList workList) {
      super(workList.enqueuer, workList.queue);
    }

    @Override
    EnqueuerWorklist nonPushable() {
      return this;
    }

    @Override
    void enqueue(EnqueuerAction action) {
      throw attemptToEnqueue();
    }

    private Unreachable attemptToEnqueue() {
      throw new Unreachable("Attempt to enqueue an action in a non pushable enqueuer work list.");
    }

    @Override
    boolean enqueueAssertAction(Action assertion) {
      assertion.execute();
      return true;
    }

    @Override
    void enqueueMarkReachableDirectAction(
        DexMethod method, ProgramDefinition context, KeepReason reason) {
      throw attemptToEnqueue();
    }

    @Override
    void enqueueMarkReachableSuperAction(DexMethod method, ProgramMethod from) {

      throw attemptToEnqueue();
    }

    @Override
    public void enqueueMarkFieldAsReachableAction(
        ProgramField field, ProgramDefinition context, KeepReason reason) {

      throw attemptToEnqueue();
    }

    @Override
    public void enqueueMarkInstantiatedAction(
        DexProgramClass clazz,
        ProgramMethod context,
        InstantiationReason instantiationReason,
        KeepReason keepReason) {

      throw attemptToEnqueue();
    }

    @Override
    void enqueueMarkAnnotationInstantiatedAction(DexProgramClass clazz, KeepReasonWitness reason) {

      throw attemptToEnqueue();
    }

    @Override
    void enqueueMarkInterfaceInstantiatedAction(DexProgramClass clazz, KeepReasonWitness reason) {

      throw attemptToEnqueue();
    }

    @Override
    boolean enqueueMarkMethodLiveAction(
        ProgramMethod method, ProgramDefinition context, KeepReason reason) {
      if (!enqueuer.addLiveMethod(method, reason)) {
        return false;
      }
      throw attemptToEnqueue();
    }

    @Override
    void enqueueMarkMethodKeptAction(ProgramMethod method, KeepReason reason) {

      throw attemptToEnqueue();
    }

    @Override
    void enqueueMarkFieldKeptAction(ProgramField field, KeepReasonWitness witness) {

      throw attemptToEnqueue();
    }

    @Override
    void enqueueTraceAnnotationAction(
        ProgramDefinition annotatedItem, DexAnnotation annotation, AnnotatedKind annotatedKind) {
      throw attemptToEnqueue();
    }

    @Override
    public void enqueueTraceCodeAction(ProgramMethod method) {

      throw attemptToEnqueue();
    }

    @Override
    public void enqueueTraceConstClassAction(
        DexType type, ProgramMethod context, boolean ignoreCompatRules) {
      throw attemptToEnqueue();
    }

    @Override
    public void enqueueTraceDirectAndIndirectClassInitializers(DexProgramClass clazz) {
      throw attemptToEnqueue();
    }

    @Override
    public void enqueueTraceInvokeDirectAction(DexMethod invokedMethod, ProgramMethod context) {
      throw attemptToEnqueue();
    }

    @Override
    public void enqueueTraceInvokeStaticAction(DexMethod invokedMethod, ProgramMethod context) {
      throw attemptToEnqueue();
    }

    @Override
    public void enqueueTraceNewInstanceAction(DexType type, ProgramMethod context) {
      throw attemptToEnqueue();
    }

    @Override
    public void enqueueTraceReflectiveFieldAccessAction(ProgramField field, ProgramMethod context) {
      throw attemptToEnqueue();
    }

    @Override
    public void enqueueTraceReflectiveFieldReadAction(ProgramField field, ProgramMethod context) {
      throw attemptToEnqueue();
    }

    @Override
    public void enqueueTraceReflectiveFieldWriteAction(ProgramField field, ProgramMethod context) {
      throw attemptToEnqueue();
    }

    @Override
    public void enqueueTraceStaticFieldRead(DexField field, ProgramMethod context) {
      throw attemptToEnqueue();
    }

    @Override
    public void enqueueTraceTypeReferenceAction(DexProgramClass clazz, KeepReason reason) {
      throw attemptToEnqueue();
    }
  }
}
