// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.apache.tapestry5.internal.plastic.asm.util;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
import org.apache.tapestry5.internal.plastic.asm.Attribute;
import org.apache.tapestry5.internal.plastic.asm.ClassReader;
import org.apache.tapestry5.internal.plastic.asm.ClassVisitor;
import org.apache.tapestry5.internal.plastic.asm.FieldVisitor;
import org.apache.tapestry5.internal.plastic.asm.Label;
import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
import org.apache.tapestry5.internal.plastic.asm.ModuleVisitor;
import org.apache.tapestry5.internal.plastic.asm.Opcodes;
import org.apache.tapestry5.internal.plastic.asm.RecordComponentVisitor;
import org.apache.tapestry5.internal.plastic.asm.Type;
import org.apache.tapestry5.internal.plastic.asm.TypePath;
import org.apache.tapestry5.internal.plastic.asm.TypeReference;
import org.apache.tapestry5.internal.plastic.asm.tree.ClassNode;
import org.apache.tapestry5.internal.plastic.asm.tree.MethodNode;
import org.apache.tapestry5.internal.plastic.asm.tree.TryCatchBlockNode;
import org.apache.tapestry5.internal.plastic.asm.tree.analysis.Analyzer;
import org.apache.tapestry5.internal.plastic.asm.tree.analysis.AnalyzerException;
import org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue;
import org.apache.tapestry5.internal.plastic.asm.tree.analysis.Frame;
import org.apache.tapestry5.internal.plastic.asm.tree.analysis.SimpleVerifier;

/**
 * A {@link ClassVisitor} that checks that its methods are properly used. More precisely this class
 * adapter checks each method call individually, based <i>only</i> on its arguments, but does
 * <i>not</i> check the <i>sequence</i> of method calls. For example, the invalid sequence {@code
 * visitField(ACC_PUBLIC, "i", "I", null)} {@code visitField(ACC_PUBLIC, "i", "D", null)} will
 * <i>not</i> be detected by this class adapter.
 *
 * <p><code>CheckClassAdapter</code> can be also used to verify bytecode transformations in order to
 * make sure that the transformed bytecode is sane. For example:
 *
 * <pre>
 * InputStream inputStream = ...; // get bytes for the source class
 * ClassReader classReader = new ClassReader(inputStream);
 * ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);
 * ClassVisitor classVisitor = new <b>MyClassAdapter</b>(new CheckClassAdapter(classWriter, true));
 * classReader.accept(classVisitor, 0);
 *
 * StringWriter stringWriter = new StringWriter();
 * PrintWriter printWriter = new PrintWriter(stringWriter);
 * CheckClassAdapter.verify(new ClassReader(classWriter.toByteArray()), false, printWriter);
 * assertTrue(stringWriter.toString().isEmpty());
 * </pre>
 *
 * <p>The above code pass the transformed bytecode through a <code>CheckClassAdapter</code>, with
 * data flow checks enabled. These checks are not exactly the same as the JVM verification, but
 * provide some basic type checking for each method instruction. If the bytecode has errors, the
 * output text shows the erroneous instruction number, and a dump of the failed method with
 * information about the type of the local variables and of the operand stack slots for each
 * instruction. For example (format is - insnNumber locals : stack):
 *
 * <pre>
 * org.apache.tapestry5.internal.plastic.asm.tree.analysis.AnalyzerException: Error at instruction 71: Expected I, but found .
 *   at org.apache.tapestry5.internal.plastic.asm.tree.analysis.Analyzer.analyze(Analyzer.java:...)
 *   at org.apache.tapestry5.internal.plastic.asm.util.CheckClassAdapter.verify(CheckClassAdapter.java:...)
 * ...
 * remove()V
 * 00000 LinkedBlockingQueue$Itr . . . . . . . .  : ICONST_0
 * 00001 LinkedBlockingQueue$Itr . . . . . . . .  : I ISTORE 2
 * 00001 LinkedBlockingQueue$Itr <b>.</b> I . . . . . .  :
 * ...
 * 00071 LinkedBlockingQueue$Itr <b>.</b> I . . . . . .  : ILOAD 1
 * 00072 <b>?</b> INVOKESPECIAL java/lang/Integer.&lt;init&gt; (I)V
 * ...
 * </pre>
 *
 * <p>The above output shows that the local variable 1, loaded by the <code>ILOAD 1</code>
 * instruction at position <code>00071</code> is not initialized, whereas the local variable 2 is
 * initialized and contains an int value.
 *
 * @author Eric Bruneton
 */
public class CheckClassAdapter extends ClassVisitor {

  /** The help message shown when command line arguments are incorrect. */
  private static final String USAGE =
      "Verifies the given class.\n"
          + "Usage: CheckClassAdapter <fully qualified class name or class file name>";

  private static final String ERROR_AT = ": error at index ";

  /** Whether the bytecode must be checked with a BasicVerifier. */
  private boolean checkDataFlow;

  /** The class version number. */
  private int version;

  /** Whether the {@link #visit} method has been called. */
  private boolean visitCalled;

  /** Whether the {@link #visitModule} method has been called. */
  private boolean visitModuleCalled;

  /** Whether the {@link #visitSource} method has been called. */
  private boolean visitSourceCalled;

  /** Whether the {@link #visitOuterClass} method has been called. */
  private boolean visitOuterClassCalled;

  /** Whether the {@link #visitNestHost} method has been called. */
  private boolean visitNestHostCalled;

  /**
   * The common package of all the nest members. Not {@literal null} if the visitNestMember method
   * has been called.
   */
  private String nestMemberPackageName;

  /** Whether the {@link #visitEnd} method has been called. */
  private boolean visitEndCalled;

  /** The index of the instruction designated by each visited label so far. */
  private Map<Label, Integer> labelInsnIndices;

  // -----------------------------------------------------------------------------------------------
  // Constructors
  // -----------------------------------------------------------------------------------------------

  /**
   * Constructs a new {@link CheckClassAdapter}. <i>Subclasses must not use this constructor</i>.
   * Instead, they must use the {@link #CheckClassAdapter(int, ClassVisitor, boolean)} version.
   *
   * @param classVisitor the class visitor to which this adapter must delegate calls.
   */
  public CheckClassAdapter(final ClassVisitor classVisitor) {
    this(classVisitor, true);
  }

  /**
   * Constructs a new {@link CheckClassAdapter}. <i>Subclasses must not use this constructor</i>.
   * Instead, they must use the {@link #CheckClassAdapter(int, ClassVisitor, boolean)} version.
   *
   * @param classVisitor the class visitor to which this adapter must delegate calls.
   * @param checkDataFlow whether to perform basic data flow checks. This option requires valid
   *     maxLocals and maxStack values.
   * @throws IllegalStateException If a subclass calls this constructor.
   */
  public CheckClassAdapter(final ClassVisitor classVisitor, final boolean checkDataFlow) {
    this(/* latest api = */ Opcodes.ASM8, classVisitor, checkDataFlow);
    if (getClass() != CheckClassAdapter.class) {
      throw new IllegalStateException();
    }
  }

  /**
   * Constructs a new {@link CheckClassAdapter}.
   *
   * @param api the ASM API version implemented by this visitor. Must be one of {@link
   *     Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link
   *     Opcodes#ASM8}.
   * @param classVisitor the class visitor to which this adapter must delegate calls.
   * @param checkDataFlow {@literal true} to perform basic data flow checks, or {@literal false} to
   *     not perform any data flow check (see {@link CheckMethodAdapter}). This option requires
   *     valid maxLocals and maxStack values.
   */
  protected CheckClassAdapter(
      final int api, final ClassVisitor classVisitor, final boolean checkDataFlow) {
    super(api, classVisitor);
    this.labelInsnIndices = new HashMap<>();
    this.checkDataFlow = checkDataFlow;
  }

  // -----------------------------------------------------------------------------------------------
  // Implementation of the ClassVisitor interface
  // -----------------------------------------------------------------------------------------------

  @Override
  public void visit(
      final int version,
      final int access,
      final String name,
      final String signature,
      final String superName,
      final String[] interfaces) {
    if (visitCalled) {
      throw new IllegalStateException("visit must be called only once");
    }
    visitCalled = true;
    checkState();
    checkAccess(
        access,
        Opcodes.ACC_PUBLIC
            | Opcodes.ACC_FINAL
            | Opcodes.ACC_SUPER
            | Opcodes.ACC_INTERFACE
            | Opcodes.ACC_ABSTRACT
            | Opcodes.ACC_SYNTHETIC
            | Opcodes.ACC_ANNOTATION
            | Opcodes.ACC_ENUM
            | Opcodes.ACC_DEPRECATED
            | Opcodes.ACC_RECORD
            | Opcodes.ACC_MODULE);
    if (name == null) {
      throw new IllegalArgumentException("Illegal class name (null)");
    }
    if (!name.endsWith("package-info") && !name.endsWith("module-info")) {
      CheckMethodAdapter.checkInternalName(version, name, "class name");
    }
    if ("java/lang/Object".equals(name)) {
      if (superName != null) {
        throw new IllegalArgumentException(
            "The super class name of the Object class must be 'null'");
      }
    } else if (name.endsWith("module-info")) {
      if (superName != null) {
        throw new IllegalArgumentException(
            "The super class name of a module-info class must be 'null'");
      }
    } else {
      CheckMethodAdapter.checkInternalName(version, superName, "super class name");
    }
    if (signature != null) {
      checkClassSignature(signature);
    }
    if ((access & Opcodes.ACC_INTERFACE) != 0 && !"java/lang/Object".equals(superName)) {
      throw new IllegalArgumentException(
          "The super class name of interfaces must be 'java/lang/Object'");
    }
    if (interfaces != null) {
      for (int i = 0; i < interfaces.length; ++i) {
        CheckMethodAdapter.checkInternalName(
            version, interfaces[i], "interface name at index " + i);
      }
    }
    this.version = version;
    super.visit(version, access, name, signature, superName, interfaces);
  }

  @Override
  public void visitSource(final String file, final String debug) {
    checkState();
    if (visitSourceCalled) {
      throw new IllegalStateException("visitSource can be called only once.");
    }
    visitSourceCalled = true;
    super.visitSource(file, debug);
  }

  @Override
  public ModuleVisitor visitModule(final String name, final int access, final String version) {
    checkState();
    if (visitModuleCalled) {
      throw new IllegalStateException("visitModule can be called only once.");
    }
    visitModuleCalled = true;
    checkFullyQualifiedName(this.version, name, "module name");
    checkAccess(access, Opcodes.ACC_OPEN | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_MANDATED);
    CheckModuleAdapter checkModuleAdapter =
        new CheckModuleAdapter(
            api, super.visitModule(name, access, version), (access & Opcodes.ACC_OPEN) != 0);
    checkModuleAdapter.classVersion = this.version;
    return checkModuleAdapter;
  }

  @Override
  public void visitNestHost(final String nestHost) {
    checkState();
    CheckMethodAdapter.checkInternalName(version, nestHost, "nestHost");
    if (visitNestHostCalled) {
      throw new IllegalStateException("visitNestHost can be called only once.");
    }
    if (nestMemberPackageName != null) {
      throw new IllegalStateException("visitNestHost and visitNestMember are mutually exclusive.");
    }
    visitNestHostCalled = true;
    super.visitNestHost(nestHost);
  }

  @Override
  public void visitNestMember(final String nestMember) {
    checkState();
    CheckMethodAdapter.checkInternalName(version, nestMember, "nestMember");
    if (visitNestHostCalled) {
      throw new IllegalStateException(
          "visitMemberOfNest and visitNestHost are mutually exclusive.");
    }
    String packageName = packageName(nestMember);
    if (nestMemberPackageName == null) {
      nestMemberPackageName = packageName;
    } else if (!nestMemberPackageName.equals(packageName)) {
      throw new IllegalStateException(
          "nest member " + nestMember + " should be in the package " + nestMemberPackageName);
    }
    super.visitNestMember(nestMember);
  }

  /**
   * <b>Experimental, use at your own risk.</b>.
   *
   * @param permittedSubtype the internal name of a permitted subtype.
   * @deprecated this API is experimental.
   */
  @Override
  @Deprecated
  public void visitPermittedSubtypeExperimental(final String permittedSubtype) {
    checkState();
    CheckMethodAdapter.checkInternalName(version, permittedSubtype, "permittedSubtype");
    super.visitPermittedSubtypeExperimental(permittedSubtype);
  }

  @Override
  public void visitOuterClass(final String owner, final String name, final String descriptor) {
    checkState();
    if (visitOuterClassCalled) {
      throw new IllegalStateException("visitOuterClass can be called only once.");
    }
    visitOuterClassCalled = true;
    if (owner == null) {
      throw new IllegalArgumentException("Illegal outer class owner");
    }
    if (descriptor != null) {
      CheckMethodAdapter.checkMethodDescriptor(version, descriptor);
    }
    super.visitOuterClass(owner, name, descriptor);
  }

  @Override
  public void visitInnerClass(
      final String name, final String outerName, final String innerName, final int access) {
    checkState();
    CheckMethodAdapter.checkInternalName(version, name, "class name");
    if (outerName != null) {
      CheckMethodAdapter.checkInternalName(version, outerName, "outer class name");
    }
    if (innerName != null) {
      int startIndex = 0;
      while (startIndex < innerName.length() && Character.isDigit(innerName.charAt(startIndex))) {
        startIndex++;
      }
      if (startIndex == 0 || startIndex < innerName.length()) {
        CheckMethodAdapter.checkIdentifier(version, innerName, startIndex, -1, "inner class name");
      }
    }
    checkAccess(
        access,
        Opcodes.ACC_PUBLIC
            | Opcodes.ACC_PRIVATE
            | Opcodes.ACC_PROTECTED
            | Opcodes.ACC_STATIC
            | Opcodes.ACC_FINAL
            | Opcodes.ACC_INTERFACE
            | Opcodes.ACC_ABSTRACT
            | Opcodes.ACC_SYNTHETIC
            | Opcodes.ACC_ANNOTATION
            | Opcodes.ACC_ENUM);
    super.visitInnerClass(name, outerName, innerName, access);
  }

  @Override
  public RecordComponentVisitor visitRecordComponent(
      final String name, final String descriptor, final String signature) {
    checkState();
    CheckMethodAdapter.checkUnqualifiedName(version, name, "record component name");
    CheckMethodAdapter.checkDescriptor(version, descriptor, /* canBeVoid = */ false);
    if (signature != null) {
      checkFieldSignature(signature);
    }
    return new CheckRecordComponentAdapter(
        api, super.visitRecordComponent(name, descriptor, signature));
  }

  @Override
  public FieldVisitor visitField(
      final int access,
      final String name,
      final String descriptor,
      final String signature,
      final Object value) {
    checkState();
    checkAccess(
        access,
        Opcodes.ACC_PUBLIC
            | Opcodes.ACC_PRIVATE
            | Opcodes.ACC_PROTECTED
            | Opcodes.ACC_STATIC
            | Opcodes.ACC_FINAL
            | Opcodes.ACC_VOLATILE
            | Opcodes.ACC_TRANSIENT
            | Opcodes.ACC_SYNTHETIC
            | Opcodes.ACC_ENUM
            | Opcodes.ACC_MANDATED
            | Opcodes.ACC_DEPRECATED);
    CheckMethodAdapter.checkUnqualifiedName(version, name, "field name");
    CheckMethodAdapter.checkDescriptor(version, descriptor, /* canBeVoid = */ false);
    if (signature != null) {
      checkFieldSignature(signature);
    }
    if (value != null) {
      CheckMethodAdapter.checkConstant(value);
    }
    return new CheckFieldAdapter(api, super.visitField(access, name, descriptor, signature, value));
  }

  @Override
  public MethodVisitor visitMethod(
      final int access,
      final String name,
      final String descriptor,
      final String signature,
      final String[] exceptions) {
    checkState();
    checkAccess(
        access,
        Opcodes.ACC_PUBLIC
            | Opcodes.ACC_PRIVATE
            | Opcodes.ACC_PROTECTED
            | Opcodes.ACC_STATIC
            | Opcodes.ACC_FINAL
            | Opcodes.ACC_SYNCHRONIZED
            | Opcodes.ACC_BRIDGE
            | Opcodes.ACC_VARARGS
            | Opcodes.ACC_NATIVE
            | Opcodes.ACC_ABSTRACT
            | Opcodes.ACC_STRICT
            | Opcodes.ACC_SYNTHETIC
            | Opcodes.ACC_MANDATED
            | Opcodes.ACC_DEPRECATED);
    if (!"<init>".equals(name) && !"<clinit>".equals(name)) {
      CheckMethodAdapter.checkMethodIdentifier(version, name, "method name");
    }
    CheckMethodAdapter.checkMethodDescriptor(version, descriptor);
    if (signature != null) {
      checkMethodSignature(signature);
    }
    if (exceptions != null) {
      for (int i = 0; i < exceptions.length; ++i) {
        CheckMethodAdapter.checkInternalName(
            version, exceptions[i], "exception name at index " + i);
      }
    }
    CheckMethodAdapter checkMethodAdapter;
    if (checkDataFlow) {
      checkMethodAdapter =
          new CheckMethodAdapter(
              api,
              access,
              name,
              descriptor,
              super.visitMethod(access, name, descriptor, signature, exceptions),
              labelInsnIndices);
    } else {
      checkMethodAdapter =
          new CheckMethodAdapter(
              api,
              super.visitMethod(access, name, descriptor, signature, exceptions),
              labelInsnIndices);
    }
    checkMethodAdapter.version = version;
    return checkMethodAdapter;
  }

  @Override
  public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
    checkState();
    CheckMethodAdapter.checkDescriptor(version, descriptor, false);
    return new CheckAnnotationAdapter(super.visitAnnotation(descriptor, visible));
  }

  @Override
  public AnnotationVisitor visitTypeAnnotation(
      final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
    checkState();
    int sort = new TypeReference(typeRef).getSort();
    if (sort != TypeReference.CLASS_TYPE_PARAMETER
        && sort != TypeReference.CLASS_TYPE_PARAMETER_BOUND
        && sort != TypeReference.CLASS_EXTENDS) {
      throw new IllegalArgumentException(
          "Invalid type reference sort 0x" + Integer.toHexString(sort));
    }
    checkTypeRef(typeRef);
    CheckMethodAdapter.checkDescriptor(version, descriptor, false);
    return new CheckAnnotationAdapter(
        super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
  }

  @Override
  public void visitAttribute(final Attribute attribute) {
    checkState();
    if (attribute == null) {
      throw new IllegalArgumentException("Invalid attribute (must not be null)");
    }
    super.visitAttribute(attribute);
  }

  @Override
  public void visitEnd() {
    checkState();
    visitEndCalled = true;
    super.visitEnd();
  }

  // -----------------------------------------------------------------------------------------------
  // Utility methods
  // -----------------------------------------------------------------------------------------------

  /** Checks that the visit method has been called and that visitEnd has not been called. */
  private void checkState() {
    if (!visitCalled) {
      throw new IllegalStateException("Cannot visit member before visit has been called.");
    }
    if (visitEndCalled) {
      throw new IllegalStateException("Cannot visit member after visitEnd has been called.");
    }
  }

  /**
   * Checks that the given access flags do not contain invalid flags. This method also checks that
   * mutually incompatible flags are not set simultaneously.
   *
   * @param access the access flags to be checked.
   * @param possibleAccess the valid access flags.
   */
  static void checkAccess(final int access, final int possibleAccess) {
    if ((access & ~possibleAccess) != 0) {
      throw new IllegalArgumentException("Invalid access flags: " + access);
    }
    int publicProtectedPrivate = Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE;
    if (Integer.bitCount(access & publicProtectedPrivate) > 1) {
      throw new IllegalArgumentException(
          "public, protected and private are mutually exclusive: " + access);
    }
    if (Integer.bitCount(access & (Opcodes.ACC_FINAL | Opcodes.ACC_ABSTRACT)) > 1) {
      throw new IllegalArgumentException("final and abstract are mutually exclusive: " + access);
    }
  }

  /**
   * Checks that the given name is a fully qualified name, using dots.
   *
   * @param version the class version.
   * @param name the name to be checked.
   * @param source the source of 'name' (e.g 'module' for a module name).
   */
  static void checkFullyQualifiedName(final int version, final String name, final String source) {
    try {
      int startIndex = 0;
      int dotIndex;
      while ((dotIndex = name.indexOf('.', startIndex + 1)) != -1) {
        CheckMethodAdapter.checkIdentifier(version, name, startIndex, dotIndex, null);
        startIndex = dotIndex + 1;
      }
      CheckMethodAdapter.checkIdentifier(version, name, startIndex, name.length(), null);
    } catch (IllegalArgumentException e) {
      throw new IllegalArgumentException(
          "Invalid " + source + " (must be a fully qualified name): " + name, e);
    }
  }

  /**
   * Checks a class signature.
   *
   * @param signature a string containing the signature that must be checked.
   */
  public static void checkClassSignature(final String signature) {
    // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
    // ClassSignature:
    //   [TypeParameters] SuperclassSignature SuperinterfaceSignature*
    // SuperclassSignature:
    //   ClassTypeSignature
    // SuperinterfaceSignature:
    //   ClassTypeSignature
    int pos = 0;
    if (getChar(signature, 0) == '<') {
      pos = checkTypeParameters(signature, pos);
    }
    pos = checkClassTypeSignature(signature, pos);
    while (getChar(signature, pos) == 'L') {
      pos = checkClassTypeSignature(signature, pos);
    }
    if (pos != signature.length()) {
      throw new IllegalArgumentException(signature + ERROR_AT + pos);
    }
  }

  /**
   * Checks a method signature.
   *
   * @param signature a string containing the signature that must be checked.
   */
  public static void checkMethodSignature(final String signature) {
    // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
    // MethodSignature:
    //   [TypeParameters] ( JavaTypeSignature* ) Result ThrowsSignature*
    // Result:
    //   JavaTypeSignature
    //   VoidDescriptor
    // ThrowsSignature:
    //   ^ ClassTypeSignature
    //   ^ TypeVariableSignature
    int pos = 0;
    if (getChar(signature, 0) == '<') {
      pos = checkTypeParameters(signature, pos);
    }
    pos = checkChar('(', signature, pos);
    while ("ZCBSIFJDL[T".indexOf(getChar(signature, pos)) != -1) {
      pos = checkJavaTypeSignature(signature, pos);
    }
    pos = checkChar(')', signature, pos);
    if (getChar(signature, pos) == 'V') {
      ++pos;
    } else {
      pos = checkJavaTypeSignature(signature, pos);
    }
    while (getChar(signature, pos) == '^') {
      ++pos;
      if (getChar(signature, pos) == 'L') {
        pos = checkClassTypeSignature(signature, pos);
      } else {
        pos = checkTypeVariableSignature(signature, pos);
      }
    }
    if (pos != signature.length()) {
      throw new IllegalArgumentException(signature + ERROR_AT + pos);
    }
  }

  /**
   * Checks a field signature.
   *
   * @param signature a string containing the signature that must be checked.
   */
  public static void checkFieldSignature(final String signature) {
    // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
    // FieldSignature:
    //   ReferenceTypeSignature
    int pos = checkReferenceTypeSignature(signature, 0);
    if (pos != signature.length()) {
      throw new IllegalArgumentException(signature + ERROR_AT + pos);
    }
  }

  /**
   * Checks the type parameters of a class or method signature.
   *
   * @param signature a string containing the signature that must be checked.
   * @param startPos index of first character to be checked.
   * @return the index of the first character after the checked part.
   */
  private static int checkTypeParameters(final String signature, final int startPos) {
    // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
    // TypeParameters:
    //   < TypeParameter TypeParameter* >
    int pos = startPos;
    pos = checkChar('<', signature, pos);
    pos = checkTypeParameter(signature, pos);
    while (getChar(signature, pos) != '>') {
      pos = checkTypeParameter(signature, pos);
    }
    return pos + 1;
  }

  /**
   * Checks a type parameter of a class or method signature.
   *
   * @param signature a string containing the signature that must be checked.
   * @param startPos index of first character to be checked.
   * @return the index of the first character after the checked part.
   */
  private static int checkTypeParameter(final String signature, final int startPos) {
    // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
    // TypeParameter:
    //   Identifier ClassBound InterfaceBound*
    // ClassBound:
    //   : [ReferenceTypeSignature]
    // InterfaceBound:
    //   : ReferenceTypeSignature
    int pos = startPos;
    pos = checkSignatureIdentifier(signature, pos);
    pos = checkChar(':', signature, pos);
    if ("L[T".indexOf(getChar(signature, pos)) != -1) {
      pos = checkReferenceTypeSignature(signature, pos);
    }
    while (getChar(signature, pos) == ':') {
      pos = checkReferenceTypeSignature(signature, pos + 1);
    }
    return pos;
  }

  /**
   * Checks a reference type signature.
   *
   * @param signature a string containing the signature that must be checked.
   * @param pos index of first character to be checked.
   * @return the index of the first character after the checked part.
   */
  private static int checkReferenceTypeSignature(final String signature, final int pos) {
    // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
    // ReferenceTypeSignature:
    //   ClassTypeSignature
    //   TypeVariableSignature
    //   ArrayTypeSignature
    // ArrayTypeSignature:
    //   [ JavaTypeSignature
    switch (getChar(signature, pos)) {
      case 'L':
        return checkClassTypeSignature(signature, pos);
      case '[':
        return checkJavaTypeSignature(signature, pos + 1);
      default:
        return checkTypeVariableSignature(signature, pos);
    }
  }

  /**
   * Checks a class type signature.
   *
   * @param signature a string containing the signature that must be checked.
   * @param startPos index of first character to be checked.
   * @return the index of the first character after the checked part.
   */
  private static int checkClassTypeSignature(final String signature, final int startPos) {
    // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
    // ClassTypeSignature:
    //   L [PackageSpecifier] SimpleClassTypeSignature ClassTypeSignatureSuffix* ;
    // PackageSpecifier:
    //   Identifier / PackageSpecifier*
    // SimpleClassTypeSignature:
    //   Identifier [TypeArguments]
    // ClassTypeSignatureSuffix:
    //   . SimpleClassTypeSignature
    int pos = startPos;
    pos = checkChar('L', signature, pos);
    pos = checkSignatureIdentifier(signature, pos);
    while (getChar(signature, pos) == '/') {
      pos = checkSignatureIdentifier(signature, pos + 1);
    }
    if (getChar(signature, pos) == '<') {
      pos = checkTypeArguments(signature, pos);
    }
    while (getChar(signature, pos) == '.') {
      pos = checkSignatureIdentifier(signature, pos + 1);
      if (getChar(signature, pos) == '<') {
        pos = checkTypeArguments(signature, pos);
      }
    }
    return checkChar(';', signature, pos);
  }

  /**
   * Checks the type arguments in a class type signature.
   *
   * @param signature a string containing the signature that must be checked.
   * @param startPos index of first character to be checked.
   * @return the index of the first character after the checked part.
   */
  private static int checkTypeArguments(final String signature, final int startPos) {
    // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
    // TypeArguments:
    //   < TypeArgument TypeArgument* >
    int pos = startPos;
    pos = checkChar('<', signature, pos);
    pos = checkTypeArgument(signature, pos);
    while (getChar(signature, pos) != '>') {
      pos = checkTypeArgument(signature, pos);
    }
    return pos + 1;
  }

  /**
   * Checks a type argument in a class type signature.
   *
   * @param signature a string containing the signature that must be checked.
   * @param startPos index of first character to be checked.
   * @return the index of the first character after the checked part.
   */
  private static int checkTypeArgument(final String signature, final int startPos) {
    // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
    // TypeArgument:
    //   [WildcardIndicator] ReferenceTypeSignature
    //   *
    // WildcardIndicator:
    //   +
    //   -
    int pos = startPos;
    char c = getChar(signature, pos);
    if (c == '*') {
      return pos + 1;
    } else if (c == '+' || c == '-') {
      pos++;
    }
    return checkReferenceTypeSignature(signature, pos);
  }

  /**
   * Checks a type variable signature.
   *
   * @param signature a string containing the signature that must be checked.
   * @param startPos index of first character to be checked.
   * @return the index of the first character after the checked part.
   */
  private static int checkTypeVariableSignature(final String signature, final int startPos) {
    // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
    // TypeVariableSignature:
    //  T Identifier ;
    int pos = startPos;
    pos = checkChar('T', signature, pos);
    pos = checkSignatureIdentifier(signature, pos);
    return checkChar(';', signature, pos);
  }

  /**
   * Checks a Java type signature.
   *
   * @param signature a string containing the signature that must be checked.
   * @param startPos index of first character to be checked.
   * @return the index of the first character after the checked part.
   */
  private static int checkJavaTypeSignature(final String signature, final int startPos) {
    // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
    // JavaTypeSignature:
    //   ReferenceTypeSignature
    //   BaseType
    // BaseType:
    //   (one of)
    //   B C D F I J S Z
    int pos = startPos;
    switch (getChar(signature, pos)) {
      case 'B':
      case 'C':
      case 'D':
      case 'F':
      case 'I':
      case 'J':
      case 'S':
      case 'Z':
        return pos + 1;
      default:
        return checkReferenceTypeSignature(signature, pos);
    }
  }

  /**
   * Checks an identifier.
   *
   * @param signature a string containing the signature that must be checked.
   * @param startPos index of first character to be checked.
   * @return the index of the first character after the checked part.
   */
  private static int checkSignatureIdentifier(final String signature, final int startPos) {
    int pos = startPos;
    while (pos < signature.length() && ".;[/<>:".indexOf(signature.codePointAt(pos)) == -1) {
      pos = signature.offsetByCodePoints(pos, 1);
    }
    if (pos == startPos) {
      throw new IllegalArgumentException(signature + ": identifier expected at index " + startPos);
    }
    return pos;
  }

  /**
   * Checks a single character.
   *
   * @param c a character.
   * @param signature a string containing the signature that must be checked.
   * @param pos index of first character to be checked.
   * @return the index of the first character after the checked part.
   */
  private static int checkChar(final char c, final String signature, final int pos) {
    if (getChar(signature, pos) == c) {
      return pos + 1;
    }
    throw new IllegalArgumentException(signature + ": '" + c + "' expected at index " + pos);
  }

  /**
   * Returns the string character at the given index, or 0.
   *
   * @param string a string.
   * @param pos an index in 'string'.
   * @return the character at the given index, or 0 if there is no such character.
   */
  private static char getChar(final String string, final int pos) {
    return pos < string.length() ? string.charAt(pos) : (char) 0;
  }

  /**
   * Checks the reference to a type in a type annotation.
   *
   * @param typeRef a reference to an annotated type.
   */
  static void checkTypeRef(final int typeRef) {
    int mask = 0;
    switch (typeRef >>> 24) {
      case TypeReference.CLASS_TYPE_PARAMETER:
      case TypeReference.METHOD_TYPE_PARAMETER:
      case TypeReference.METHOD_FORMAL_PARAMETER:
        mask = 0xFFFF0000;
        break;
      case TypeReference.FIELD:
      case TypeReference.METHOD_RETURN:
      case TypeReference.METHOD_RECEIVER:
      case TypeReference.LOCAL_VARIABLE:
      case TypeReference.RESOURCE_VARIABLE:
      case TypeReference.INSTANCEOF:
      case TypeReference.NEW:
      case TypeReference.CONSTRUCTOR_REFERENCE:
      case TypeReference.METHOD_REFERENCE:
        mask = 0xFF000000;
        break;
      case TypeReference.CLASS_EXTENDS:
      case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
      case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
      case TypeReference.THROWS:
      case TypeReference.EXCEPTION_PARAMETER:
        mask = 0xFFFFFF00;
        break;
      case TypeReference.CAST:
      case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
      case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
      case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
      case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
        mask = 0xFF0000FF;
        break;
      default:
        throw new AssertionError();
    }
    if ((typeRef & ~mask) != 0) {
      throw new IllegalArgumentException(
          "Invalid type reference 0x" + Integer.toHexString(typeRef));
    }
  }

  /**
   * Returns the package name of an internal name.
   *
   * @param name an internal name.
   * @return the package name or "" if there is no package.
   */
  private static String packageName(final String name) {
    int index = name.lastIndexOf('/');
    if (index == -1) {
      return "";
    }
    return name.substring(0, index);
  }

  // -----------------------------------------------------------------------------------------------
  // Static verification methods
  // -----------------------------------------------------------------------------------------------

  /**
   * Checks the given class.
   *
   * <p>Usage: CheckClassAdapter &lt;binary class name or class file name&gt;
   *
   * @param args the command line arguments.
   * @throws IOException if the class cannot be found, or if an IO exception occurs.
   */
  public static void main(final String[] args) throws IOException {
    main(args, new PrintWriter(System.err, true));
  }

  /**
   * Checks the given class.
   *
   * @param args the command line arguments.
   * @param logger where to log errors.
   * @throws IOException if the class cannot be found, or if an IO exception occurs.
   */
  static void main(final String[] args, final PrintWriter logger) throws IOException {
    if (args.length != 1) {
      logger.println(USAGE);
      return;
    }

    ClassReader classReader;
    if (args[0].endsWith(".class")) {
      InputStream inputStream =
          new FileInputStream(args[0]); // NOPMD(AvoidFileStream): can't fix for 1.5 compatibility
      classReader = new ClassReader(inputStream);
    } else {
      classReader = new ClassReader(args[0]);
    }

    verify(classReader, false, logger);
  }

  /**
   * Checks the given class.
   *
   * @param classReader the class to be checked.
   * @param printResults whether to print the results of the bytecode verification.
   * @param printWriter where the results (or the stack trace in case of error) must be printed.
   */
  public static void verify(
      final ClassReader classReader, final boolean printResults, final PrintWriter printWriter) {
    verify(classReader, null, printResults, printWriter);
  }

  /**
   * Checks the given class.
   *
   * @param classReader the class to be checked.
   * @param loader a <code>ClassLoader</code> which will be used to load referenced classes. May be
   *     {@literal null}.
   * @param printResults whether to print the results of the bytecode verification.
   * @param printWriter where the results (or the stack trace in case of error) must be printed.
   */
  public static void verify(
      final ClassReader classReader,
      final ClassLoader loader,
      final boolean printResults,
      final PrintWriter printWriter) {
    ClassNode classNode = new ClassNode();
    classReader.accept(
        new CheckClassAdapter(Opcodes.ASM9_EXPERIMENTAL, classNode, false) {},
        ClassReader.SKIP_DEBUG);

    Type syperType = classNode.superName == null ? null : Type.getObjectType(classNode.superName);
    List<MethodNode> methods = classNode.methods;

    List<Type> interfaces = new ArrayList<>();
    for (String interfaceName : classNode.interfaces) {
      interfaces.add(Type.getObjectType(interfaceName));
    }

    for (MethodNode method : methods) {
      SimpleVerifier verifier =
          new SimpleVerifier(
              Type.getObjectType(classNode.name),
              syperType,
              interfaces,
              (classNode.access & Opcodes.ACC_INTERFACE) != 0);
      Analyzer<BasicValue> analyzer = new Analyzer<>(verifier);
      if (loader != null) {
        verifier.setClassLoader(loader);
      }
      try {
        analyzer.analyze(classNode.name, method);
      } catch (AnalyzerException e) {
        e.printStackTrace(printWriter);
      }
      if (printResults) {
        printAnalyzerResult(method, analyzer, printWriter);
      }
    }
    printWriter.flush();
  }

  static void printAnalyzerResult(
      final MethodNode method, final Analyzer<BasicValue> analyzer, final PrintWriter printWriter) {
    Textifier textifier = new Textifier();
    TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(textifier);

    printWriter.println(method.name + method.desc);
    for (int i = 0; i < method.instructions.size(); ++i) {
      method.instructions.get(i).accept(traceMethodVisitor);

      StringBuilder stringBuilder = new StringBuilder();
      Frame<BasicValue> frame = analyzer.getFrames()[i];
      if (frame == null) {
        stringBuilder.append('?');
      } else {
        for (int j = 0; j < frame.getLocals(); ++j) {
          stringBuilder.append(getUnqualifiedName(frame.getLocal(j).toString())).append(' ');
        }
        stringBuilder.append(" : ");
        for (int j = 0; j < frame.getStackSize(); ++j) {
          stringBuilder.append(getUnqualifiedName(frame.getStack(j).toString())).append(' ');
        }
      }
      while (stringBuilder.length() < method.maxStack + method.maxLocals + 1) {
        stringBuilder.append(' ');
      }
      printWriter.print(Integer.toString(i + 100000).substring(1));
      printWriter.print(
          " " + stringBuilder + " : " + textifier.text.get(textifier.text.size() - 1));
    }
    for (TryCatchBlockNode tryCatchBlock : method.tryCatchBlocks) {
      tryCatchBlock.accept(traceMethodVisitor);
      printWriter.print(" " + textifier.text.get(textifier.text.size() - 1));
    }
    printWriter.println();
  }

  private static String getUnqualifiedName(final String name) {
    int lastSlashIndex = name.lastIndexOf('/');
    if (lastSlashIndex == -1) {
      return name;
    } else {
      int endIndex = name.length();
      if (name.charAt(endIndex - 1) == ';') {
        endIndex--;
      }
      return name.substring(lastSlashIndex + 1, endIndex);
    }
  }
}
