code: @VisibleForTesting
    static <T> TypeToken<? extends T> toGenericType(Class<T> cls) {
      if (cls.isArray()) {
        Type arrayOfGenericType =
            Types.newArrayType(
                // If we are passed with int[].class, don't turn it to GenericArrayType
                toGenericType(cls.getComponentType()).runtimeType);
        @SuppressWarnings("unchecked") // array is covariant
        TypeToken<? extends T> result = (TypeToken<? extends T>) of(arrayOfGenericType);
        return result;
      }
      TypeVariable<Class<T>>[] typeParams = cls.getTypeParameters();
      Type ownerType =
          cls.isMemberClass() && !Modifier.isStatic(cls.getModifiers())
              ? toGenericType(cls.getEnclosingClass()).runtimeType
              : null;
  
      if ((typeParams.length > 0) || ((ownerType != null) && ownerType != cls.getEnclosingClass())) {
        @SuppressWarnings("unchecked") // Like, it's Iterable<T> for Iterable.class
        TypeToken<? extends T> type =
            (TypeToken<? extends T>)
                of(Types.newParameterizedTypeWithOwner(ownerType, cls, typeParams));
        return type;
      } else {
        return of(cls);
      }
    }
docs: Returns the type token representing the generic type declaration of {@code cls}. For example:
  {@code TypeToken.getGenericType(Iterable.class)} returns {@code Iterable<T>}.
  
  <p>If {@code cls} isn't parameterized and isn't a generic array, the type token of the class is
  returned.