private Constant parseValue() throws IOException {
    int tag = input.readUnsignedByte();

    if (observer != null) {
      CstString humanTag = new CstString(Character.toString((char) tag));
      parsed(1, "tag: " + humanTag.toQuoted());
    }

    switch (tag) {
      case 'B':
        {
          CstInteger value = (CstInteger) parseConstant();
          return CstByte.make(value.getValue());
        }
      case 'C':
        {
          CstInteger value = (CstInteger) parseConstant();
          int intValue = value.getValue();
          return CstChar.make(value.getValue());
        }
      case 'D':
        {
          CstDouble value = (CstDouble) parseConstant();
          return value;
        }
      case 'F':
        {
          CstFloat value = (CstFloat) parseConstant();
          return value;
        }
      case 'I':
        {
          CstInteger value = (CstInteger) parseConstant();
          return value;
        }
      case 'J':
        {
          CstLong value = (CstLong) parseConstant();
          return value;
        }
      case 'S':
        {
          CstInteger value = (CstInteger) parseConstant();
          return CstShort.make(value.getValue());
        }
      case 'Z':
        {
          CstInteger value = (CstInteger) parseConstant();
          return CstBoolean.make(value.getValue());
        }
      case 'c':
        {
          int classInfoIndex = input.readUnsignedShort();
          CstString value = (CstString) pool.get(classInfoIndex);
          Type type = Type.internReturnType(value.getString());

          if (observer != null) {
            parsed(2, "class_info: " + type.toHuman());
          }

          return new CstType(type);
        }
      case 's':
        {
          return parseConstant();
        }
      case 'e':
        {
          requireLength(4);

          int typeNameIndex = input.readUnsignedShort();
          int constNameIndex = input.readUnsignedShort();
          CstString typeName = (CstString) pool.get(typeNameIndex);
          CstString constName = (CstString) pool.get(constNameIndex);

          if (observer != null) {
            parsed(2, "type_name: " + typeName.toHuman());
            parsed(2, "const_name: " + constName.toHuman());
          }

          return new CstEnumRef(new CstNat(constName, typeName));
        }
      case '@':
        {
          Annotation annotation = parseAnnotation(AnnotationVisibility.EMBEDDED);
          return new CstAnnotation(annotation);
        }
      case '[':
        {
          requireLength(2);

          int numValues = input.readUnsignedShort();
          CstArray.List list = new CstArray.List(numValues);

          if (observer != null) {
            parsed(2, "num_values: " + numValues);
            changeIndent(1);
          }

          for (int i = 0; i < numValues; i++) {
            if (observer != null) {
              changeIndent(-1);
              parsed(0, "element_value[" + i + "]:");
              changeIndent(1);
            }
            list.set(i, parseValue());
          }

          if (observer != null) {
            changeIndent(-1);
          }

          list.setImmutable();
          return new CstArray(list);
        }
      default:
        {
          throw new ParseException("unknown annotation tag: " + Hex.u1(tag));
        }
    }
  }
Parses an annotation value.

@return {@code non-null;} the parsed value
android/android_framework/dex-maker/src/main/java/com/android/dx/cf/direct/AnnotationParser.java