public static Prototype fromDescriptor(String descriptor) {
    Prototype result = internTable.get(descriptor);
    if (result != null) {
      return result;
    }

    Type[] params = makeParameterArray(descriptor);
    int paramCount = 0;
    int at = 1;

    for (; ; ) {
      int startAt = at;
      char c = descriptor.charAt(at);
      if (c == ')') {
        at++;
        break;
      }

      // Skip array markers.
      while (c == '[') {
        at++;
        c = descriptor.charAt(at);
      }

      if (c == 'L') {
        // It looks like the start of a class name; find the end.
        int endAt = descriptor.indexOf(';', at);
        if (endAt == -1) {
          throw new IllegalArgumentException("bad descriptor");
        }
        at = endAt + 1;
      } else {
        at++;
      }

      params[paramCount] = Type.intern(descriptor.substring(startAt, at));
      paramCount++;
    }

    Type returnType = Type.internReturnType(descriptor.substring(at));
    StdTypeList parameterTypes = new StdTypeList(paramCount);

    for (int i = 0; i < paramCount; i++) {
      parameterTypes.set(i, params[i]);
    }

    return new Prototype(descriptor, returnType, parameterTypes);
  }
Returns a prototype for a method descriptor.

<p>The {@code Prototype} returned will be the interned value if present, or a new instance
otherwise. If a new instance is created, it is not placed in the intern table.

@param descriptor {@code non-null;} the descriptor
@return {@code non-null;} the corresponding instance
@throws IllegalArgumentException thrown if the descriptor has invalid syntax
android/android_framework/dex-maker/src/main/java/com/android/dx/rop/type/Prototype.java