// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// classfile.cc -- classfile parsing and stripping.
//

// TODO(adonovan) don't pass pointers by reference; this is not
// compatible with Google C++ style.

// See README.txt for details.
//
// For definition of JVM class file format, see:
// Java SE 8 Edition:
// http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4

#define __STDC_FORMAT_MACROS 1
#define __STDC_LIMIT_MACROS 1
#include <inttypes.h> // for PRIx32
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <set>
#include <sstream>
#include <string>
#include <vector>

#include "third_party/ijar/common.h"

namespace {
// Converts a value to string.
// Workaround for mingw where std::to_string is not implemented.
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52015.
template <typename T>
std::string ToString(const T& value) {
  std::ostringstream oss;
  oss << value;
  return oss.str();
}
}  // namespace

namespace devtools_ijar {

// See Table 4.3 in JVM Spec.
enum CONSTANT {
  CONSTANT_Class              = 7,
  CONSTANT_FieldRef           = 9,
  CONSTANT_Methodref          = 10,
  CONSTANT_Interfacemethodref = 11,
  CONSTANT_String             = 8,
  CONSTANT_Integer            = 3,
  CONSTANT_Float              = 4,
  CONSTANT_Long               = 5,
  CONSTANT_Double             = 6,
  CONSTANT_NameAndType        = 12,
  CONSTANT_Utf8               = 1,
  CONSTANT_MethodHandle       = 15,
  CONSTANT_MethodType         = 16,
  CONSTANT_InvokeDynamic      = 18
};

// See Tables 4.1, 4.4, 4.5 in JVM Spec.
enum ACCESS {
  ACC_PUBLIC = 0x0001,
  ACC_PRIVATE = 0x0002,
  ACC_PROTECTED = 0x0004,
  ACC_STATIC = 0x0008,
  ACC_FINAL = 0x0010,
  ACC_SYNCHRONIZED = 0x0020,
  ACC_BRIDGE = 0x0040,
  ACC_VOLATILE = 0x0040,
  ACC_TRANSIENT = 0x0080,
  ACC_INTERFACE = 0x0200,
  ACC_ABSTRACT = 0x0400,
  ACC_SYNTHETIC = 0x1000
};

// See Table 4.7.20-A in Java 8 JVM Spec.
enum TARGET_TYPE {
  // Targets for type parameter declarations (ElementType.TYPE_PARAMETER):
  CLASS_TYPE_PARAMETER        = 0x00,
  METHOD_TYPE_PARAMETER       = 0x01,

  // Targets for type uses that may be externally visible in classes and members
  // (ElementType.TYPE_USE):
  CLASS_EXTENDS               = 0x10,
  CLASS_TYPE_PARAMETER_BOUND  = 0x11,
  METHOD_TYPE_PARAMETER_BOUND = 0x12,
  FIELD                       = 0x13,
  METHOD_RETURN               = 0x14,
  METHOD_RECEIVER             = 0x15,
  METHOD_FORMAL_PARAMETER     = 0x16,
  THROWS                      = 0x17,

  // TARGET_TYPE >= 0x40 is reserved for type uses that occur only within code
  // blocks. Ijar doesn't need to know about these.
};

struct Constant;

// TODO(adonovan) these globals are unfortunate
static std::vector<Constant*>        const_pool_in; // input constant pool
static std::vector<Constant*>        const_pool_out; // output constant_pool
static std::set<std::string>         used_class_names;
static Constant *                    class_name;

// Returns the Constant object, given an index into the input constant pool.
// Note: constant(0) == NULL; this invariant is exploited by the
// InnerClassesAttribute, inter alia.
inline Constant *constant(int idx) {
  if (idx < 0 || (unsigned)idx >= const_pool_in.size()) {
    fprintf(stderr, "Illegal constant pool index: %d\n", idx);
    abort();
  }
  return const_pool_in[idx];
}

/**********************************************************************
 *                                                                    *
 *                             Constants                              *
 *                                                                    *
 **********************************************************************/

// See sec.4.4 of JVM spec.
struct Constant {

  Constant(u1 tag) :
      slot_(0),
      tag_(tag) {}

  virtual ~Constant() {}

  // For UTF-8 string constants, returns the encoded string.
  // Otherwise, returns an undefined string value suitable for debugging.
  virtual std::string Display() = 0;

  virtual void Write(u1 *&p) = 0;

  // Called by slot() when a constant has been identified as required
  // in the output classfile's constant pool.  This is a hook allowing
  // constants to register their dependency on other constants, by
  // calling slot() on them in turn.
  virtual void Keep() {}

  bool Kept() {
    return slot_ != 0;
  }

  // Returns the index of this constant in the output class's constant
  // pool, assigning a slot if not already done.
  u2 slot() {
    if (slot_ == 0) {
      Keep();
      slot_ = const_pool_out.size(); // BugBot's "narrowing" warning
                                     // is bogus.  The number of
                                     // output constants can't exceed
                                     // the number of input constants.
      if (slot_ == 0) {
        fprintf(stderr, "Constant::slot() called before output phase.\n");
        abort();
      }
      const_pool_out.push_back(this);
      if (tag_ == CONSTANT_Long || tag_ == CONSTANT_Double) {
        const_pool_out.push_back(NULL);
      }
    }
    return slot_;
  }

  u2 slot_; // zero => "this constant is unreachable garbage"
  u1 tag_;
};

// Extracts class names from a signature and puts them into the global
// variable used_class_names.
//
// desc: the descriptor class names should be extracted from.
// p: the position where the extraction should tart.
void ExtractClassNames(const std::string& desc, size_t* p);

// See sec.4.4.1 of JVM spec.
struct Constant_Class : Constant
{
  Constant_Class(u2 name_index) :
      Constant(CONSTANT_Class),
      name_index_(name_index) {}

  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u2be(p, constant(name_index_)->slot());
  }

  std::string Display() {
    return constant(name_index_)->Display();
  }

  void Keep() { constant(name_index_)->slot(); }

  u2 name_index_;
};

// See sec.4.4.2 of JVM spec.
struct Constant_FMIref : Constant
{
  Constant_FMIref(u1 tag,
                  u2 class_index,
                  u2 name_type_index) :
      Constant(tag),
      class_index_(class_index),
      name_type_index_(name_type_index) {}

  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u2be(p, constant(class_index_)->slot());
    put_u2be(p, constant(name_type_index_)->slot());
  }

  std::string Display() {
    return constant(class_index_)->Display() + "::" +
        constant(name_type_index_)->Display();
  }

  void Keep() {
    constant(class_index_)->slot();
    constant(name_type_index_)->slot();
  }

  u2 class_index_;
  u2 name_type_index_;
};

// See sec.4.4.3 of JVM spec.
struct Constant_String : Constant
{
  Constant_String(u2 string_index) :
      Constant(CONSTANT_String),
      string_index_(string_index) {}

  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u2be(p, constant(string_index_)->slot());
  }

  std::string Display() {
    return "\"" + constant(string_index_)->Display() + "\"";
  }

  void Keep() { constant(string_index_)->slot(); }

  u2 string_index_;
};

// See sec.4.4.4 of JVM spec.
struct Constant_IntegerOrFloat : Constant
{
  Constant_IntegerOrFloat(u1 tag, u4 bytes) :
      Constant(tag),
      bytes_(bytes) {}

  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u4be(p, bytes_);
  }

  std::string Display() { return "int/float"; }

  u4 bytes_;
};

// See sec.4.4.5 of JVM spec.
struct Constant_LongOrDouble : Constant_IntegerOrFloat
{
  Constant_LongOrDouble(u1 tag, u4 high_bytes, u4 low_bytes) :
      Constant_IntegerOrFloat(tag, high_bytes),
      low_bytes_(low_bytes) {}

  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u4be(p, bytes_);
    put_u4be(p, low_bytes_);
  }

  std::string Display() { return "long/double"; }

  u4 low_bytes_;
};

// See sec.4.4.6 of JVM spec.
struct Constant_NameAndType : Constant
{
  Constant_NameAndType(u2 name_index, u2 descr_index) :
      Constant(CONSTANT_NameAndType),
      name_index_(name_index),
      descr_index_(descr_index) {}

  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u2be(p, constant(name_index_)->slot());
    put_u2be(p, constant(descr_index_)->slot());
  }

  std::string Display() {
    return constant(name_index_)->Display() + "::" +
        constant(descr_index_)->Display();
  }

  void Keep() {
    constant(name_index_)->slot();
    constant(descr_index_)->slot();
  }

  u2 name_index_;
  u2 descr_index_;
};

// See sec.4.4.7 of JVM spec.
struct Constant_Utf8 : Constant
{
  Constant_Utf8(u4 length, const u1 *utf8) :
      Constant(CONSTANT_Utf8),
      length_(length),
      utf8_(utf8) {}

  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u2be(p, length_);
    put_n(p, utf8_, length_);
  }

  std::string Display() {
    return std::string((const char*) utf8_, length_);
  }

  u4 length_;
  const u1 *utf8_;
};

// See sec.4.4.8 of JVM spec.
struct Constant_MethodHandle : Constant
{
  Constant_MethodHandle(u1 reference_kind, u2 reference_index) :
      Constant(CONSTANT_MethodHandle),
      reference_kind_(reference_kind),
      reference_index_(reference_index) {}

  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u1(p, reference_kind_);
    put_u2be(p, reference_index_);
  }

  std::string Display() {
    return "Constant_MethodHandle::" + ToString(reference_kind_) + "::"
        + constant(reference_index_)->Display();
  }

  u1 reference_kind_;
  u2 reference_index_;
};

// See sec.4.4.9 of JVM spec.
struct Constant_MethodType : Constant
{
  Constant_MethodType(u2 descriptor_index) :
      Constant(CONSTANT_MethodType),
      descriptor_index_(descriptor_index) {}

  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u2be(p, descriptor_index_);
  }

  std::string Display() {
    return  "Constant_MethodType::" + constant(descriptor_index_)->Display();
  }

  u2 descriptor_index_;
};

// See sec.4.4.10 of JVM spec.
struct Constant_InvokeDynamic : Constant
{
  Constant_InvokeDynamic(u2 bootstrap_method_attr_index, u2 name_and_type_index) :
      Constant(CONSTANT_InvokeDynamic),
      bootstrap_method_attr_index_(bootstrap_method_attr_index),
      name_and_type_index_(name_and_type_index) {}

  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u2be(p, bootstrap_method_attr_index_);
    put_u2be(p, name_and_type_index_);
  }

  std::string Display() {
    return  "Constant_InvokeDynamic::"
        + ToString(bootstrap_method_attr_index_) + "::"
        + constant(name_and_type_index_)->Display();
  }

  u2 bootstrap_method_attr_index_;
  u2 name_and_type_index_;
};

/**********************************************************************
 *                                                                    *
 *                             Attributes                             *
 *                                                                    *
 **********************************************************************/

// See sec.4.7 of JVM spec.
struct Attribute {

  virtual ~Attribute() {}
  virtual void Write(u1 *&p) = 0;
  virtual void ExtractClassNames() {}
  virtual bool KeepForCompile() const { return false; }

  void WriteProlog(u1 *&p, u2 length) {
    put_u2be(p, attribute_name_->slot());
    put_u4be(p, length);
  }

  Constant *attribute_name_;
};

struct HasAttrs {
  std::vector<Attribute*> attributes;

  void WriteAttrs(u1 *&p);
  void ReadAttrs(const u1 *&p);

  virtual ~HasAttrs() {
    for (const auto *attribute : attributes) {
      delete attribute;
    }
  }

  void ExtractClassNames() {
    for (auto *attribute : attributes) {
      attribute->ExtractClassNames();
    }
  }
};

// See sec.4.7.5 of JVM spec.
struct ExceptionsAttribute : Attribute {

  static ExceptionsAttribute* Read(const u1 *&p, Constant *attribute_name) {
    ExceptionsAttribute *attr = new ExceptionsAttribute;
    attr->attribute_name_ = attribute_name;
    u2 number_of_exceptions = get_u2be(p);
    for (int ii = 0; ii < number_of_exceptions; ++ii) {
      attr->exceptions_.push_back(constant(get_u2be(p)));
    }
    return attr;
  }

  void Write(u1 *&p) {
    WriteProlog(p, exceptions_.size() * 2 + 2);
    put_u2be(p, exceptions_.size());
    for (size_t ii = 0; ii < exceptions_.size(); ++ii) {
      put_u2be(p, exceptions_[ii]->slot());
    }
  }

  std::vector<Constant*> exceptions_;
};

// See sec.4.7.6 of JVM spec.
struct InnerClassesAttribute : Attribute {

  struct Entry {
    Constant *inner_class_info;
    Constant *outer_class_info;
    Constant *inner_name;
    u2 inner_class_access_flags;
  };

  virtual ~InnerClassesAttribute() {
    for (size_t i = 0; i < entries_.size(); i++) {
      delete entries_[i];
    }
  }

  static InnerClassesAttribute* Read(const u1 *&p, Constant *attribute_name) {
    InnerClassesAttribute *attr = new InnerClassesAttribute;
    attr->attribute_name_ = attribute_name;

    u2 number_of_classes = get_u2be(p);
    for (int ii = 0; ii < number_of_classes; ++ii) {
      Entry *entry = new Entry;
      entry->inner_class_info = constant(get_u2be(p));
      entry->outer_class_info = constant(get_u2be(p));
      entry->inner_name = constant(get_u2be(p));
      entry->inner_class_access_flags = get_u2be(p);

      attr->entries_.push_back(entry);
    }
    return attr;
  }

  void Write(u1 *&p) {
    std::set<int> kept_entries;
    // We keep an entry if the constant referring to the inner class is already
    // kept. Then we mark its outer class and its class name as kept, too, then
    // iterate until a fixed point is reached.
    int entry_count;

    do {
      entry_count = kept_entries.size();
      for (int i_entry = 0; i_entry < static_cast<int>(entries_.size());
           ++i_entry) {
        Entry* entry = entries_[i_entry];
        if (entry->inner_class_info->Kept() ||
            used_class_names.find(entry->inner_class_info->Display()) !=
                used_class_names.end() ||
            entry->outer_class_info == class_name) {
          if (entry->inner_name == NULL) {
            // JVMS 4.7.6: inner_name_index is zero iff the class is anonymous
            continue;
          }

          kept_entries.insert(i_entry);

          // JVMS 4.7.6: outer_class_info_index is zero for top-level classes
          if (entry->outer_class_info != NULL) {
            entry->outer_class_info->slot();
          }

          entry->inner_name->slot();
        }
      }
    } while (entry_count != static_cast<int>(kept_entries.size()));

    if (kept_entries.empty()) {
      return;
    }

    WriteProlog(p, 2 + kept_entries.size() * 8);
    put_u2be(p, kept_entries.size());

    for (std::set<int>::iterator it = kept_entries.begin();
         it != kept_entries.end();
         ++it) {
      Entry *entry = entries_[*it];
      put_u2be(p, entry->inner_class_info == NULL
               ? 0
               : entry->inner_class_info->slot());
      put_u2be(p, entry->outer_class_info == NULL
               ? 0
               : entry->outer_class_info->slot());
      put_u2be(p, entry->inner_name == NULL
               ? 0
               : entry->inner_name->slot());
      put_u2be(p, entry->inner_class_access_flags);
    }
  }

  std::vector<Entry*> entries_;
};

// See sec.4.7.7 of JVM spec.
// We preserve EnclosingMethod attributes to be able to identify local and
// anonymous classes. These classes will be stripped of most content, as they
// represent implementation details that shoudn't leak into the ijars. Omitting
// EnclosingMethod attributes can lead to type-checking failures in the presence
// of generics (see b/9070939).
struct EnclosingMethodAttribute : Attribute {

  static EnclosingMethodAttribute* Read(const u1 *&p,
                                        Constant *attribute_name) {
    EnclosingMethodAttribute *attr = new EnclosingMethodAttribute;
    attr->attribute_name_ = attribute_name;
    attr->class_ = constant(get_u2be(p));
    attr->method_ = constant(get_u2be(p));
    return attr;
  }

  void Write(u1 *&p) {
    WriteProlog(p, 4);
    put_u2be(p, class_->slot());
    put_u2be(p, method_ == NULL ? 0 : method_->slot());
  }

  Constant *class_;
  Constant *method_;
};

// See sec.4.7.16.1 of JVM spec.
// Used by AnnotationDefault and other attributes.
struct ElementValue {
  virtual ~ElementValue() {}
  virtual void Write(u1 *&p) = 0;
  virtual void ExtractClassNames() {}
  static ElementValue* Read(const u1 *&p);
  u1 tag_;
  u4 length_;
};

struct BaseTypeElementValue : ElementValue {
  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u2be(p, const_value_->slot());
  }
  static BaseTypeElementValue *Read(const u1 *&p) {
    BaseTypeElementValue *value = new BaseTypeElementValue;
    value->const_value_ = constant(get_u2be(p));
    return value;
  }
  Constant *const_value_;
};

struct EnumTypeElementValue : ElementValue {
  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u2be(p, type_name_->slot());
    put_u2be(p, const_name_->slot());
  }
  static EnumTypeElementValue *Read(const u1 *&p) {
    EnumTypeElementValue *value = new EnumTypeElementValue;
    value->type_name_ = constant(get_u2be(p));
    value->const_name_ = constant(get_u2be(p));
    return value;
  }
  Constant *type_name_;
  Constant *const_name_;
};

struct ClassTypeElementValue : ElementValue {
  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u2be(p, class_info_->slot());
  }

  virtual void ExtractClassNames() {
    size_t idx = 0;
    devtools_ijar::ExtractClassNames(class_info_->Display(), &idx);
  }

  static ClassTypeElementValue *Read(const u1 *&p) {
    ClassTypeElementValue *value = new ClassTypeElementValue;
    value->class_info_ = constant(get_u2be(p));
    return value;
  }
  Constant *class_info_;
};

struct ArrayTypeElementValue : ElementValue {
  virtual ~ArrayTypeElementValue() {
    for (const auto *value : values_) {
      delete value;
    }
  }

  virtual void ExtractClassNames() {
    for (auto *value : values_) {
      value->ExtractClassNames();
    }
  }

  void Write(u1 *&p) {
    put_u1(p, tag_);
    put_u2be(p, values_.size());
    for (auto *value : values_) {
      value->Write(p);
    }
  }
  static ArrayTypeElementValue *Read(const u1 *&p) {
    ArrayTypeElementValue *value = new ArrayTypeElementValue;
    u2 num_values = get_u2be(p);
    for (int ii = 0; ii < num_values; ++ii) {
      value->values_.push_back(ElementValue::Read(p));
    }
    return value;
  }
  std::vector<ElementValue*> values_;
};

// See sec.4.7.16 of JVM spec.
struct Annotation {
  virtual ~Annotation() {
    for (size_t i = 0; i < element_value_pairs_.size(); i++) {
      delete element_value_pairs_[i]->element_value_;
      delete element_value_pairs_[i];
    }
  }

  void ExtractClassNames() {
    for (size_t i = 0; i < element_value_pairs_.size(); i++) {
      element_value_pairs_[i]->element_value_->ExtractClassNames();
    }
  }

  void Write(u1 *&p) {
    put_u2be(p, type_->slot());
    put_u2be(p, element_value_pairs_.size());
    for (size_t ii = 0; ii < element_value_pairs_.size(); ++ii) {
      put_u2be(p, element_value_pairs_[ii]->element_name_->slot());
      element_value_pairs_[ii]->element_value_->Write(p);
    }
  }
  static Annotation *Read(const u1 *&p) {
    Annotation *value = new Annotation;
    value->type_ = constant(get_u2be(p));
    u2 num_element_value_pairs = get_u2be(p);
    for (int ii = 0; ii < num_element_value_pairs; ++ii) {
      ElementValuePair *pair = new ElementValuePair;
      pair->element_name_ = constant(get_u2be(p));
      pair->element_value_ = ElementValue::Read(p);
      value->element_value_pairs_.push_back(pair);
    }
    return value;
  }
  Constant *type_;
  struct ElementValuePair {
    Constant *element_name_;
    ElementValue *element_value_;
  };
  std::vector<ElementValuePair*> element_value_pairs_;
};

// See sec 4.7.20 of Java 8 JVM Spec
//
// Each entry in the annotations table represents a single run-time visible
// annotation on a type used in a declaration or expression. The type_annotation
// structure has the following format:
//
// type_annotation {
//   u1 target_type;
//   union {
//     type_parameter_target;
//     supertype_target;
//     type_parameter_bound_target;
//     empty_target;
//     method_formal_parameter_target;
//     throws_target;
//     localvar_target;
//     catch_target;
//     offset_target;
//     type_argument_target;
//   } target_info;
//   type_path target_path;
//   u2        type_index;
//   u2        num_element_value_pairs;
//   {
//     u2            element_name_index;
//     element_value value;
//   }
//   element_value_pairs[num_element_value_pairs];
// }
//
struct TypeAnnotation {
  virtual ~TypeAnnotation() {
    delete target_info_;
    delete type_path_;
    delete annotation_;
  }

  void ExtractClassNames() {
    annotation_->ExtractClassNames();
  }

  void Write(u1 *&p) {
    put_u1(p, target_type_);
    target_info_->Write(p);
    type_path_->Write(p);
    annotation_->Write(p);
  }

  static TypeAnnotation *Read(const u1 *&p) {
    TypeAnnotation *value = new TypeAnnotation;
    value->target_type_ = get_u1(p);
    value->target_info_ = ReadTargetInfo(p, value->target_type_);
    value->type_path_ = TypePath::Read(p);
    value->annotation_ = Annotation::Read(p);
    return value;
  }

  struct TargetInfo {
    virtual ~TargetInfo() {}
    virtual void Write(u1 *&p) = 0;
  };

  struct TypeParameterTargetInfo : TargetInfo {
    void Write(u1 *&p) {
      put_u1(p, type_parameter_index_);
    }
    static TypeParameterTargetInfo *Read(const u1 *&p) {
      TypeParameterTargetInfo *value = new TypeParameterTargetInfo;
      value->type_parameter_index_ = get_u1(p);
      return value;
    }
    u1 type_parameter_index_;
  };

  struct ClassExtendsInfo : TargetInfo {
    void Write(u1 *&p) {
      put_u2be(p, supertype_index_);
    }
    static ClassExtendsInfo *Read(const u1 *&p) {
      ClassExtendsInfo *value = new ClassExtendsInfo;
      value->supertype_index_ = get_u2be(p);
      return value;
    }
    u2 supertype_index_;
  };

  struct TypeParameterBoundInfo : TargetInfo {
    void Write(u1 *&p) {
      put_u1(p, type_parameter_index_);
      put_u1(p, bound_index_);
    }
    static TypeParameterBoundInfo *Read(const u1 *&p) {
      TypeParameterBoundInfo *value = new TypeParameterBoundInfo;
      value->type_parameter_index_ = get_u1(p);
      value->bound_index_ = get_u1(p);
      return value;
    }
    u1 type_parameter_index_;
    u1 bound_index_;
  };

  struct EmptyInfo : TargetInfo {
    void Write(u1 *& /*p*/) {}
    static EmptyInfo *Read(const u1 *& /*p*/) { return new EmptyInfo; }
  };

  struct MethodFormalParameterInfo : TargetInfo {
    void Write(u1 *&p) {
      put_u1(p, method_formal_parameter_index_);
    }
    static MethodFormalParameterInfo *Read(const u1 *&p) {
      MethodFormalParameterInfo *value = new MethodFormalParameterInfo;
      value->method_formal_parameter_index_ = get_u1(p);
      return value;
    }
    u1 method_formal_parameter_index_;
  };

  struct ThrowsTypeInfo : TargetInfo {
    void Write(u1 *&p) {
      put_u2be(p, throws_type_index_);
    }
    static ThrowsTypeInfo *Read(const u1 *&p) {
      ThrowsTypeInfo *value = new ThrowsTypeInfo;
      value->throws_type_index_ = get_u2be(p);
      return value;
    }
    u2 throws_type_index_;
  };

  static TargetInfo *ReadTargetInfo(const u1 *&p, u1 target_type) {
    switch (target_type) {
      case CLASS_TYPE_PARAMETER:
      case METHOD_TYPE_PARAMETER:
        return TypeParameterTargetInfo::Read(p);
      case CLASS_EXTENDS:
        return ClassExtendsInfo::Read(p);
      case CLASS_TYPE_PARAMETER_BOUND:
      case METHOD_TYPE_PARAMETER_BOUND:
        return TypeParameterBoundInfo::Read(p);
      case FIELD:
      case METHOD_RETURN:
      case METHOD_RECEIVER:
        return new EmptyInfo;
      case METHOD_FORMAL_PARAMETER:
        return MethodFormalParameterInfo::Read(p);
      case THROWS:
        return ThrowsTypeInfo::Read(p);
      default:
        fprintf(stderr, "Illegal type annotation target type: %d\n",
                target_type);
        abort();
    }
  }

  struct TypePath {
    void Write(u1 *&p) {
      put_u1(p, path_.size());
      for (TypePathEntry entry : path_) {
        put_u1(p, entry.type_path_kind_);
        put_u1(p, entry.type_argument_index_);
      }
    }
    static TypePath *Read(const u1 *&p) {
      TypePath *value = new TypePath;
      u1 path_length = get_u1(p);
      for (int ii = 0; ii < path_length; ++ii) {
        TypePathEntry entry;
        entry.type_path_kind_ = get_u1(p);
        entry.type_argument_index_ = get_u1(p);
        value->path_.push_back(entry);
      }
      return value;
    }

    struct TypePathEntry {
      u1 type_path_kind_;
      u1 type_argument_index_;
    };
    std::vector<TypePathEntry> path_;
  };

  u1 target_type_;
  TargetInfo *target_info_;
  TypePath *type_path_;
  Annotation *annotation_;
};

struct AnnotationTypeElementValue : ElementValue {
  virtual ~AnnotationTypeElementValue() {
    delete annotation_;
  }

  void Write(u1 *&p) {
    put_u1(p, tag_);
    annotation_->Write(p);
  }
  static AnnotationTypeElementValue *Read(const u1 *&p) {
    AnnotationTypeElementValue *value = new AnnotationTypeElementValue;
    value->annotation_ = Annotation::Read(p);
    return value;
  }

  Annotation *annotation_;
};

ElementValue* ElementValue::Read(const u1 *&p) {
  const u1* start = p;
  ElementValue *result;
  u1 tag = get_u1(p);
  if (tag != 0 && strchr("BCDFIJSZs", (char) tag) != NULL) {
    result = BaseTypeElementValue::Read(p);
  } else if ((char) tag == 'e') {
    result = EnumTypeElementValue::Read(p);
  } else if ((char) tag == 'c') {
    result = ClassTypeElementValue::Read(p);
  } else if ((char) tag == '[') {
    result = ArrayTypeElementValue::Read(p);
  } else if ((char) tag == '@') {
    result = AnnotationTypeElementValue::Read(p);
  } else {
    fprintf(stderr, "Illegal element_value::tag: %d\n", tag);
    abort();
  }
  result->tag_ = tag;
  result->length_ = p - start;
  return result;
}

// See sec.4.7.20 of JVM spec.
// We preserve AnnotationDefault attributes because they are required
// in order to make use of an annotation in new code.
struct AnnotationDefaultAttribute : Attribute {
  virtual ~AnnotationDefaultAttribute() {
    delete default_value_;
  }

  static AnnotationDefaultAttribute* Read(const u1 *&p,
                                          Constant *attribute_name) {
    AnnotationDefaultAttribute *attr = new AnnotationDefaultAttribute;
    attr->attribute_name_ = attribute_name;
    attr->default_value_ = ElementValue::Read(p);
    return attr;
  }

  void Write(u1 *&p) {
    WriteProlog(p, default_value_->length_);
    default_value_->Write(p);
  }

  virtual void ExtractClassNames() {
    default_value_->ExtractClassNames();
  }

  ElementValue *default_value_;
};

// See sec.4.7.2 of JVM spec.
// We preserve ConstantValue attributes because they are required for
// compile-time constant propagation.
struct ConstantValueAttribute : Attribute {

  static ConstantValueAttribute* Read(const u1 *&p, Constant *attribute_name) {
    ConstantValueAttribute *attr = new ConstantValueAttribute;
    attr->attribute_name_ = attribute_name;
    attr->constantvalue_ = constant(get_u2be(p));
    return attr;
  }

  void Write(u1 *&p) {
    WriteProlog(p, 2);
    put_u2be(p, constantvalue_->slot());
  }

  Constant *constantvalue_;
};

// See sec.4.7.9 of JVM spec.
// We preserve Signature attributes because they are required by the
// compiler for type-checking of generics.
struct SignatureAttribute : Attribute {

  static SignatureAttribute* Read(const u1 *&p, Constant *attribute_name) {
    SignatureAttribute *attr = new SignatureAttribute;
    attr->attribute_name_ = attribute_name;
    attr->signature_  = constant(get_u2be(p));
    return attr;
  }

  void Write(u1 *&p) {
    WriteProlog(p, 2);
    put_u2be(p, signature_->slot());
  }

  virtual void ExtractClassNames() {
    size_t signature_idx = 0;
    devtools_ijar::ExtractClassNames(signature_->Display(), &signature_idx);
  }

  Constant *signature_;
};

// See sec.4.7.15 of JVM spec.
// We preserve Deprecated attributes because they are required by the
// compiler to generate warning messages.
struct DeprecatedAttribute : Attribute {
  static DeprecatedAttribute *Read(const u1 *& /*p*/,
                                   Constant *attribute_name) {
    DeprecatedAttribute *attr = new DeprecatedAttribute;
    attr->attribute_name_ = attribute_name;
    return attr;
  }

  void Write(u1 *&p) {
    WriteProlog(p, 0);
  }
};

// See sec.4.7.16-17 of JVM spec v3.  Includes RuntimeVisible and
// RuntimeInvisible.
//
// We preserve all annotations.
struct AnnotationsAttribute : Attribute {
  virtual ~AnnotationsAttribute() {
    for (size_t i = 0; i < annotations_.size(); i++) {
      delete annotations_[i];
    }
  }

  static AnnotationsAttribute* Read(const u1 *&p, Constant *attribute_name) {
    AnnotationsAttribute *attr = new AnnotationsAttribute;
    attr->attribute_name_ = attribute_name;
    u2 num_annotations = get_u2be(p);
    for (int ii = 0; ii < num_annotations; ++ii) {
      Annotation *annotation = Annotation::Read(p);
      attr->annotations_.push_back(annotation);
    }
    return attr;
  }

  virtual void ExtractClassNames() {
    for (auto *annotation : annotations_) {
      annotation->ExtractClassNames();
    }
  }

  virtual bool KeepForCompile() const {
    for (auto *annotation : annotations_) {
      if (annotation->type_->Display() == "Lkotlin/Metadata;") {
        return true;
      }
    }
    return false;
  }

  void Write(u1 *&p) {
    WriteProlog(p, -1);
    u1 *payload_start = p - 4;
    put_u2be(p, annotations_.size());
    for (auto *annotation : annotations_) {
      annotation->Write(p);
    }
    put_u4be(payload_start, p - 4 - payload_start);  // backpatch length
  }

  std::vector<Annotation*> annotations_;
};

// See sec.4.7.18-19 of JVM spec.  Includes RuntimeVisible and
// RuntimeInvisible.
//
// We preserve all annotations.
struct ParameterAnnotationsAttribute : Attribute {

  static ParameterAnnotationsAttribute* Read(const u1 *&p,
                                             Constant *attribute_name) {
    ParameterAnnotationsAttribute *attr = new ParameterAnnotationsAttribute;
    attr->attribute_name_ = attribute_name;
    u1 num_parameters = get_u1(p);
    for (int ii = 0; ii < num_parameters; ++ii) {
      std::vector<Annotation*> annotations;
      u2 num_annotations = get_u2be(p);
      for (int ii = 0; ii < num_annotations; ++ii) {
        Annotation *annotation = Annotation::Read(p);
        annotations.push_back(annotation);
      }
      attr->parameter_annotations_.push_back(annotations);
    }
    return attr;
  }

  virtual void ExtractClassNames() {
    for (size_t i = 0; i < parameter_annotations_.size(); i++) {
      const std::vector<Annotation*>& annotations = parameter_annotations_[i];
      for (size_t j = 0; j < annotations.size(); j++) {
        annotations[j]->ExtractClassNames();
      }
    }
  }

  void Write(u1 *&p) {
    WriteProlog(p, -1);
    u1 *payload_start = p - 4;
    put_u1(p, parameter_annotations_.size());
    for (size_t ii = 0; ii < parameter_annotations_.size(); ++ii) {
      std::vector<Annotation *> &annotations = parameter_annotations_[ii];
      put_u2be(p, annotations.size());
      for (size_t jj = 0; jj < annotations.size(); ++jj) {
        annotations[jj]->Write(p);
      }
    }
    put_u4be(payload_start, p - 4 - payload_start);  // backpatch length
  }

  std::vector<std::vector<Annotation*> > parameter_annotations_;
};

// See sec.4.7.20 of Java 8 JVM spec. Includes RuntimeVisibleTypeAnnotations
// and RuntimeInvisibleTypeAnnotations.
struct TypeAnnotationsAttribute : Attribute {
  static TypeAnnotationsAttribute *Read(const u1 *&p, Constant *attribute_name,
                                        u4 /*attribute_length*/) {
    auto attr = new TypeAnnotationsAttribute;
    attr->attribute_name_ = attribute_name;
    u2 num_annotations = get_u2be(p);
    for (int ii = 0; ii < num_annotations; ++ii) {
      TypeAnnotation *annotation = TypeAnnotation::Read(p);
      attr->type_annotations_.push_back(annotation);
    }
    return attr;
  }

  virtual void ExtractClassNames() {
    for (auto *type_annotation : type_annotations_) {
      type_annotation->ExtractClassNames();
    }
  }

  void Write(u1 *&p) {
    WriteProlog(p, -1);
    u1 *payload_start = p - 4;
    put_u2be(p, type_annotations_.size());
    for (TypeAnnotation *annotation : type_annotations_) {
      annotation->Write(p);
    }
    put_u4be(payload_start, p - 4 - payload_start);  // backpatch length
  }

  std::vector<TypeAnnotation*> type_annotations_;
};

// See JVMS §4.7.24
struct MethodParametersAttribute : Attribute {
  static MethodParametersAttribute *Read(const u1 *&p, Constant *attribute_name,
                                         u4 /*attribute_length*/) {
    auto attr = new MethodParametersAttribute;
    attr->attribute_name_ = attribute_name;
    u1 parameters_count = get_u1(p);
    for (int ii = 0; ii < parameters_count; ++ii) {
      MethodParameter* parameter = new MethodParameter;
      int name_id = get_u2be(p);
      parameter->name_ = name_id == 0 ? NULL : constant(name_id);
      parameter->access_flags_ = get_u2be(p);
      attr->parameters_.push_back(parameter);
    }
    return attr;
  }

  void Write(u1 *&p) {
    WriteProlog(p, -1);
    u1 *payload_start = p - 4;
    put_u1(p, parameters_.size());
    for (MethodParameter* parameter : parameters_) {
      put_u2be(p, parameter->name_ == NULL ? 0 : parameter->name_->slot());
      put_u2be(p, parameter->access_flags_);
    }
    put_u4be(payload_start, p - 4 - payload_start);  // backpatch length
  }

  struct MethodParameter {
    Constant *name_;
    u2 access_flags_;
  };

  std::vector<MethodParameter*> parameters_;
};

// See JVMS §4.7.28
struct NestHostAttribute : Attribute {
  static NestHostAttribute *Read(const u1 *&p, Constant *attribute_name,
                                 u4 /*attribute_length*/) {
    auto attr = new NestHostAttribute;
    attr->attribute_name_ = attribute_name;
    attr->host_class_index_ = constant(get_u2be(p));
    return attr;
  }

  void Write(u1 *&p) {
    WriteProlog(p, 2);
    put_u2be(p, host_class_index_->slot());
  }

  Constant *host_class_index_;
};

// See JVMS §4.7.29
struct NestMembersAttribute : Attribute {
  static NestMembersAttribute *Read(const u1 *&p, Constant *attribute_name,
                                    u4 /*attribute_length*/) {
    auto attr = new NestMembersAttribute;
    attr->attribute_name_ = attribute_name;
    u2 number_of_classes = get_u2be(p);
    for (int ii = 0; ii < number_of_classes; ++ii) {
      attr->classes_.push_back(constant(get_u2be(p)));
    }
    return attr;
  }

  void Write(u1 *&p) {
    std::set<int> kept_entries;
    for (size_t ii = 0; ii < classes_.size(); ++ii) {
      Constant *class_ = classes_[ii];
      if (class_->Kept() || (used_class_names.find(class_->Display()) !=
                             used_class_names.end())) {
        kept_entries.insert(ii);
      }
    }
    if (kept_entries.empty()) {
      return;
    }
    WriteProlog(p, kept_entries.size() * 2 + 2);
    put_u2be(p, kept_entries.size());
    for (std::set<int>::iterator it = kept_entries.begin();
         it != kept_entries.end(); ++it) {
      put_u2be(p, classes_[*it]->slot());
    }
  }

  std::vector<Constant *> classes_;
};

// See JVMS §4.7.30
struct RecordAttribute : Attribute {
  static RecordAttribute *Read(const u1 *&p, Constant *attribute_name,
                                    u4 attribute_length) {
    auto attr = new RecordAttribute;
    attr->attribute_name_ = attribute_name;
    attr->attribute_length_ = attribute_length;
    u2 components_length = get_u2be(p);
    for (int i = 0; i < components_length; ++i) {
      attr->components_.push_back(RecordComponentInfo::Read(p));
    }
    return attr;
  }

  void Write(u1 *&p) {
    u1 *tmp = new u1[attribute_length_];
    u1 *start = tmp;
    put_u2be(tmp, components_.size());
    for (size_t i = 0; i < components_.size(); ++i) {
      components_[i]->Write(tmp);
    }
    u2 length = tmp - start;
    WriteProlog(p, length);
    memcpy(p, start, length);
    p += length;
  }

  struct RecordComponentInfo : HasAttrs {
    void Write(u1 *&p) {
      put_u2be(p, name_->slot());
      put_u2be(p, descriptor_->slot());
      WriteAttrs(p);
    }
    static RecordComponentInfo *Read(const u1 *&p) {
      RecordComponentInfo *value = new RecordComponentInfo;
      value->name_ = constant(get_u2be(p));
      value->descriptor_ = constant(get_u2be(p));
      value->ReadAttrs(p);
      return value;
    }

    Constant *name_;
    Constant *descriptor_;
  };

  u4 attribute_length_;
  std::vector<RecordComponentInfo *> components_;
};

// See JVMS §4.7.31
struct PermittedSubclassesAttribute : Attribute {
  static PermittedSubclassesAttribute *Read(const u1 *&p,
                                            Constant *attribute_name) {
    PermittedSubclassesAttribute *attr = new PermittedSubclassesAttribute;
    attr->attribute_name_ = attribute_name;
    u2 number_of_exceptions = get_u2be(p);
    for (int ii = 0; ii < number_of_exceptions; ++ii) {
      attr->permitted_subclasses_.push_back(constant(get_u2be(p)));
    }
    return attr;
  }

  void Write(u1 *&p) {
    WriteProlog(p, permitted_subclasses_.size() * 2 + 2);
    put_u2be(p, permitted_subclasses_.size());
    for (size_t ii = 0; ii < permitted_subclasses_.size(); ++ii) {
      put_u2be(p, permitted_subclasses_[ii]->slot());
    }
  }

  std::vector<Constant *> permitted_subclasses_;
};

struct GeneralAttribute : Attribute {
  static GeneralAttribute* Read(const u1 *&p, Constant *attribute_name,
                                u4 attribute_length) {
    auto attr = new GeneralAttribute;
    attr->attribute_name_ = attribute_name;
    attr->attribute_length_ = attribute_length;
    attr->attribute_content_ = p;
    p += attribute_length;
    return attr;
  }

  void Write(u1 *&p) {
    WriteProlog(p, attribute_length_);
    put_n(p, attribute_content_, attribute_length_);
  }

  u4 attribute_length_;
  const u1 *attribute_content_;
};

/**********************************************************************
 *                                                                    *
 *                             ClassFile                              *
 *                                                                    *
 **********************************************************************/

// A field or method.
// See sec.4.5 and 4.6 of JVM spec.
struct Member : HasAttrs {
  u2 access_flags;
  Constant *name;
  Constant *descriptor;

  static Member* Read(const u1 *&p) {
    Member *m = new Member;
    m->access_flags = get_u2be(p);
    m->name = constant(get_u2be(p));
    m->descriptor = constant(get_u2be(p));
    m->ReadAttrs(p);
    return m;
  }

  void Write(u1 *&p) {
    put_u2be(p, access_flags);
    put_u2be(p, name->slot());
    put_u2be(p, descriptor->slot());
    WriteAttrs(p);
  }
};

// See sec.4.1 of JVM spec.
struct ClassFile : HasAttrs {

  size_t length;

  // Header:
  u4 magic;
  u2 major;
  u2 minor;

  // Body:
  u2 access_flags;
  Constant *this_class;
  Constant *super_class;
  std::vector<Constant*> interfaces;
  std::vector<Member*> fields;
  std::vector<Member*> methods;

  virtual ~ClassFile() {
    for (size_t i = 0; i < fields.size(); i++) {
      delete fields[i];
    }

    for (size_t i = 0; i < methods.size(); i++) {
      delete methods[i];
    }

    // Constants do not need to be deleted; they are owned by the constant pool.
  }

  void WriteClass(u1 *&p);

  bool ReadConstantPool(const u1 *&p);

  bool KeepForCompile();

  bool IsLocalOrAnonymous();

  void WriteHeader(u1 *&p) {
    put_u4be(p, magic);
    put_u2be(p, major);
    put_u2be(p, minor);

    put_u2be(p, const_pool_out.size());
    for (u2 ii = 1; ii < const_pool_out.size(); ++ii) {
      if (const_pool_out[ii] != NULL) { // NB: NULLs appear after long/double.
        const_pool_out[ii]->Write(p);
      }
    }
  }

  void WriteBody(u1 *&p) {
    put_u2be(p, access_flags);
    put_u2be(p, this_class->slot());
    put_u2be(p, super_class == NULL ? 0 : super_class->slot());
    put_u2be(p, interfaces.size());
    for (size_t ii = 0; ii < interfaces.size(); ++ii) {
      put_u2be(p, interfaces[ii]->slot());
    }
    put_u2be(p, fields.size());
    for (size_t ii = 0; ii < fields.size(); ++ii) {
      fields[ii]->Write(p);
    }
    put_u2be(p, methods.size());
    for (size_t ii = 0; ii < methods.size(); ++ii) {
      methods[ii]->Write(p);
    }

    Attribute* inner_classes = NULL;

    // Make the inner classes attribute the last, so that it can know which
    // constants were needed
    for (size_t ii = 0; ii < attributes.size(); ii++) {
      if (attributes[ii]->attribute_name_->Display() == "InnerClasses") {
        inner_classes = attributes[ii];
        attributes.erase(attributes.begin() + ii);
        break;
      }
    }

    if (inner_classes != NULL) {
      attributes.push_back(inner_classes);
    }

    Attribute* nest_members = NULL;

    for (size_t ii = 0; ii < attributes.size(); ii++) {
      if (attributes[ii]->attribute_name_->Display() == "NestMembers") {
        nest_members = attributes[ii];
        attributes.erase(attributes.begin() + ii);
        break;
      }
    }

    if (nest_members != NULL) {
      attributes.push_back(nest_members);
    }

    WriteAttrs(p);
  }

};

void HasAttrs::ReadAttrs(const u1 *&p) {
  u2 attributes_count = get_u2be(p);
  for (int ii = 0; ii < attributes_count; ii++) {
    Constant *attribute_name = constant(get_u2be(p));
    u4 attribute_length = get_u4be(p);

    std::string attr_name = attribute_name->Display();
    if (attr_name == "SourceFile" ||
        attr_name == "StackMapTable" ||
        attr_name == "LineNumberTable" ||
        attr_name == "LocalVariableTable" ||
        attr_name == "LocalVariableTypeTable" ||
        attr_name == "Code" ||
        attr_name == "Synthetic" ||
        attr_name == "BootstrapMethods" ||
        attr_name == "SourceDebugExtension") {
      p += attribute_length; // drop these attributes
    } else if (attr_name == "Exceptions") {
      attributes.push_back(ExceptionsAttribute::Read(p, attribute_name));
    } else if (attr_name == "Signature") {
      attributes.push_back(SignatureAttribute::Read(p, attribute_name));
    } else if (attr_name == "Deprecated") {
      attributes.push_back(DeprecatedAttribute::Read(p, attribute_name));
    } else if (attr_name == "EnclosingMethod") {
      attributes.push_back(EnclosingMethodAttribute::Read(p, attribute_name));
    } else if (attr_name == "InnerClasses") {
      // TODO(bazel-team): omit private inner classes
      attributes.push_back(InnerClassesAttribute::Read(p, attribute_name));
    } else if (attr_name == "AnnotationDefault") {
      attributes.push_back(AnnotationDefaultAttribute::Read(p, attribute_name));
    } else if (attr_name == "ConstantValue") {
      attributes.push_back(ConstantValueAttribute::Read(p, attribute_name));
    } else if (attr_name == "RuntimeVisibleAnnotations" ||
               attr_name == "RuntimeInvisibleAnnotations") {
      attributes.push_back(AnnotationsAttribute::Read(p, attribute_name));
    } else if (attr_name == "RuntimeVisibleParameterAnnotations" ||
               attr_name == "RuntimeInvisibleParameterAnnotations") {
      attributes.push_back(
          ParameterAnnotationsAttribute::Read(p, attribute_name));
    } else if (attr_name == "Scala" ||
               attr_name == "ScalaSig" ||
               attr_name == "ScalaInlineInfo" ||
               attr_name == "TurbineTransitiveJar") {
      // These are opaque blobs, so can be handled with a general
      // attribute handler
      attributes.push_back(GeneralAttribute::Read(p, attribute_name,
                                                  attribute_length));
    } else if (attr_name == "RuntimeVisibleTypeAnnotations" ||
               attr_name == "RuntimeInvisibleTypeAnnotations") {
      attributes.push_back(TypeAnnotationsAttribute::Read(p, attribute_name,
                                                          attribute_length));
    } else if (attr_name == "MethodParameters") {
      attributes.push_back(
          MethodParametersAttribute::Read(p, attribute_name, attribute_length));
    } else if (attr_name == "NestHost") {
      attributes.push_back(
          NestHostAttribute::Read(p, attribute_name, attribute_length));
    } else if (attr_name == "NestMembers") {
      attributes.push_back(
          NestMembersAttribute::Read(p, attribute_name, attribute_length));
    } else if (attr_name == "Record") {
      attributes.push_back(
          RecordAttribute::Read(p, attribute_name, attribute_length));
    } else if (attr_name == "PermittedSubclasses") {
      attributes.push_back(
          PermittedSubclassesAttribute::Read(p, attribute_name));
    } else {
      // Skip over unknown attributes with a warning.  The JVM spec
      // says this is ok, so long as we handle the mandatory attributes.
      // Don't even warn for the D8 desugar SynthesizedClass attribute. It is
      // not relevant for ijar.
      if (attr_name != "com.android.tools.r8.SynthesizedClass" &&
          attr_name != "com.android.tools.r8.SynthesizedClassV2") {
        fprintf(stderr, "ijar: skipping unknown attribute: \"%s\".\n",
                attr_name.c_str());
      }
      p += attribute_length;
    }
  }
}

void HasAttrs::WriteAttrs(u1 *&p) {
  u1* p_size = p;

  put_u2be(p, 0);
  int n_written_attrs = 0;
  for (size_t ii = 0; ii < attributes.size(); ii++) {
    u1* before = p;
    attributes[ii]->Write(p);
    if (p != before) {
      n_written_attrs++;
    }
  }

  put_u2be(p_size, n_written_attrs);
}

// See sec.4.4 of JVM spec.
bool ClassFile::ReadConstantPool(const u1 *&p) {

  const_pool_in.clear();
  const_pool_in.push_back(NULL); // dummy first item

  u2 cp_count = get_u2be(p);
  for (int ii = 1; ii < cp_count; ++ii) {
    u1 tag = get_u1(p);

    if (devtools_ijar::verbose) {
      fprintf(stderr, "cp[%d/%d] = tag %d\n", ii, cp_count, tag);
    }

    switch(tag) {
      case CONSTANT_Class: {
        u2 name_index = get_u2be(p);
        const_pool_in.push_back(new Constant_Class(name_index));
        break;
      }
      case CONSTANT_FieldRef:
      case CONSTANT_Methodref:
      case CONSTANT_Interfacemethodref: {
        u2 class_index = get_u2be(p);
        u2 nti = get_u2be(p);
        const_pool_in.push_back(new Constant_FMIref(tag, class_index, nti));
        break;
      }
      case CONSTANT_String: {
        u2 string_index = get_u2be(p);
        const_pool_in.push_back(new Constant_String(string_index));
        break;
      }
      case CONSTANT_NameAndType: {
        u2 name_index = get_u2be(p);
        u2 descriptor_index = get_u2be(p);
        const_pool_in.push_back(
            new Constant_NameAndType(name_index, descriptor_index));
        break;
      }
      case CONSTANT_Utf8: {
        u2 length = get_u2be(p);
        if (devtools_ijar::verbose) {
          fprintf(stderr, "Utf8: \"%s\" (%d)\n",
                  std::string((const char*) p, length).c_str(), length);
        }

        const_pool_in.push_back(new Constant_Utf8(length, p));
        p += length;
        break;
      }
      case CONSTANT_Integer:
      case CONSTANT_Float: {
        u4 bytes = get_u4be(p);
        const_pool_in.push_back(new Constant_IntegerOrFloat(tag, bytes));
        break;
      }
      case CONSTANT_Long:
      case CONSTANT_Double: {
        u4 high_bytes = get_u4be(p);
        u4 low_bytes = get_u4be(p);
        const_pool_in.push_back(
            new Constant_LongOrDouble(tag, high_bytes, low_bytes));
        // Longs and doubles occupy two constant pool slots.
        // ("In retrospect, making 8-byte constants take two "constant
        // pool entries was a poor choice." --JVM Spec.)
        const_pool_in.push_back(NULL);
        ii++;
        break;
      }
      case CONSTANT_MethodHandle: {
        u1 reference_kind = get_u1(p);
        u2 reference_index = get_u2be(p);
        const_pool_in.push_back(
            new Constant_MethodHandle(reference_kind, reference_index));
        break;
      }
      case CONSTANT_MethodType: {
        u2 descriptor_index = get_u2be(p);
        const_pool_in.push_back(new Constant_MethodType(descriptor_index));
        break;
      }
      case CONSTANT_InvokeDynamic: {
        u2 bootstrap_method_attr = get_u2be(p);
        u2 name_name_type_index = get_u2be(p);
        const_pool_in.push_back(new Constant_InvokeDynamic(
            bootstrap_method_attr, name_name_type_index));
        break;
      }
      default: {
        fprintf(stderr, "Unknown constant: %02x. Passing class through.\n",
                tag);
        return false;
      }
    }
  }

  return true;
}

bool ClassFile::IsLocalOrAnonymous() {
  for (const Attribute *attribute : attributes) {
    if (attribute->attribute_name_->Display() == "EnclosingMethod") {
      // JVMS 4.7.6: a class must has EnclosingMethod attribute iff it
      // represents a local class or an anonymous class
      return true;
    }
  }
  return false;
}

static bool HasKeepForCompile(const std::vector<Attribute *> attributes) {
  for (const Attribute *attribute : attributes) {
    if (attribute->KeepForCompile()) {
      return true;
    }
  }
  return false;
}

bool ClassFile::KeepForCompile() {
  if (HasKeepForCompile(attributes)) {
    return true;
  }
  return false;
}

static ClassFile *ReadClass(const void *classdata, size_t length) {
  const u1 *p = (u1*) classdata;

  ClassFile *clazz = new ClassFile;

  clazz->length = length;

  clazz->magic = get_u4be(p);
  if (clazz->magic != 0xCAFEBABE) {
    fprintf(stderr, "Bad magic %" PRIx32 "\n", clazz->magic);
    abort();
  }
  clazz->major = get_u2be(p);
  clazz->minor = get_u2be(p);

  if (!clazz->ReadConstantPool(p)) {
    delete clazz;
    return NULL;
  }

  clazz->access_flags = get_u2be(p);
  clazz->this_class = constant(get_u2be(p));
  class_name = clazz->this_class;

  u2 super_class_id = get_u2be(p);
  clazz->super_class = super_class_id == 0 ? NULL : constant(super_class_id);

  u2 interfaces_count = get_u2be(p);
  for (int ii = 0; ii < interfaces_count; ++ii) {
    clazz->interfaces.push_back(constant(get_u2be(p)));
  }

  u2 fields_count = get_u2be(p);
  for (int ii = 0; ii < fields_count; ++ii) {
    Member *field = Member::Read(p);

    if ((field->access_flags & ACC_PRIVATE) == ACC_PRIVATE) {
      // drop private fields
      continue;
    }
    clazz->fields.push_back(field);
  }

  u2 methods_count = get_u2be(p);
  for (int ii = 0; ii < methods_count; ++ii) {
    Member *method = Member::Read(p);

    // drop class initializers
    if (method->name->Display() == "<clinit>") continue;

    if ((method->access_flags & ACC_PRIVATE) == ACC_PRIVATE) {
      // drop private methods
      continue;
    }
    if ((method->access_flags & (ACC_SYNTHETIC | ACC_BRIDGE | ACC_PUBLIC |
                                 ACC_PROTECTED)) == ACC_SYNTHETIC) {
      // drop package-private non-bridge synthetic methods, e.g. synthetic
      // constructors used to instantiate private nested classes within their
      // declaring compilation unit
      continue;
    }
    clazz->methods.push_back(method);
  }

  clazz->ReadAttrs(p);

  return clazz;
}

// In theory, '/' is also reserved, but it's okay if we just parse package
// identifiers as part of the class name. Note that signatures are UTF-8, but
// this works just as well as in plain ASCII.
static const char *SIGNATURE_NON_IDENTIFIER_CHARS = ".;[<>:";

void Expect(const std::string& desc, size_t* p, char expected) {
  if (desc[*p] != expected) {
    fprintf(stderr, "Expected '%c' in '%s' at %zd in signature\n",
            expected, desc.substr(*p).c_str(), *p);
    exit(1);
  }

  *p += 1;
}

// These functions form a crude recursive descent parser for descriptors and
// signatures in class files (see JVM spec 4.3).
//
// This parser is a bit more liberal than the spec, but this should be fine,
// because it accepts all valid class files and croaks only on invalid ones.
void ParseFromClassTypeSignature(const std::string& desc, size_t* p);
void ParseSimpleClassTypeSignature(const std::string& desc, size_t* p);
void ParseClassTypeSignatureSuffix(const std::string& desc, size_t* p);
void ParseIdentifier(const std::string& desc, size_t* p);
void ParseTypeArgumentsOpt(const std::string& desc, size_t* p);
void ParseMethodDescriptor(const std::string& desc, size_t* p);

void ParseClassTypeSignature(const std::string& desc, size_t* p) {
  Expect(desc, p, 'L');
  ParseSimpleClassTypeSignature(desc, p);
  ParseClassTypeSignatureSuffix(desc, p);
  Expect(desc, p, ';');
}

void ParseSimpleClassTypeSignature(const std::string& desc, size_t* p) {
  ParseIdentifier(desc, p);
  ParseTypeArgumentsOpt(desc, p);
}

void ParseClassTypeSignatureSuffix(const std::string& desc, size_t* p) {
  while (desc[*p] == '.') {
    *p += 1;
    ParseSimpleClassTypeSignature(desc, p);
  }
}

void ParseIdentifier(const std::string& desc, size_t* p) {
  size_t next = desc.find_first_of(SIGNATURE_NON_IDENTIFIER_CHARS, *p);
  std::string id = desc.substr(*p, next - *p);
  used_class_names.insert(id);
  *p = next;
}

void ParseTypeArgumentsOpt(const std::string& desc, size_t* p) {
  if (desc[*p] != '<') {
    return;
  }

  *p += 1;
  while (desc[*p] != '>') {
    switch (desc[*p]) {
      case '*':
        *p += 1;
        break;

      case '+':
      case '-':
        *p += 1;
        ExtractClassNames(desc, p);
        break;

      default:
        ExtractClassNames(desc, p);
        break;
    }
  }

  *p += 1;
}

void ParseMethodDescriptor(const std::string& desc, size_t* p) {
  Expect(desc, p, '(');
  while (desc[*p] != ')') {
    ExtractClassNames(desc, p);
  }

  Expect(desc, p, ')');
  ExtractClassNames(desc, p);
}

void ParseFormalTypeParameters(const std::string& desc, size_t* p) {
  Expect(desc, p, '<');
  while (desc[*p] != '>') {
    ParseIdentifier(desc, p);
    Expect(desc, p, ':');
    if (desc[*p] != ':' && desc[*p] != '>') {
      ExtractClassNames(desc, p);
    }

    while (desc[*p] == ':') {
      Expect(desc, p, ':');
      ExtractClassNames(desc, p);
    }
  }

  Expect(desc, p, '>');
}

void ExtractClassNames(const std::string& desc, size_t* p) {
  switch (desc[*p]) {
    case '<':
      ParseFormalTypeParameters(desc, p);
      ExtractClassNames(desc, p);
      break;

    case 'L':
      ParseClassTypeSignature(desc, p);
      break;

    case '[':
      *p += 1;
      ExtractClassNames(desc, p);
      break;

    case 'T':
      *p += 1;
      ParseIdentifier(desc, p);
      Expect(desc, p, ';');
      break;

    case '(':
      ParseMethodDescriptor(desc, p);
      break;

    case 'B':
    case 'C':
    case 'D':
    case 'F':
    case 'I':
    case 'J':
    case 'S':
    case 'Z':
    case 'V':
      *p += 1;
      break;

    default:
      fprintf(stderr, "Invalid signature %s\n", desc.substr(*p).c_str());
  }
}

void ClassFile::WriteClass(u1 *&p) {
  used_class_names.clear();
  std::vector<Member *> members;
  members.insert(members.end(), fields.begin(), fields.end());
  members.insert(members.end(), methods.begin(), methods.end());
  ExtractClassNames();
  for (auto *member : members) {
    size_t idx = 0;
    devtools_ijar::ExtractClassNames(member->descriptor->Display(), &idx);
    member->ExtractClassNames();
  }

  // We have to write the body out before the header in order to reference
  // the essential constants and populate the output constant pool:
  u1 *body = new u1[length];
  u1 *q = body;
  WriteBody(q); // advances q
  u4 body_length = q - body;

  WriteHeader(p); // advances p
  put_n(p, body, body_length);
  delete[] body;
}

bool StripClass(u1 *&classdata_out, const u1 *classdata_in, size_t in_length) {
  ClassFile *clazz = ReadClass(classdata_in, in_length);
  bool keep = true;
  if (clazz == NULL || clazz->KeepForCompile()) {
    // Class is invalid or kept. Simply copy it to the output and call it a day.
    put_n(classdata_out, classdata_in, in_length);
  } else if (clazz->IsLocalOrAnonymous()) {
    keep = false;
  } else {
    // Constant pool item zero is a dummy entry.  Setting it marks the
    // beginning of the output phase; calls to Constant::slot() will
    // fail if called prior to this.
    const_pool_out.push_back(NULL);
    clazz->WriteClass(classdata_out);

    delete clazz;
  }

  // Now clean up all the mess we left behind.

  for (size_t i = 0; i < const_pool_in.size(); i++) {
    delete const_pool_in[i];
  }

  const_pool_in.clear();
  const_pool_out.clear();
  return keep;
}

}  // namespace devtools_ijar
