public static @NotNull TypeInfo readTYPE(@NotNull StubInputStream record) throws IOException {
    int flags = record.readByte() & 0xFF;
    boolean hasTypeAnnotations = isSet(flags, HAS_TYPE_ANNOTATIONS);
    int kindOrdinal = clear(flags, HAS_TYPE_ANNOTATIONS);
    if (kindOrdinal >= ALL_KINDS.length) {
      throw new IOException("Unexpected TypeKind: " + flags);
    }
    TypeKind kind = ALL_KINDS[kindOrdinal];
    TypeInfo info;
    RefTypeInfo outer = null;
    switch (kind) {
      case REF:
        info = new RefTypeInfo(Objects.requireNonNull(record.readNameString()));
        break;
      case INNER_SIMPLE:
        outer = new RefTypeInfo(Objects.requireNonNull(record.readNameString()));
        info = new RefTypeInfo(Objects.requireNonNull(record.readNameString()), outer);
        break;
      case INNER:
        outer = (RefTypeInfo)readTYPE(record);
        info = new RefTypeInfo(Objects.requireNonNull(record.readNameString()), outer);
        break;
      case INNER_GENERIC:
        outer = (RefTypeInfo)readTYPE(record);
      case GENERIC:
        String name = Objects.requireNonNull(record.readNameString());
        byte count = record.readByte();
        TypeInfo[] components = new TypeInfo[count];
        for (int i = 0; i < count; i++) {
          components[i] = readTYPE(record);
        }
        info = new RefTypeInfo(name, outer, components);
        break;
      case EXTENDS:
      case SUPER:
      case ARRAY:
      case ELLIPSIS:
        info = new DerivedTypeInfo(kind, readTYPE(record));
        break;
      default:
        info = kind.isReference() ? new RefTypeInfo(Objects.requireNonNull(kind.text)) : new SimpleTypeInfo(kind);
    }
    info.setTypeAnnotations(hasTypeAnnotations ? TypeAnnotationContainer.readTypeAnnotations(record) : TypeAnnotationContainer.EMPTY);
    return info;
  }
public static @NotNull TypeInfo readTYPE(@NotNull StubInputStream record)