public void writeAnnotation(Annotation annotation, boolean topLevel) {
    boolean annotates = topLevel && out.annotates();
    StringIdsSection stringIds = file.getStringIds();
    TypeIdsSection typeIds = file.getTypeIds();

    CstType type = annotation.getType();
    int typeIdx = typeIds.indexOf(type);

    if (annotates) {
      out.annotate("  type_idx: " + Hex.u4(typeIdx) + " // " + type.toHuman());
    }

    out.writeUleb128(typeIds.indexOf(annotation.getType()));

    Collection<NameValuePair> pairs = annotation.getNameValuePairs();
    int size = pairs.size();

    if (annotates) {
      out.annotate("  size: " + Hex.u4(size));
    }

    out.writeUleb128(size);

    int at = 0;
    for (NameValuePair pair : pairs) {
      CstString name = pair.getName();
      int nameIdx = stringIds.indexOf(name);
      Constant value = pair.getValue();

      if (annotates) {
        out.annotate(0, "  elements[" + at + "]:");
        at++;
        out.annotate("    name_idx: " + Hex.u4(nameIdx) + " // " + name.toHuman());
      }

      out.writeUleb128(nameIdx);

      if (annotates) {
        out.annotate("    value: " + constantToHuman(value));
      }

      writeConstant(value);
    }

    if (annotates) {
      out.endAnnotation();
    }
  }
Writes out the encoded form of the given annotation, that is, as an {@code encoded_annotation}
and not including a {@code value_type} prefix. If the output stream keeps (debugging)
annotations and {@code topLevel} is {@code true}, then this method will write (debugging)
annotations.

@param annotation {@code non-null;} annotation instance to write
@param topLevel {@code true} iff the given annotation is the top-level annotation or {@code
    false} if it is a sub-annotation of some other annotation
android/android_framework/dex-maker/src/main/java/com/android/dx/dex/file/ValueEncoder.java