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

import com.android.tools.r8.cf.code.CfArithmeticBinop;
import com.android.tools.r8.cf.code.CfArrayLength;
import com.android.tools.r8.cf.code.CfArrayLoad;
import com.android.tools.r8.cf.code.CfArrayStore;
import com.android.tools.r8.cf.code.CfCheckCast;
import com.android.tools.r8.cf.code.CfCmp;
import com.android.tools.r8.cf.code.CfConstClass;
import com.android.tools.r8.cf.code.CfConstDynamic;
import com.android.tools.r8.cf.code.CfConstMethodHandle;
import com.android.tools.r8.cf.code.CfConstMethodType;
import com.android.tools.r8.cf.code.CfConstNull;
import com.android.tools.r8.cf.code.CfConstNumber;
import com.android.tools.r8.cf.code.CfConstString;
import com.android.tools.r8.cf.code.CfDexItemBasedConstString;
import com.android.tools.r8.cf.code.CfFieldInstruction;
import com.android.tools.r8.cf.code.CfFrame;
import com.android.tools.r8.cf.code.CfGoto;
import com.android.tools.r8.cf.code.CfIf;
import com.android.tools.r8.cf.code.CfIfCmp;
import com.android.tools.r8.cf.code.CfIinc;
import com.android.tools.r8.cf.code.CfInitClass;
import com.android.tools.r8.cf.code.CfInstanceFieldRead;
import com.android.tools.r8.cf.code.CfInstanceFieldWrite;
import com.android.tools.r8.cf.code.CfInstanceOf;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.cf.code.CfInvokeDynamic;
import com.android.tools.r8.cf.code.CfJsrRet;
import com.android.tools.r8.cf.code.CfLabel;
import com.android.tools.r8.cf.code.CfLoad;
import com.android.tools.r8.cf.code.CfLogicalBinop;
import com.android.tools.r8.cf.code.CfMonitor;
import com.android.tools.r8.cf.code.CfMultiANewArray;
import com.android.tools.r8.cf.code.CfNeg;
import com.android.tools.r8.cf.code.CfNew;
import com.android.tools.r8.cf.code.CfNewArray;
import com.android.tools.r8.cf.code.CfNewUnboxedEnum;
import com.android.tools.r8.cf.code.CfNop;
import com.android.tools.r8.cf.code.CfNumberConversion;
import com.android.tools.r8.cf.code.CfPosition;
import com.android.tools.r8.cf.code.CfRecordFieldValues;
import com.android.tools.r8.cf.code.CfReturn;
import com.android.tools.r8.cf.code.CfReturnVoid;
import com.android.tools.r8.cf.code.CfStackInstruction;
import com.android.tools.r8.cf.code.CfStaticFieldRead;
import com.android.tools.r8.cf.code.CfStaticFieldWrite;
import com.android.tools.r8.cf.code.CfStore;
import com.android.tools.r8.cf.code.CfSwitch;
import com.android.tools.r8.cf.code.CfSwitch.Kind;
import com.android.tools.r8.cf.code.CfThrow;
import com.android.tools.r8.cf.code.CfTryCatch;
import com.android.tools.r8.cf.code.frame.FrameType;
import com.android.tools.r8.cf.code.frame.PreciseFrameType;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.CfCode.LocalVariableInfo;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexCallSite;
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.DexMethodHandle;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.MemberType;
import com.android.tools.r8.ir.code.Monitor;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.DescriptorUtils;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import java.util.stream.Collectors;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.util.Printer;

/**
 * Utility to print CF code and instructions.
 *
 * <p>This implementation prints the code formatted according to the Jasmin syntax.
 */
public class CfPrinter {

  private static final boolean PRINT_INSTRUCTION_INDEX = true;
  private static final boolean PRINT_INLINE_LOCALS = true;

  private final String indent;

  // Sorted list of labels.
  private final List<CfLabel> sortedLabels;
  // Map from label to its sorted-order index.
  private final Reference2IntMap<CfLabel> labelToIndex;
  // Map from sorted-order label index to the locals live at that label.
  private final List<List<LocalVariableInfo>> localsAtLabel;

  private final StringBuilder builder = new StringBuilder();
  private final ClassNameMapper mapper;

  private int nextInstructionIndex = 0;
  private final int instructionIndexSpace;

  /** Entry for printing single instructions without global knowledge (eg, label numbers). */
  public CfPrinter() {
    indent = "";
    labelToIndex = null;
    mapper = null;
    instructionIndexSpace = 0;

    sortedLabels = Collections.emptyList();
    localsAtLabel = Collections.emptyList();
  }

  /** Entry for printing a complete code object. */
  public CfPrinter(CfCode code) {
    this(code, null, null);
  }

  /** Entry for printing a complete method object. */
  public CfPrinter(CfCode code, DexEncodedMethod method, ClassNameMapper mapper) {
    this.mapper = mapper;
    indent = "  ";
    instructionIndexSpace = ("" + code.getInstructions().size()).length();
    labelToIndex = new Reference2IntOpenHashMap<>();
    sortedLabels = new ArrayList<>();
    for (CfInstruction instruction : code.getInstructions()) {
      if (instruction instanceof CfLabel) {
        labelToIndex.put((CfLabel) instruction, sortedLabels.size());
        sortedLabels.add((CfLabel) instruction);
      }
    }
    if (method != null) {
      builder.append(".method ");
      appendMethod(method.getReference());
      newline();
    }
    builder.append(".limit stack ").append(code.getMaxStack());
    newline();
    builder.append(".limit locals ").append(code.getMaxLocals());

    List<LocalVariableInfo> localVariables = getSortedLocalVariables(code);
    localsAtLabel = computeLocalsAtLabels(localVariables);

    for (LocalVariableInfo local : localVariables) {
      DebugLocalInfo info = local.getLocal();
      newline();
      builder
          .append(".var ")
          .append(local.getIndex())
          .append(" is ")
          .append(info.name)
          .append(" ")
          .append(info.type.toDescriptorString())
          .append(" from ")
          .append(getLabel(local.getStart()))
          .append(" to ")
          .append(getLabel(local.getEnd()));
      if (info.signature != null) {
        appendComment(info.signature.toString());
      }
    }
    for (CfTryCatch tryCatch : code.getTryCatchRanges()) {
      for (int i = 0; i < tryCatch.guards.size(); i++) {
        newline();
        DexType guard = tryCatch.guards.get(i);
        assert guard != null;
        builder
            .append(".catch ")
            .append(guard.getInternalName()) // Do we wan't to write 'all' here?
            .append(" from ")
            .append(getLabel(tryCatch.start))
            .append(" to ")
            .append(getLabel(tryCatch.end))
            .append(" using ")
            .append(getLabel(tryCatch.targets.get(i)));
      }
    }
    for (CfInstruction instruction : code.getInstructions()) {
      instruction.print(this);
    }
    newline();
    if (method != null) {
      builder.append(".end method");
      newline();
    }
  }

  private List<List<LocalVariableInfo>> computeLocalsAtLabels(
      List<LocalVariableInfo> localVariables) {
    if (!PRINT_INLINE_LOCALS) {
      return null;
    }
    List<List<LocalVariableInfo>> localsAtLabel = new ArrayList<>(sortedLabels.size());
    Set<LocalVariableInfo> openLocals = new HashSet<>();
    ListIterator<LocalVariableInfo> nextLocalVariableEntry = localVariables.listIterator();
    for (CfLabel orderedLabel : sortedLabels) {
      int thisIndex = labelToIndex.getInt(orderedLabel);
      openLocals.removeIf(o -> labelToIndex.getInt(o.getEnd()) <= thisIndex);
      while (nextLocalVariableEntry.hasNext()) {
        LocalVariableInfo next = nextLocalVariableEntry.next();
        int startIndex = labelToIndex.getInt(next.getStart());
        int endIndex = labelToIndex.getInt(next.getEnd());
        if (startIndex <= thisIndex) {
          if (thisIndex < endIndex) {
            openLocals.add(next);
          }
        } else {
          nextLocalVariableEntry.previous();
          break;
        }
      }
      ArrayList<LocalVariableInfo> locals = new ArrayList<>(openLocals);
      locals.sort((a, b) -> Integer.compare(a.getIndex(), b.getIndex()));
      localsAtLabel.add(locals);
    }
    return localsAtLabel;
  }

  private List<LocalVariableInfo> getSortedLocalVariables(CfCode code) {
    List<LocalVariableInfo> localVariables = new ArrayList<>(code.getLocalVariables());
    localVariables.sort(
        (a, b) -> {
          // Start with locals starting early.
          int first =
              Integer.compare(labelToIndex.getInt(a.getStart()), labelToIndex.getInt(b.getStart()));
          if (first != 0) {
            return first;
          }
          // Then locals with longer scope (ie, reverse order).
          int second =
              Integer.compare(labelToIndex.getInt(b.getEnd()), labelToIndex.getInt(a.getEnd()));
          if (second != 0) {
            return second;
          }
          // Finally, locals with smallest index.
          return Integer.compare(a.getIndex(), b.getIndex());
        });
    return localVariables;
  }

  private void print(String name) {
    indent();
    builder.append(name);
  }

  public void print(CfRecordFieldValues recordFieldValues) {
    String recordType =
        recordFieldValues.getFields().length == 0
            ? "empty"
            : recordFieldValues.getFields()[0].holder.toString();
    print("record_field_values(" + recordType + ")");
  }

  public void print(CfNop nop) {
    print("nop");
  }

  public void print(CfStackInstruction instruction) {
    switch (instruction.getOpcode()) {
      case Pop:
        print("pop");
        return;
      case Pop2:
        print("pop2");
        return;
      case Dup:
        print("dup");
        return;
      case DupX1:
        print("dup_x1");
        return;
      case DupX2:
        print("dup_x2");
        return;
      case Dup2:
        print("dup2");
        return;
      case Dup2X1:
        print("dup2_x1");
        return;
      case Dup2X2:
        print("dup2_x2");
        return;
      case Swap:
        print("swap");
        return;
      default:
        throw new Unreachable("Invalid instruction for CfStackInstruction");
    }
  }

  public void print(CfThrow insn) {
    print("athrow");
  }

  public void print(CfConstNull constNull) {
    print("aconst_null");
  }

  public void print(CfConstNumber constNumber) {
    indent();
    // TODO(zerny): Determine when the number matches the tconst_X instructions.
    switch (constNumber.getType()) {
      case INT:
        builder.append("ldc ").append(constNumber.getIntValue());
        break;
      case FLOAT:
        builder.append("ldc ").append(constNumber.getFloatValue());
        break;
      case LONG:
        builder.append("ldc_w ").append(constNumber.getLongValue());
        break;
      case DOUBLE:
        builder.append("ldc_w ").append(constNumber.getDoubleValue());
        break;
      default:
        throw new Unreachable("Unexpected const-number type: " + constNumber.getType());
    }
  }

  public void print(CfConstClass constClass) {
    indent();
    builder.append("ldc ");
    appendType(constClass.getType());
  }

  public void print(CfConstDynamic constDynamic) {
    indent();
    builder.append("ldc <dynamic> ");
    appendType(constDynamic.getType());
  }

  public void print(CfInitClass initClass) {
    indent();
    builder.append("initclass ");
    appendType(initClass.getClassValue());
  }

  public void print(CfReturnVoid ret) {
    print("return");
  }

  public void print(CfReturn ret) {
    print(typePrefix(ret.getType()) + "return");
  }

  public void print(CfMonitor monitor) {
    print(monitor.getType() == Monitor.Type.ENTER ? "monitorenter" : "monitorexit");
  }

  public void print(CfArithmeticBinop arithmeticBinop) {
    print(opcodeName(arithmeticBinop.getAsmOpcode()));
  }

  public void print(CfCmp cmp) {
    print(opcodeName(cmp.getAsmOpcode()));
  }

  public void print(CfLogicalBinop logicalBinop) {
    print(opcodeName(logicalBinop.getAsmOpcode()));
  }

  public void print(CfNeg neg) {
    print(opcodeName(neg.getAsmOpcode()));
  }

  public void print(CfNumberConversion numberConversion) {
    print(opcodeName(numberConversion.getAsmOpcode()));
  }

  public void print(CfConstString constString) {
    indent();
    builder.append("ldc ").append(constString.getString());
  }

  public void print(CfDexItemBasedConstString constString) {
    indent();
    builder.append("ldc* ").append(constString.getItem().toString());
  }

  public void print(CfArrayLoad arrayLoad) {
    indent();
    builder.append(typePrefix(arrayLoad.getType())).append("aload");
  }

  public void print(CfArrayStore arrayStore) {
    indent();
    builder.append(typePrefix(arrayStore.getType())).append("astore");
  }

  public void print(CfInvoke invoke) {
    indent();
    builder.append(opcodeName(invoke.getOpcode())).append(' ');
    appendMethod(invoke.getMethod());
  }

  public void print(CfInvokeDynamic invoke) {
    indent();
    DexCallSite callSite = invoke.getCallSite();
    DexMethodHandle bootstrapMethod = callSite.bootstrapMethod;
    builder.append(opcodeName(Opcodes.INVOKEDYNAMIC)).append(' ');
    builder.append(callSite.methodName);
    builder.append(callSite.methodProto.toDescriptorString());
    if (callSite.bootstrapArgs.size() > 1) {
      DexValue.DexValueMethodHandle dexValueMethodHandle =
          callSite.bootstrapArgs.get(1).asDexValueMethodHandle();
      if (dexValueMethodHandle != null) {
        DexMethodHandle handle = dexValueMethodHandle.getValue();
        builder.append(", handle:");
        builder.append(handle.toSourceString());
        builder.append(", itf: ").append(handle.isInterface);
      }
    }
    builder.append(", bsm:");
    appendMethod(bootstrapMethod.asMethod());
  }

  public void print(CfFrame frame) {
    indent();
    builder.append("; frame: [");
    if (!frame.getLocals().isEmpty()) {
      int firstLocalIndex = frame.getLocals().firstIntKey();
      frame.forEachLocal(
          (localIndex, frameType) -> {
            String separator = localIndex == firstLocalIndex ? "" : ", ";
            builder.append(separator).append(localIndex).append(':');
            print(frameType);
          });
    }
    builder.append("] [");
    {
      String separator = "";
      for (PreciseFrameType element : frame.getStack()) {
        builder.append(separator);
        print(element);
        separator = ", ";
      }
    }
    builder.append(']');
  }

  private void print(FrameType type) {
    if (type.isPrimitive()) {
      builder.append(type.asPrimitive().getTypeName());
    } else if (type.isInitialized()) {
      appendType(type.asInitializedReferenceType().getInitializedType());
    } else if (type.isUninitializedNew()) {
      builder.append("uninitialized ").append(getLabel(type.getUninitializedLabel()));
    } else {
      builder.append(type.toString());
    }
  }

  public void print(CfInstanceOf insn) {
    indent();
    builder.append("instanceof ");
    appendClass(insn.getType());
  }

  public void print(CfCheckCast insn) {
    indent();
    builder.append("checkcast ");
    appendClass(insn.getType());
  }

  public void print(CfInstanceFieldRead insn) {
    print(insn.asFieldInstruction());
  }

  public void print(CfInstanceFieldWrite insn) {
    print(insn.asFieldInstruction());
  }

  public void print(CfStaticFieldRead insn) {
    print(insn.asFieldInstruction());
  }

  public void print(CfStaticFieldWrite insn) {
    print(insn.asFieldInstruction());
  }

  public void print(CfFieldInstruction insn) {
    indent();
    switch (insn.getOpcode()) {
      case Opcodes.GETFIELD:
        builder.append("getfield ");
        break;
      case Opcodes.PUTFIELD:
        builder.append("putfield ");
        break;
      case Opcodes.GETSTATIC:
        builder.append("getstatic ");
        break;
      case Opcodes.PUTSTATIC:
        builder.append("putstatic ");
        break;
      default:
        throw new Unreachable("Unexpected field-instruction opcode " + insn.getOpcode());
    }
    appendField(insn.getField());
    builder.append(' ');
    appendDescriptor(insn.getField().type);
  }

  public void print(CfNew newInstance) {
    indent();
    builder.append("new ");
    appendClass(newInstance.getType());
  }

  public void print(CfNewArray newArray) {
    indent();
    String elementDescriptor = newArray.getType().toDescriptorString().substring(1);
    if (newArray.getType().isPrimitiveArrayType()) {
      // Primitive arrays are formatted as the Java type: int, byte, etc.
      builder.append("newarray ");
      builder.append(DescriptorUtils.descriptorToJavaType(elementDescriptor));
    } else {
      builder.append("anewarray ");
      if (elementDescriptor.charAt(0) == '[') {
        // Arrays of arrays are formatted using the descriptor syntax.
        builder.append(elementDescriptor);
      } else {
        // Arrays of class types are formatted using the "internal name".
        builder.append(Type.getType(elementDescriptor).getInternalName());
      }
    }
  }

  public void print(CfNewUnboxedEnum newInstance) {
    indent();
    builder.append("newunboxedenum ");
    appendClass(newInstance.getType());
  }

  public void print(CfMultiANewArray multiANewArray) {
    indent();
    builder.append("multianewarray ");
    appendClass(multiANewArray.getType());
    builder.append(' ').append(multiANewArray.getDimensions());
  }

  public void print(CfArrayLength arrayLength) {
    print("arraylength");
  }

  public void print(CfLabel label) {
    newline();
    instructionIndex();
    builder.append(getLabel(label)).append(':');
    if (PRINT_INLINE_LOCALS && labelToIndex != null) {
      int labelNumber = labelToIndex.getInt(label);
      List<LocalVariableInfo> locals = localsAtLabel.get(labelNumber);
      appendComment(
          "locals: "
              + String.join(
                  ", ",
                  locals.stream().map(LocalVariableInfo::toString).collect(Collectors.toList())));
    }
  }

  public void print(CfPosition instruction) {
    Position position = instruction.getPosition();
    indent();
    builder.append(".line ").append(position.getLine());
    if (position.hasCallerPosition() || position.hasFile()) {
      appendComment(position.toString());
    }
  }

  public void print(CfGoto jump) {
    indent();
    builder.append("goto ").append(getLabel(jump.getTarget()));
  }

  private String ifPostfix(If.Type kind) {
    return kind.toString().toLowerCase();
  }

  public void print(CfIf conditional) {
    indent();
    if (conditional.getType().isObject()) {
      builder.append("if").append(conditional.getKind() == If.Type.EQ ? "null" : "nonnull");
    } else {
      builder.append("if").append(ifPostfix(conditional.getKind()));
    }
    builder.append(' ').append(getLabel(conditional.getTarget()));
  }

  public void print(CfIfCmp conditional) {
    indent();
    builder
        .append(conditional.getType().isObject() ? "if_acmp" : "if_icmp")
        .append(ifPostfix(conditional.getKind()))
        .append(' ')
        .append(getLabel(conditional.getTarget()));
  }

  public void print(CfSwitch cfSwitch) {
    indent();
    Kind kind = cfSwitch.getKind();
    builder.append(kind == Kind.LOOKUP ? "lookup" : "table").append("switch");
    IntList keys = (IntList) cfSwitch.getKeys();
    List<CfLabel> targets = cfSwitch.getSwitchTargets();
    for (int i = 0; i < targets.size(); i++) {
      indent();
      int key = kind == Kind.LOOKUP ? keys.getInt(i) : (keys.getInt(0) + i);
      builder
          .append("  ")
          .append(key)
          .append(": ")
          .append(getLabel(targets.get(i)));
    }
    indent();
    builder
        .append("  default: ")
        .append(getLabel(cfSwitch.getDefaultTarget()));
  }

  public void print(CfLoad load) {
    printPrefixed(load.getType(), "load", load.getLocalIndex());
  }

  public void print(CfStore store) {
    printPrefixed(store.getType(), "store", store.getLocalIndex());
  }

  public void print(CfIinc instruction) {
    indent();
    builder
        .append("iinc ")
        .append(instruction.getLocalIndex())
        .append(' ')
        .append(instruction.getIncrement());
  }

  private void printPrefixed(ValueType type, String instruction, int local) {
    indent();
    builder.append(typePrefix(type)).append(instruction).append(' ').append(local);
  }

  private char typePrefix(ValueType type) {
    switch (type) {
      case OBJECT:
        return 'a';
      case INT:
        return 'i';
      case FLOAT:
        return 'f';
      case LONG:
        return 'l';
      case DOUBLE:
        return 'd';
      default:
        throw new Unreachable("Unexpected type for prefix: " + type);
    }
  }

  public char typePrefix(MemberType type) {
    switch (type) {
      case OBJECT:
        return 'a';
      case BOOLEAN_OR_BYTE:
        return 'b';
      case CHAR:
        return 'c';
      case SHORT:
        return 's';
      case INT:
        return 'i';
      case FLOAT:
        return 'f';
      case LONG:
        return 'l';
      case DOUBLE:
        return 'd';
      default:
        throw new Unreachable("Unexpected member type for prefix: " + type);
    }
  }

  public char typePrefix(NumericType type) {
    switch (type) {
      case BYTE:
      case CHAR:
      case SHORT:
      case INT:
        return 'i';
      case FLOAT:
        return 'f';
      case LONG:
        return 'l';
      case DOUBLE:
        return 'd';
      default:
        throw new Unreachable("Unexpected numeric type for prefix: " + type);
    }
  }

  public void print(CfConstMethodHandle handle) {
    indent();
    builder.append("ldc ");
    builder.append(handle.getHandle().toString());
  }

  public void print(CfConstMethodType type) {
    indent();
    builder.append("ldc ");
    builder.append(type.getType().toString());
  }

  public void print(CfJsrRet ret) {
    indent();
    builder.append("ret ").append(ret.getLocal());
  }

  private String getLabel(CfLabel label) {
    return labelToIndex != null ? ("L" + labelToIndex.getInt(label)) : "L?";
  }

  private void newline() {
    if (builder.length() > 0) {
      builder.append('\n');
    }
  }

  private void instructionIndex() {
    if (PRINT_INSTRUCTION_INDEX && instructionIndexSpace > 0) {
      builder.append(String.format("%" + instructionIndexSpace + "d: ", nextInstructionIndex++));
    }
  }

  private void indent() {
    newline();
    instructionIndex();
    builder.append(indent);
  }

  private void comment(String comment) {
    indent();
    builder.append("; ").append(comment);
  }

  private void appendComment(String comment) {
    builder.append(" ; ").append(comment);
  }

  private void appendDescriptor(DexType type) {
    if (mapper != null) {
      builder.append(DescriptorUtils.javaTypeToDescriptor(mapper.originalNameOf(type)));
      return;
    }
    builder.append(type.toDescriptorString());
  }

  private void appendType(DexType type) {
    if (type.isArrayType() || type.isClassType()) {
      appendClass(type);
    } else {
      builder.append(type);
    }
  }

  private void appendClass(DexType type) {
    assert type.isArrayType() || type.isClassType();
    if (mapper == null) {
      builder.append(type.getInternalName());
    } else if (type == DexItemFactory.nullValueType) {
      builder.append("NULL");
    } else {
      builder.append(
          DescriptorUtils.descriptorToInternalName(
              DescriptorUtils.javaTypeToDescriptor(mapper.originalNameOf(type))));
    }
  }

  private void appendField(DexField field) {
    if (mapper != null) {
      builder.append(mapper.originalSignatureOf(field).toString());
      return;
    }
    appendClass(field.holder);
    builder.append('/').append(field.name);
  }

  private void appendMethod(DexMethod method) {
    if (mapper != null) {
      MethodSignature signature = mapper.originalSignatureOf(method);
      builder.append(mapper.originalNameOf(method.holder)).append('.');
      builder.append(signature.name).append(signature.toDescriptor());
      return;
    }
    builder.append(method.qualifiedName());
    builder.append(method.proto.toDescriptorString());
  }

  private String opcodeName(int opcode) {
    return Printer.OPCODES[opcode].toLowerCase();
  }

  @Override
  public String toString() {
    return builder.toString();
  }
}
