/**
   * Prints out the contents of this instance, in a debugging-friendly way. This is meant to be
   * called from {@link ClassDefItem#debugPrint}.
   *
   * @param out {@code non-null;} where to output to
   */
  /* package */ void debugPrint(PrintWriter out) {
    if (classAnnotations != null) {
      out.println("  class annotations: " + classAnnotations);
    }

    if (fieldAnnotations != null) {
      out.println("  field annotations:");
      for (FieldAnnotationStruct item : fieldAnnotations) {
        out.println("    " + item.toHuman());
      }
    }

    if (methodAnnotations != null) {
      out.println("  method annotations:");
      for (MethodAnnotationStruct item : methodAnnotations) {
        out.println("    " + item.toHuman());
      }
    }

    if (parameterAnnotations != null) {
      out.println("  parameter annotations:");
      for (ParameterAnnotationStruct item : parameterAnnotations) {
        out.println("    " + item.toHuman());
      }
    }
  }
  /** {@inheritDoc} */
  public void addContents(DexFile file) {
    MixedItemSection wordData = file.getWordData();

    if (classAnnotations != null) {
      classAnnotations = wordData.intern(classAnnotations);
    }

    if (fieldAnnotations != null) {
      for (FieldAnnotationStruct item : fieldAnnotations) {
        item.addContents(file);
      }
    }

    if (methodAnnotations != null) {
      for (MethodAnnotationStruct item : methodAnnotations) {
        item.addContents(file);
      }
    }

    if (parameterAnnotations != null) {
      for (ParameterAnnotationStruct item : parameterAnnotations) {
        item.addContents(file);
      }
    }
  }
  /**
   * Gets the method annotations for a given method, if any. This is meant for use by debugging /
   * dumping code.
   *
   * @param method {@code non-null;} the method
   * @return {@code null-ok;} the method annotations, if any
   */
  public Annotations getMethodAnnotations(CstMethodRef method) {
    if (methodAnnotations == null) {
      return null;
    }

    for (MethodAnnotationStruct item : methodAnnotations) {
      if (item.getMethod().equals(method)) {
        return item.getAnnotations();
      }
    }

    return null;
  }
  /** {@inheritDoc} */
  @Override
  protected void writeTo0(DexFile file, AnnotatedOutput out) {
    boolean annotates = out.annotates();
    int classOff = OffsettedItem.getAbsoluteOffsetOr0(classAnnotations);
    int fieldsSize = listSize(fieldAnnotations);
    int methodsSize = listSize(methodAnnotations);
    int parametersSize = listSize(parameterAnnotations);

    if (annotates) {
      out.annotate(0, offsetString() + " annotations directory");
      out.annotate(4, "  class_annotations_off: " + Hex.u4(classOff));
      out.annotate(4, "  fields_size:           " + Hex.u4(fieldsSize));
      out.annotate(4, "  methods_size:          " + Hex.u4(methodsSize));
      out.annotate(4, "  parameters_size:       " + Hex.u4(parametersSize));
    }

    out.writeInt(classOff);
    out.writeInt(fieldsSize);
    out.writeInt(methodsSize);
    out.writeInt(parametersSize);

    if (fieldsSize != 0) {
      Collections.sort(fieldAnnotations);
      if (annotates) {
        out.annotate(0, "  fields:");
      }
      for (FieldAnnotationStruct item : fieldAnnotations) {
        item.writeTo(file, out);
      }
    }

    if (methodsSize != 0) {
      Collections.sort(methodAnnotations);
      if (annotates) {
        out.annotate(0, "  methods:");
      }
      for (MethodAnnotationStruct item : methodAnnotations) {
        item.writeTo(file, out);
      }
    }

    if (parametersSize != 0) {
      Collections.sort(parameterAnnotations);
      if (annotates) {
        out.annotate(0, "  parameters:");
      }
      for (ParameterAnnotationStruct item : parameterAnnotations) {
        item.writeTo(file, out);
      }
    }
  }