001/*
002 * Copyright (C) 2006 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 */
014
015package com.google.common.reflect;
016
017import static com.google.common.base.Preconditions.checkArgument;
018import static com.google.common.base.Preconditions.checkNotNull;
019import static com.google.common.base.Preconditions.checkState;
020
021import com.google.common.annotations.Beta;
022import com.google.common.annotations.VisibleForTesting;
023import com.google.common.base.Joiner;
024import com.google.common.base.Predicate;
025import com.google.common.collect.FluentIterable;
026import com.google.common.collect.ForwardingSet;
027import com.google.common.collect.ImmutableList;
028import com.google.common.collect.ImmutableMap;
029import com.google.common.collect.ImmutableSet;
030import com.google.common.collect.Maps;
031import com.google.common.collect.Ordering;
032import com.google.common.primitives.Primitives;
033import com.google.errorprone.annotations.CanIgnoreReturnValue;
034import java.io.Serializable;
035import java.lang.reflect.Constructor;
036import java.lang.reflect.GenericArrayType;
037import java.lang.reflect.Method;
038import java.lang.reflect.Modifier;
039import java.lang.reflect.ParameterizedType;
040import java.lang.reflect.Type;
041import java.lang.reflect.TypeVariable;
042import java.lang.reflect.WildcardType;
043import java.util.Arrays;
044import java.util.Comparator;
045import java.util.Map;
046import java.util.Set;
047import org.checkerframework.checker.nullness.compatqual.MonotonicNonNullDecl;
048import org.checkerframework.checker.nullness.compatqual.NullableDecl;
049
050/**
051 * A {@link Type} with generics.
052 *
053 * <p>Operations that are otherwise only available in {@link Class} are implemented to support
054 * {@code Type}, for example {@link #isSubtypeOf}, {@link #isArray} and {@link #getComponentType}.
055 * It also provides additional utilities such as {@link #getTypes}, {@link #resolveType}, etc.
056 *
057 * <p>There are three ways to get a {@code TypeToken} instance:
058 *
059 * <ul>
060 *   <li>Wrap a {@code Type} obtained via reflection. For example: {@code
061 *       TypeToken.of(method.getGenericReturnType())}.
062 *   <li>Capture a generic type with a (usually anonymous) subclass. For example:
063 *       <pre>{@code
064 * new TypeToken<List<String>>() {}
065 * }</pre>
066 *       <p>Note that it's critical that the actual type argument is carried by a subclass. The
067 *       following code is wrong because it only captures the {@code <T>} type variable of the
068 *       {@code listType()} method signature; while {@code <String>} is lost in erasure:
069 *       <pre>{@code
070 * class Util {
071 *   static <T> TypeToken<List<T>> listType() {
072 *     return new TypeToken<List<T>>() {};
073 *   }
074 * }
075 *
076 * TypeToken<List<String>> stringListType = Util.<String>listType();
077 * }</pre>
078 *   <li>Capture a generic type with a (usually anonymous) subclass and resolve it against a context
079 *       class that knows what the type parameters are. For example:
080 *       <pre>{@code
081 * abstract class IKnowMyType<T> {
082 *   TypeToken<T> type = new TypeToken<T>(getClass()) {};
083 * }
084 * new IKnowMyType<String>() {}.type => String
085 * }</pre>
086 * </ul>
087 *
088 * <p>{@code TypeToken} is serializable when no type variable is contained in the type.
089 *
090 * <p>Note to Guice users: {@code} TypeToken is similar to Guice's {@code TypeLiteral} class except
091 * that it is serializable and offers numerous additional utility methods.
092 *
093 * @author Bob Lee
094 * @author Sven Mawson
095 * @author Ben Yu
096 * @since 12.0
097 */
098@Beta
099@SuppressWarnings("serial") // SimpleTypeToken is the serialized form.
100public abstract class TypeToken<T> extends TypeCapture<T> implements Serializable {
101
102  private final Type runtimeType;
103
104  /** Resolver for resolving types with {@link #runtimeType} as context. */
105  @MonotonicNonNullDecl private transient TypeResolver typeResolver;
106
107  /**
108   * Constructs a new type token of {@code T}.
109   *
110   * <p>Clients create an empty anonymous subclass. Doing so embeds the type parameter in the
111   * anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.
112   *
113   * <p>For example:
114   *
115   * <pre>{@code
116   * TypeToken<List<String>> t = new TypeToken<List<String>>() {};
117   * }</pre>
118   */
119  protected TypeToken() {
120    this.runtimeType = capture();
121    checkState(
122        !(runtimeType instanceof TypeVariable),
123        "Cannot construct a TypeToken for a type variable.\n"
124            + "You probably meant to call new TypeToken<%s>(getClass()) "
125            + "that can resolve the type variable for you.\n"
126            + "If you do need to create a TypeToken of a type variable, "
127            + "please use TypeToken.of() instead.",
128        runtimeType);
129  }
130
131  /**
132   * Constructs a new type token of {@code T} while resolving free type variables in the context of
133   * {@code declaringClass}.
134   *
135   * <p>Clients create an empty anonymous subclass. Doing so embeds the type parameter in the
136   * anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.
137   *
138   * <p>For example:
139   *
140   * <pre>{@code
141   * abstract class IKnowMyType<T> {
142   *   TypeToken<T> getMyType() {
143   *     return new TypeToken<T>(getClass()) {};
144   *   }
145   * }
146   *
147   * new IKnowMyType<String>() {}.getMyType() => String
148   * }</pre>
149   */
150  protected TypeToken(Class<?> declaringClass) {
151    Type captured = super.capture();
152    if (captured instanceof Class) {
153      this.runtimeType = captured;
154    } else {
155      this.runtimeType = of(declaringClass).resolveType(captured).runtimeType;
156    }
157  }
158
159  private TypeToken(Type type) {
160    this.runtimeType = checkNotNull(type);
161  }
162
163  /** Returns an instance of type token that wraps {@code type}. */
164  public static <T> TypeToken<T> of(Class<T> type) {
165    return new SimpleTypeToken<T>(type);
166  }
167
168  /** Returns an instance of type token that wraps {@code type}. */
169  public static TypeToken<?> of(Type type) {
170    return new SimpleTypeToken<>(type);
171  }
172
173  /**
174   * Returns the raw type of {@code T}. Formally speaking, if {@code T} is returned by {@link
175   * java.lang.reflect.Method#getGenericReturnType}, the raw type is what's returned by {@link
176   * java.lang.reflect.Method#getReturnType} of the same method object. Specifically:
177   *
178   * <ul>
179   *   <li>If {@code T} is a {@code Class} itself, {@code T} itself is returned.
180   *   <li>If {@code T} is a {@link ParameterizedType}, the raw type of the parameterized type is
181   *       returned.
182   *   <li>If {@code T} is a {@link GenericArrayType}, the returned type is the corresponding array
183   *       class. For example: {@code List<Integer>[] => List[]}.
184   *   <li>If {@code T} is a type variable or a wildcard type, the raw type of the first upper bound
185   *       is returned. For example: {@code <X extends Foo> => Foo}.
186   * </ul>
187   */
188  public final Class<? super T> getRawType() {
189    // For wildcard or type variable, the first bound determines the runtime type.
190    Class<?> rawType = getRawTypes().iterator().next();
191    @SuppressWarnings("unchecked") // raw type is |T|
192    Class<? super T> result = (Class<? super T>) rawType;
193    return result;
194  }
195
196  /** Returns the represented type. */
197  public final Type getType() {
198    return runtimeType;
199  }
200
201  /**
202   * Returns a new {@code TypeToken} where type variables represented by {@code typeParam} are
203   * substituted by {@code typeArg}. For example, it can be used to construct {@code Map<K, V>} for
204   * any {@code K} and {@code V} type:
205   *
206   * <pre>{@code
207   * static <K, V> TypeToken<Map<K, V>> mapOf(
208   *     TypeToken<K> keyType, TypeToken<V> valueType) {
209   *   return new TypeToken<Map<K, V>>() {}
210   *       .where(new TypeParameter<K>() {}, keyType)
211   *       .where(new TypeParameter<V>() {}, valueType);
212   * }
213   * }</pre>
214   *
215   * @param <X> The parameter type
216   * @param typeParam the parameter type variable
217   * @param typeArg the actual type to substitute
218   */
219  public final <X> TypeToken<T> where(TypeParameter<X> typeParam, TypeToken<X> typeArg) {
220    TypeResolver resolver =
221        new TypeResolver()
222            .where(
223                ImmutableMap.of(
224                    new TypeResolver.TypeVariableKey(typeParam.typeVariable), typeArg.runtimeType));
225    // If there's any type error, we'd report now rather than later.
226    return new SimpleTypeToken<T>(resolver.resolveType(runtimeType));
227  }
228
229  /**
230   * Returns a new {@code TypeToken} where type variables represented by {@code typeParam} are
231   * substituted by {@code typeArg}. For example, it can be used to construct {@code Map<K, V>} for
232   * any {@code K} and {@code V} type:
233   *
234   * <pre>{@code
235   * static <K, V> TypeToken<Map<K, V>> mapOf(
236   *     Class<K> keyType, Class<V> valueType) {
237   *   return new TypeToken<Map<K, V>>() {}
238   *       .where(new TypeParameter<K>() {}, keyType)
239   *       .where(new TypeParameter<V>() {}, valueType);
240   * }
241   * }</pre>
242   *
243   * @param <X> The parameter type
244   * @param typeParam the parameter type variable
245   * @param typeArg the actual type to substitute
246   */
247  public final <X> TypeToken<T> where(TypeParameter<X> typeParam, Class<X> typeArg) {
248    return where(typeParam, of(typeArg));
249  }
250
251  /**
252   * Resolves the given {@code type} against the type context represented by this type. For example:
253   *
254   * <pre>{@code
255   * new TypeToken<List<String>>() {}.resolveType(
256   *     List.class.getMethod("get", int.class).getGenericReturnType())
257   * => String.class
258   * }</pre>
259   */
260  public final TypeToken<?> resolveType(Type type) {
261    checkNotNull(type);
262    TypeResolver resolver = typeResolver;
263    if (resolver == null) {
264      resolver = (typeResolver = TypeResolver.accordingTo(runtimeType));
265    }
266    return of(resolver.resolveType(type));
267  }
268
269  private Type[] resolveInPlace(Type[] types) {
270    for (int i = 0; i < types.length; i++) {
271      types[i] = resolveType(types[i]).getType();
272    }
273    return types;
274  }
275
276  private TypeToken<?> resolveSupertype(Type type) {
277    TypeToken<?> supertype = resolveType(type);
278    // super types' type mapping is a subset of type mapping of this type.
279    supertype.typeResolver = typeResolver;
280    return supertype;
281  }
282
283  /**
284   * Returns the generic superclass of this type or {@code null} if the type represents {@link
285   * Object} or an interface. This method is similar but different from {@link
286   * Class#getGenericSuperclass}. For example, {@code new TypeToken<StringArrayList>()
287   * {}.getGenericSuperclass()} will return {@code new TypeToken<ArrayList<String>>() {}}; while
288   * {@code StringArrayList.class.getGenericSuperclass()} will return {@code ArrayList<E>}, where
289   * {@code E} is the type variable declared by class {@code ArrayList}.
290   *
291   * <p>If this type is a type variable or wildcard, its first upper bound is examined and returned
292   * if the bound is a class or extends from a class. This means that the returned type could be a
293   * type variable too.
294   */
295  @NullableDecl
296  final TypeToken<? super T> getGenericSuperclass() {
297    if (runtimeType instanceof TypeVariable) {
298      // First bound is always the super class, if one exists.
299      return boundAsSuperclass(((TypeVariable<?>) runtimeType).getBounds()[0]);
300    }
301    if (runtimeType instanceof WildcardType) {
302      // wildcard has one and only one upper bound.
303      return boundAsSuperclass(((WildcardType) runtimeType).getUpperBounds()[0]);
304    }
305    Type superclass = getRawType().getGenericSuperclass();
306    if (superclass == null) {
307      return null;
308    }
309    @SuppressWarnings("unchecked") // super class of T
310    TypeToken<? super T> superToken = (TypeToken<? super T>) resolveSupertype(superclass);
311    return superToken;
312  }
313
314  @NullableDecl
315  private TypeToken<? super T> boundAsSuperclass(Type bound) {
316    TypeToken<?> token = of(bound);
317    if (token.getRawType().isInterface()) {
318      return null;
319    }
320    @SuppressWarnings("unchecked") // only upper bound of T is passed in.
321    TypeToken<? super T> superclass = (TypeToken<? super T>) token;
322    return superclass;
323  }
324
325  /**
326   * Returns the generic interfaces that this type directly {@code implements}. This method is
327   * similar but different from {@link Class#getGenericInterfaces()}. For example, {@code new
328   * TypeToken<List<String>>() {}.getGenericInterfaces()} will return a list that contains {@code
329   * new TypeToken<Iterable<String>>() {}}; while {@code List.class.getGenericInterfaces()} will
330   * return an array that contains {@code Iterable<T>}, where the {@code T} is the type variable
331   * declared by interface {@code Iterable}.
332   *
333   * <p>If this type is a type variable or wildcard, its upper bounds are examined and those that
334   * are either an interface or upper-bounded only by interfaces are returned. This means that the
335   * returned types could include type variables too.
336   */
337  final ImmutableList<TypeToken<? super T>> getGenericInterfaces() {
338    if (runtimeType instanceof TypeVariable) {
339      return boundsAsInterfaces(((TypeVariable<?>) runtimeType).getBounds());
340    }
341    if (runtimeType instanceof WildcardType) {
342      return boundsAsInterfaces(((WildcardType) runtimeType).getUpperBounds());
343    }
344    ImmutableList.Builder<TypeToken<? super T>> builder = ImmutableList.builder();
345    for (Type interfaceType : getRawType().getGenericInterfaces()) {
346      @SuppressWarnings("unchecked") // interface of T
347      TypeToken<? super T> resolvedInterface =
348          (TypeToken<? super T>) resolveSupertype(interfaceType);
349      builder.add(resolvedInterface);
350    }
351    return builder.build();
352  }
353
354  private ImmutableList<TypeToken<? super T>> boundsAsInterfaces(Type[] bounds) {
355    ImmutableList.Builder<TypeToken<? super T>> builder = ImmutableList.builder();
356    for (Type bound : bounds) {
357      @SuppressWarnings("unchecked") // upper bound of T
358      TypeToken<? super T> boundType = (TypeToken<? super T>) of(bound);
359      if (boundType.getRawType().isInterface()) {
360        builder.add(boundType);
361      }
362    }
363    return builder.build();
364  }
365
366  /**
367   * Returns the set of interfaces and classes that this type is or is a subtype of. The returned
368   * types are parameterized with proper type arguments.
369   *
370   * <p>Subtypes are always listed before supertypes. But the reverse is not true. A type isn't
371   * necessarily a subtype of all the types following. Order between types without subtype
372   * relationship is arbitrary and not guaranteed.
373   *
374   * <p>If this type is a type variable or wildcard, upper bounds that are themselves type variables
375   * aren't included (their super interfaces and superclasses are).
376   */
377  public final TypeSet getTypes() {
378    return new TypeSet();
379  }
380
381  /**
382   * Returns the generic form of {@code superclass}. For example, if this is {@code
383   * ArrayList<String>}, {@code Iterable<String>} is returned given the input {@code
384   * Iterable.class}.
385   */
386  public final TypeToken<? super T> getSupertype(Class<? super T> superclass) {
387    checkArgument(
388        this.someRawTypeIsSubclassOf(superclass),
389        "%s is not a super class of %s",
390        superclass,
391        this);
392    if (runtimeType instanceof TypeVariable) {
393      return getSupertypeFromUpperBounds(superclass, ((TypeVariable<?>) runtimeType).getBounds());
394    }
395    if (runtimeType instanceof WildcardType) {
396      return getSupertypeFromUpperBounds(superclass, ((WildcardType) runtimeType).getUpperBounds());
397    }
398    if (superclass.isArray()) {
399      return getArraySupertype(superclass);
400    }
401    @SuppressWarnings("unchecked") // resolved supertype
402    TypeToken<? super T> supertype =
403        (TypeToken<? super T>) resolveSupertype(toGenericType(superclass).runtimeType);
404    return supertype;
405  }
406
407  /**
408   * Returns subtype of {@code this} with {@code subclass} as the raw class. For example, if this is
409   * {@code Iterable<String>} and {@code subclass} is {@code List}, {@code List<String>} is
410   * returned.
411   */
412  public final TypeToken<? extends T> getSubtype(Class<?> subclass) {
413    checkArgument(
414        !(runtimeType instanceof TypeVariable), "Cannot get subtype of type variable <%s>", this);
415    if (runtimeType instanceof WildcardType) {
416      return getSubtypeFromLowerBounds(subclass, ((WildcardType) runtimeType).getLowerBounds());
417    }
418    // unwrap array type if necessary
419    if (isArray()) {
420      return getArraySubtype(subclass);
421    }
422    // At this point, it's either a raw class or parameterized type.
423    checkArgument(
424        getRawType().isAssignableFrom(subclass), "%s isn't a subclass of %s", subclass, this);
425    Type resolvedTypeArgs = resolveTypeArgsForSubclass(subclass);
426    @SuppressWarnings("unchecked") // guarded by the isAssignableFrom() statement above
427    TypeToken<? extends T> subtype = (TypeToken<? extends T>) of(resolvedTypeArgs);
428    return subtype;
429  }
430
431  /**
432   * Returns true if this type is a supertype of the given {@code type}. "Supertype" is defined
433   * according to <a
434   * href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.5.1">the rules for type
435   * arguments</a> introduced with Java generics.
436   *
437   * @since 19.0
438   */
439  public final boolean isSupertypeOf(TypeToken<?> type) {
440    return type.isSubtypeOf(getType());
441  }
442
443  /**
444   * Returns true if this type is a supertype of the given {@code type}. "Supertype" is defined
445   * according to <a
446   * href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.5.1">the rules for type
447   * arguments</a> introduced with Java generics.
448   *
449   * @since 19.0
450   */
451  public final boolean isSupertypeOf(Type type) {
452    return of(type).isSubtypeOf(getType());
453  }
454
455  /**
456   * Returns true if this type is a subtype of the given {@code type}. "Subtype" is defined
457   * according to <a
458   * href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.5.1">the rules for type
459   * arguments</a> introduced with Java generics.
460   *
461   * @since 19.0
462   */
463  public final boolean isSubtypeOf(TypeToken<?> type) {
464    return isSubtypeOf(type.getType());
465  }
466
467  /**
468   * Returns true if this type is a subtype of the given {@code type}. "Subtype" is defined
469   * according to <a
470   * href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.5.1">the rules for type
471   * arguments</a> introduced with Java generics.
472   *
473   * @since 19.0
474   */
475  public final boolean isSubtypeOf(Type supertype) {
476    checkNotNull(supertype);
477    if (supertype instanceof WildcardType) {
478      // if 'supertype' is <? super Foo>, 'this' can be:
479      // Foo, SubFoo, <? extends Foo>.
480      // if 'supertype' is <? extends Foo>, nothing is a subtype.
481      return any(((WildcardType) supertype).getLowerBounds()).isSupertypeOf(runtimeType);
482    }
483    // if 'this' is wildcard, it's a suptype of to 'supertype' if any of its "extends"
484    // bounds is a subtype of 'supertype'.
485    if (runtimeType instanceof WildcardType) {
486      // <? super Base> is of no use in checking 'from' being a subtype of 'to'.
487      return any(((WildcardType) runtimeType).getUpperBounds()).isSubtypeOf(supertype);
488    }
489    // if 'this' is type variable, it's a subtype if any of its "extends"
490    // bounds is a subtype of 'supertype'.
491    if (runtimeType instanceof TypeVariable) {
492      return runtimeType.equals(supertype)
493          || any(((TypeVariable<?>) runtimeType).getBounds()).isSubtypeOf(supertype);
494    }
495    if (runtimeType instanceof GenericArrayType) {
496      return of(supertype).isSupertypeOfArray((GenericArrayType) runtimeType);
497    }
498    // Proceed to regular Type subtype check
499    if (supertype instanceof Class) {
500      return this.someRawTypeIsSubclassOf((Class<?>) supertype);
501    } else if (supertype instanceof ParameterizedType) {
502      return this.isSubtypeOfParameterizedType((ParameterizedType) supertype);
503    } else if (supertype instanceof GenericArrayType) {
504      return this.isSubtypeOfArrayType((GenericArrayType) supertype);
505    } else { // to instanceof TypeVariable
506      return false;
507    }
508  }
509
510  /**
511   * Returns true if this type is known to be an array type, such as {@code int[]}, {@code T[]},
512   * {@code <? extends Map<String, Integer>[]>} etc.
513   */
514  public final boolean isArray() {
515    return getComponentType() != null;
516  }
517
518  /**
519   * Returns true if this type is one of the nine primitive types (including {@code void}).
520   *
521   * @since 15.0
522   */
523  public final boolean isPrimitive() {
524    return (runtimeType instanceof Class) && ((Class<?>) runtimeType).isPrimitive();
525  }
526
527  /**
528   * Returns the corresponding wrapper type if this is a primitive type; otherwise returns {@code
529   * this} itself. Idempotent.
530   *
531   * @since 15.0
532   */
533  public final TypeToken<T> wrap() {
534    if (isPrimitive()) {
535      @SuppressWarnings("unchecked") // this is a primitive class
536      Class<T> type = (Class<T>) runtimeType;
537      return of(Primitives.wrap(type));
538    }
539    return this;
540  }
541
542  private boolean isWrapper() {
543    return Primitives.allWrapperTypes().contains(runtimeType);
544  }
545
546  /**
547   * Returns the corresponding primitive type if this is a wrapper type; otherwise returns {@code
548   * this} itself. Idempotent.
549   *
550   * @since 15.0
551   */
552  public final TypeToken<T> unwrap() {
553    if (isWrapper()) {
554      @SuppressWarnings("unchecked") // this is a wrapper class
555      Class<T> type = (Class<T>) runtimeType;
556      return of(Primitives.unwrap(type));
557    }
558    return this;
559  }
560
561  /**
562   * Returns the array component type if this type represents an array ({@code int[]}, {@code T[]},
563   * {@code <? extends Map<String, Integer>[]>} etc.), or else {@code null} is returned.
564   */
565  @NullableDecl
566  public final TypeToken<?> getComponentType() {
567    Type componentType = Types.getComponentType(runtimeType);
568    if (componentType == null) {
569      return null;
570    }
571    return of(componentType);
572  }
573
574  /**
575   * Returns the {@link Invokable} for {@code method}, which must be a member of {@code T}.
576   *
577   * @since 14.0
578   */
579  public final Invokable<T, Object> method(Method method) {
580    checkArgument(
581        this.someRawTypeIsSubclassOf(method.getDeclaringClass()),
582        "%s not declared by %s",
583        method,
584        this);
585    return new Invokable.MethodInvokable<T>(method) {
586      @Override
587      Type getGenericReturnType() {
588        return resolveType(super.getGenericReturnType()).getType();
589      }
590
591      @Override
592      Type[] getGenericParameterTypes() {
593        return resolveInPlace(super.getGenericParameterTypes());
594      }
595
596      @Override
597      Type[] getGenericExceptionTypes() {
598        return resolveInPlace(super.getGenericExceptionTypes());
599      }
600
601      @Override
602      public TypeToken<T> getOwnerType() {
603        return TypeToken.this;
604      }
605
606      @Override
607      public String toString() {
608        return getOwnerType() + "." + super.toString();
609      }
610    };
611  }
612
613  /**
614   * Returns the {@link Invokable} for {@code constructor}, which must be a member of {@code T}.
615   *
616   * @since 14.0
617   */
618  public final Invokable<T, T> constructor(Constructor<?> constructor) {
619    checkArgument(
620        constructor.getDeclaringClass() == getRawType(),
621        "%s not declared by %s",
622        constructor,
623        getRawType());
624    return new Invokable.ConstructorInvokable<T>(constructor) {
625      @Override
626      Type getGenericReturnType() {
627        return resolveType(super.getGenericReturnType()).getType();
628      }
629
630      @Override
631      Type[] getGenericParameterTypes() {
632        return resolveInPlace(super.getGenericParameterTypes());
633      }
634
635      @Override
636      Type[] getGenericExceptionTypes() {
637        return resolveInPlace(super.getGenericExceptionTypes());
638      }
639
640      @Override
641      public TypeToken<T> getOwnerType() {
642        return TypeToken.this;
643      }
644
645      @Override
646      public String toString() {
647        return getOwnerType() + "(" + Joiner.on(", ").join(getGenericParameterTypes()) + ")";
648      }
649    };
650  }
651
652  /**
653   * The set of interfaces and classes that {@code T} is or is a subtype of. {@link Object} is not
654   * included in the set if this type is an interface.
655   *
656   * @since 13.0
657   */
658  public class TypeSet extends ForwardingSet<TypeToken<? super T>> implements Serializable {
659
660    @MonotonicNonNullDecl private transient ImmutableSet<TypeToken<? super T>> types;
661
662    TypeSet() {}
663
664    /** Returns the types that are interfaces implemented by this type. */
665    public TypeSet interfaces() {
666      return new InterfaceSet(this);
667    }
668
669    /** Returns the types that are classes. */
670    public TypeSet classes() {
671      return new ClassSet();
672    }
673
674    @Override
675    protected Set<TypeToken<? super T>> delegate() {
676      ImmutableSet<TypeToken<? super T>> filteredTypes = types;
677      if (filteredTypes == null) {
678        // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
679        @SuppressWarnings({"unchecked", "rawtypes"})
680        ImmutableList<TypeToken<? super T>> collectedTypes =
681            (ImmutableList) TypeCollector.FOR_GENERIC_TYPE.collectTypes(TypeToken.this);
682        return (types =
683            FluentIterable.from(collectedTypes)
684                .filter(TypeFilter.IGNORE_TYPE_VARIABLE_OR_WILDCARD)
685                .toSet());
686      } else {
687        return filteredTypes;
688      }
689    }
690
691    /** Returns the raw types of the types in this set, in the same order. */
692    public Set<Class<? super T>> rawTypes() {
693      // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
694      @SuppressWarnings({"unchecked", "rawtypes"})
695      ImmutableList<Class<? super T>> collectedTypes =
696          (ImmutableList) TypeCollector.FOR_RAW_TYPE.collectTypes(getRawTypes());
697      return ImmutableSet.copyOf(collectedTypes);
698    }
699
700    private static final long serialVersionUID = 0;
701  }
702
703  private final class InterfaceSet extends TypeSet {
704
705    private final transient TypeSet allTypes;
706    @MonotonicNonNullDecl private transient ImmutableSet<TypeToken<? super T>> interfaces;
707
708    InterfaceSet(TypeSet allTypes) {
709      this.allTypes = allTypes;
710    }
711
712    @Override
713    protected Set<TypeToken<? super T>> delegate() {
714      ImmutableSet<TypeToken<? super T>> result = interfaces;
715      if (result == null) {
716        return (interfaces =
717            FluentIterable.from(allTypes).filter(TypeFilter.INTERFACE_ONLY).toSet());
718      } else {
719        return result;
720      }
721    }
722
723    @Override
724    public TypeSet interfaces() {
725      return this;
726    }
727
728    @Override
729    public Set<Class<? super T>> rawTypes() {
730      // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
731      @SuppressWarnings({"unchecked", "rawtypes"})
732      ImmutableList<Class<? super T>> collectedTypes =
733          (ImmutableList) TypeCollector.FOR_RAW_TYPE.collectTypes(getRawTypes());
734      return FluentIterable.from(collectedTypes)
735          .filter(
736              new Predicate<Class<?>>() {
737                @Override
738                public boolean apply(Class<?> type) {
739                  return type.isInterface();
740                }
741              })
742          .toSet();
743    }
744
745    @Override
746    public TypeSet classes() {
747      throw new UnsupportedOperationException("interfaces().classes() not supported.");
748    }
749
750    private Object readResolve() {
751      return getTypes().interfaces();
752    }
753
754    private static final long serialVersionUID = 0;
755  }
756
757  private final class ClassSet extends TypeSet {
758
759    @MonotonicNonNullDecl private transient ImmutableSet<TypeToken<? super T>> classes;
760
761    @Override
762    protected Set<TypeToken<? super T>> delegate() {
763      ImmutableSet<TypeToken<? super T>> result = classes;
764      if (result == null) {
765        @SuppressWarnings({"unchecked", "rawtypes"})
766        ImmutableList<TypeToken<? super T>> collectedTypes =
767            (ImmutableList)
768                TypeCollector.FOR_GENERIC_TYPE.classesOnly().collectTypes(TypeToken.this);
769        return (classes =
770            FluentIterable.from(collectedTypes)
771                .filter(TypeFilter.IGNORE_TYPE_VARIABLE_OR_WILDCARD)
772                .toSet());
773      } else {
774        return result;
775      }
776    }
777
778    @Override
779    public TypeSet classes() {
780      return this;
781    }
782
783    @Override
784    public Set<Class<? super T>> rawTypes() {
785      // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
786      @SuppressWarnings({"unchecked", "rawtypes"})
787      ImmutableList<Class<? super T>> collectedTypes =
788          (ImmutableList) TypeCollector.FOR_RAW_TYPE.classesOnly().collectTypes(getRawTypes());
789      return ImmutableSet.copyOf(collectedTypes);
790    }
791
792    @Override
793    public TypeSet interfaces() {
794      throw new UnsupportedOperationException("classes().interfaces() not supported.");
795    }
796
797    private Object readResolve() {
798      return getTypes().classes();
799    }
800
801    private static final long serialVersionUID = 0;
802  }
803
804  private enum TypeFilter implements Predicate<TypeToken<?>> {
805    IGNORE_TYPE_VARIABLE_OR_WILDCARD {
806      @Override
807      public boolean apply(TypeToken<?> type) {
808        return !(type.runtimeType instanceof TypeVariable
809            || type.runtimeType instanceof WildcardType);
810      }
811    },
812    INTERFACE_ONLY {
813      @Override
814      public boolean apply(TypeToken<?> type) {
815        return type.getRawType().isInterface();
816      }
817    }
818  }
819
820  /**
821   * Returns true if {@code o} is another {@code TypeToken} that represents the same {@link Type}.
822   */
823  @Override
824  public boolean equals(@NullableDecl Object o) {
825    if (o instanceof TypeToken) {
826      TypeToken<?> that = (TypeToken<?>) o;
827      return runtimeType.equals(that.runtimeType);
828    }
829    return false;
830  }
831
832  @Override
833  public int hashCode() {
834    return runtimeType.hashCode();
835  }
836
837  @Override
838  public String toString() {
839    return Types.toString(runtimeType);
840  }
841
842  /** Implemented to support serialization of subclasses. */
843  protected Object writeReplace() {
844    // TypeResolver just transforms the type to our own impls that are Serializable
845    // except TypeVariable.
846    return of(new TypeResolver().resolveType(runtimeType));
847  }
848
849  /**
850   * Ensures that this type token doesn't contain type variables, which can cause unchecked type
851   * errors for callers like {@link TypeToInstanceMap}.
852   */
853  @CanIgnoreReturnValue
854  final TypeToken<T> rejectTypeVariables() {
855    new TypeVisitor() {
856      @Override
857      void visitTypeVariable(TypeVariable<?> type) {
858        throw new IllegalArgumentException(
859            runtimeType + "contains a type variable and is not safe for the operation");
860      }
861
862      @Override
863      void visitWildcardType(WildcardType type) {
864        visit(type.getLowerBounds());
865        visit(type.getUpperBounds());
866      }
867
868      @Override
869      void visitParameterizedType(ParameterizedType type) {
870        visit(type.getActualTypeArguments());
871        visit(type.getOwnerType());
872      }
873
874      @Override
875      void visitGenericArrayType(GenericArrayType type) {
876        visit(type.getGenericComponentType());
877      }
878    }.visit(runtimeType);
879    return this;
880  }
881
882  private boolean someRawTypeIsSubclassOf(Class<?> superclass) {
883    for (Class<?> rawType : getRawTypes()) {
884      if (superclass.isAssignableFrom(rawType)) {
885        return true;
886      }
887    }
888    return false;
889  }
890
891  private boolean isSubtypeOfParameterizedType(ParameterizedType supertype) {
892    Class<?> matchedClass = of(supertype).getRawType();
893    if (!someRawTypeIsSubclassOf(matchedClass)) {
894      return false;
895    }
896    Type[] typeParams = matchedClass.getTypeParameters();
897    Type[] toTypeArgs = supertype.getActualTypeArguments();
898    for (int i = 0; i < typeParams.length; i++) {
899      // If 'supertype' is "List<? extends CharSequence>"
900      // and 'this' is StringArrayList,
901      // First step is to figure out StringArrayList "is-a" List<E> and <E> is
902      // String.
903      // typeParams[0] is E and fromTypeToken.get(typeParams[0]) will resolve to
904      // String.
905      // String is then matched against <? extends CharSequence>.
906      if (!resolveType(typeParams[i]).is(toTypeArgs[i])) {
907        return false;
908      }
909    }
910    // We only care about the case when the supertype is a non-static inner class
911    // in which case we need to make sure the subclass's owner type is a subtype of the
912    // supertype's owner.
913    return Modifier.isStatic(((Class<?>) supertype.getRawType()).getModifiers())
914        || supertype.getOwnerType() == null
915        || isOwnedBySubtypeOf(supertype.getOwnerType());
916  }
917
918  private boolean isSubtypeOfArrayType(GenericArrayType supertype) {
919    if (runtimeType instanceof Class) {
920      Class<?> fromClass = (Class<?>) runtimeType;
921      if (!fromClass.isArray()) {
922        return false;
923      }
924      return of(fromClass.getComponentType()).isSubtypeOf(supertype.getGenericComponentType());
925    } else if (runtimeType instanceof GenericArrayType) {
926      GenericArrayType fromArrayType = (GenericArrayType) runtimeType;
927      return of(fromArrayType.getGenericComponentType())
928          .isSubtypeOf(supertype.getGenericComponentType());
929    } else {
930      return false;
931    }
932  }
933
934  private boolean isSupertypeOfArray(GenericArrayType subtype) {
935    if (runtimeType instanceof Class) {
936      Class<?> thisClass = (Class<?>) runtimeType;
937      if (!thisClass.isArray()) {
938        return thisClass.isAssignableFrom(Object[].class);
939      }
940      return of(subtype.getGenericComponentType()).isSubtypeOf(thisClass.getComponentType());
941    } else if (runtimeType instanceof GenericArrayType) {
942      return of(subtype.getGenericComponentType())
943          .isSubtypeOf(((GenericArrayType) runtimeType).getGenericComponentType());
944    } else {
945      return false;
946    }
947  }
948
949  /**
950   * Return true if any of the following conditions is met:
951   *
952   * <ul>
953   *   <li>'this' and {@code formalType} are equal
954   *   <li>{@code formalType} is {@code <? extends Foo>} and 'this' is a subtype of {@code Foo}
955   *   <li>{@code formalType} is {@code <? super Foo>} and 'this' is a supertype of {@code Foo}
956   * </ul>
957   */
958  private boolean is(Type formalType) {
959    if (runtimeType.equals(formalType)) {
960      return true;
961    }
962    if (formalType instanceof WildcardType) {
963      // if "formalType" is <? extends Foo>, "this" can be:
964      // Foo, SubFoo, <? extends Foo>, <? extends SubFoo>, <T extends Foo> or
965      // <T extends SubFoo>.
966      // if "formalType" is <? super Foo>, "this" can be:
967      // Foo, SuperFoo, <? super Foo> or <? super SuperFoo>.
968      return every(((WildcardType) formalType).getUpperBounds()).isSupertypeOf(runtimeType)
969          && every(((WildcardType) formalType).getLowerBounds()).isSubtypeOf(runtimeType);
970    }
971    return false;
972  }
973
974  private static Bounds every(Type[] bounds) {
975    // Every bound must match. On any false, result is false.
976    return new Bounds(bounds, false);
977  }
978
979  private static Bounds any(Type[] bounds) {
980    // Any bound matches. On any true, result is true.
981    return new Bounds(bounds, true);
982  }
983
984  private static class Bounds {
985    private final Type[] bounds;
986    private final boolean target;
987
988    Bounds(Type[] bounds, boolean target) {
989      this.bounds = bounds;
990      this.target = target;
991    }
992
993    boolean isSubtypeOf(Type supertype) {
994      for (Type bound : bounds) {
995        if (of(bound).isSubtypeOf(supertype) == target) {
996          return target;
997        }
998      }
999      return !target;
1000    }
1001
1002    boolean isSupertypeOf(Type subtype) {
1003      TypeToken<?> type = of(subtype);
1004      for (Type bound : bounds) {
1005        if (type.isSubtypeOf(bound) == target) {
1006          return target;
1007        }
1008      }
1009      return !target;
1010    }
1011  }
1012
1013  private ImmutableSet<Class<? super T>> getRawTypes() {
1014    final ImmutableSet.Builder<Class<?>> builder = ImmutableSet.builder();
1015    new TypeVisitor() {
1016      @Override
1017      void visitTypeVariable(TypeVariable<?> t) {
1018        visit(t.getBounds());
1019      }
1020
1021      @Override
1022      void visitWildcardType(WildcardType t) {
1023        visit(t.getUpperBounds());
1024      }
1025
1026      @Override
1027      void visitParameterizedType(ParameterizedType t) {
1028        builder.add((Class<?>) t.getRawType());
1029      }
1030
1031      @Override
1032      void visitClass(Class<?> t) {
1033        builder.add(t);
1034      }
1035
1036      @Override
1037      void visitGenericArrayType(GenericArrayType t) {
1038        builder.add(Types.getArrayClass(of(t.getGenericComponentType()).getRawType()));
1039      }
1040    }.visit(runtimeType);
1041    // Cast from ImmutableSet<Class<?>> to ImmutableSet<Class<? super T>>
1042    @SuppressWarnings({"unchecked", "rawtypes"})
1043    ImmutableSet<Class<? super T>> result = (ImmutableSet) builder.build();
1044    return result;
1045  }
1046
1047  private boolean isOwnedBySubtypeOf(Type supertype) {
1048    for (TypeToken<?> type : getTypes()) {
1049      Type ownerType = type.getOwnerTypeIfPresent();
1050      if (ownerType != null && of(ownerType).isSubtypeOf(supertype)) {
1051        return true;
1052      }
1053    }
1054    return false;
1055  }
1056
1057  /**
1058   * Returns the owner type of a {@link ParameterizedType} or enclosing class of a {@link Class}, or
1059   * null otherwise.
1060   */
1061  @NullableDecl
1062  private Type getOwnerTypeIfPresent() {
1063    if (runtimeType instanceof ParameterizedType) {
1064      return ((ParameterizedType) runtimeType).getOwnerType();
1065    } else if (runtimeType instanceof Class<?>) {
1066      return ((Class<?>) runtimeType).getEnclosingClass();
1067    } else {
1068      return null;
1069    }
1070  }
1071
1072  /**
1073   * Returns the type token representing the generic type declaration of {@code cls}. For example:
1074   * {@code TypeToken.getGenericType(Iterable.class)} returns {@code Iterable<T>}.
1075   *
1076   * <p>If {@code cls} isn't parameterized and isn't a generic array, the type token of the class is
1077   * returned.
1078   */
1079  @VisibleForTesting
1080  static <T> TypeToken<? extends T> toGenericType(Class<T> cls) {
1081    if (cls.isArray()) {
1082      Type arrayOfGenericType =
1083          Types.newArrayType(
1084              // If we are passed with int[].class, don't turn it to GenericArrayType
1085              toGenericType(cls.getComponentType()).runtimeType);
1086      @SuppressWarnings("unchecked") // array is covariant
1087      TypeToken<? extends T> result = (TypeToken<? extends T>) of(arrayOfGenericType);
1088      return result;
1089    }
1090    TypeVariable<Class<T>>[] typeParams = cls.getTypeParameters();
1091    Type ownerType =
1092        cls.isMemberClass() && !Modifier.isStatic(cls.getModifiers())
1093            ? toGenericType(cls.getEnclosingClass()).runtimeType
1094            : null;
1095
1096    if ((typeParams.length > 0) || ((ownerType != null) && ownerType != cls.getEnclosingClass())) {
1097      @SuppressWarnings("unchecked") // Like, it's Iterable<T> for Iterable.class
1098      TypeToken<? extends T> type =
1099          (TypeToken<? extends T>)
1100              of(Types.newParameterizedTypeWithOwner(ownerType, cls, typeParams));
1101      return type;
1102    } else {
1103      return of(cls);
1104    }
1105  }
1106
1107  private TypeToken<? super T> getSupertypeFromUpperBounds(
1108      Class<? super T> supertype, Type[] upperBounds) {
1109    for (Type upperBound : upperBounds) {
1110      @SuppressWarnings("unchecked") // T's upperbound is <? super T>.
1111      TypeToken<? super T> bound = (TypeToken<? super T>) of(upperBound);
1112      if (bound.isSubtypeOf(supertype)) {
1113        @SuppressWarnings({"rawtypes", "unchecked"}) // guarded by the isSubtypeOf check.
1114        TypeToken<? super T> result = bound.getSupertype((Class) supertype);
1115        return result;
1116      }
1117    }
1118    throw new IllegalArgumentException(supertype + " isn't a super type of " + this);
1119  }
1120
1121  private TypeToken<? extends T> getSubtypeFromLowerBounds(Class<?> subclass, Type[] lowerBounds) {
1122    for (Type lowerBound : lowerBounds) {
1123      @SuppressWarnings("unchecked") // T's lower bound is <? extends T>
1124      TypeToken<? extends T> bound = (TypeToken<? extends T>) of(lowerBound);
1125      // Java supports only one lowerbound anyway.
1126      return bound.getSubtype(subclass);
1127    }
1128    throw new IllegalArgumentException(subclass + " isn't a subclass of " + this);
1129  }
1130
1131  private TypeToken<? super T> getArraySupertype(Class<? super T> supertype) {
1132    // with component type, we have lost generic type information
1133    // Use raw type so that compiler allows us to call getSupertype()
1134    @SuppressWarnings("rawtypes")
1135    TypeToken componentType =
1136        checkNotNull(getComponentType(), "%s isn't a super type of %s", supertype, this);
1137    // array is covariant. component type is super type, so is the array type.
1138    @SuppressWarnings("unchecked") // going from raw type back to generics
1139    TypeToken<?> componentSupertype = componentType.getSupertype(supertype.getComponentType());
1140    @SuppressWarnings("unchecked") // component type is super type, so is array type.
1141    TypeToken<? super T> result =
1142        (TypeToken<? super T>)
1143            // If we are passed with int[].class, don't turn it to GenericArrayType
1144            of(newArrayClassOrGenericArrayType(componentSupertype.runtimeType));
1145    return result;
1146  }
1147
1148  private TypeToken<? extends T> getArraySubtype(Class<?> subclass) {
1149    // array is covariant. component type is subtype, so is the array type.
1150    TypeToken<?> componentSubtype = getComponentType().getSubtype(subclass.getComponentType());
1151    @SuppressWarnings("unchecked") // component type is subtype, so is array type.
1152    TypeToken<? extends T> result =
1153        (TypeToken<? extends T>)
1154            // If we are passed with int[].class, don't turn it to GenericArrayType
1155            of(newArrayClassOrGenericArrayType(componentSubtype.runtimeType));
1156    return result;
1157  }
1158
1159  private Type resolveTypeArgsForSubclass(Class<?> subclass) {
1160    // If both runtimeType and subclass are not parameterized, return subclass
1161    // If runtimeType is not parameterized but subclass is, process subclass as a parameterized type
1162    // If runtimeType is a raw type (i.e. is a parameterized type specified as a Class<?>), we
1163    // return subclass as a raw type
1164    if (runtimeType instanceof Class
1165        && ((subclass.getTypeParameters().length == 0)
1166            || (getRawType().getTypeParameters().length != 0))) {
1167      // no resolution needed
1168      return subclass;
1169    }
1170    // class Base<A, B> {}
1171    // class Sub<X, Y> extends Base<X, Y> {}
1172    // Base<String, Integer>.subtype(Sub.class):
1173
1174    // Sub<X, Y>.getSupertype(Base.class) => Base<X, Y>
1175    // => X=String, Y=Integer
1176    // => Sub<X, Y>=Sub<String, Integer>
1177    TypeToken<?> genericSubtype = toGenericType(subclass);
1178    @SuppressWarnings({"rawtypes", "unchecked"}) // subclass isn't <? extends T>
1179    Type supertypeWithArgsFromSubtype =
1180        genericSubtype.getSupertype((Class) getRawType()).runtimeType;
1181    return new TypeResolver()
1182        .where(supertypeWithArgsFromSubtype, runtimeType)
1183        .resolveType(genericSubtype.runtimeType);
1184  }
1185
1186  /**
1187   * Creates an array class if {@code componentType} is a class, or else, a {@link
1188   * GenericArrayType}. This is what Java7 does for generic array type parameters.
1189   */
1190  private static Type newArrayClassOrGenericArrayType(Type componentType) {
1191    return Types.JavaVersion.JAVA7.newArrayType(componentType);
1192  }
1193
1194  private static final class SimpleTypeToken<T> extends TypeToken<T> {
1195
1196    SimpleTypeToken(Type type) {
1197      super(type);
1198    }
1199
1200    private static final long serialVersionUID = 0;
1201  }
1202
1203  /**
1204   * Collects parent types from a sub type.
1205   *
1206   * @param <K> The type "kind". Either a TypeToken, or Class.
1207   */
1208  private abstract static class TypeCollector<K> {
1209
1210    static final TypeCollector<TypeToken<?>> FOR_GENERIC_TYPE =
1211        new TypeCollector<TypeToken<?>>() {
1212          @Override
1213          Class<?> getRawType(TypeToken<?> type) {
1214            return type.getRawType();
1215          }
1216
1217          @Override
1218          Iterable<? extends TypeToken<?>> getInterfaces(TypeToken<?> type) {
1219            return type.getGenericInterfaces();
1220          }
1221
1222          @NullableDecl
1223          @Override
1224          TypeToken<?> getSuperclass(TypeToken<?> type) {
1225            return type.getGenericSuperclass();
1226          }
1227        };
1228
1229    static final TypeCollector<Class<?>> FOR_RAW_TYPE =
1230        new TypeCollector<Class<?>>() {
1231          @Override
1232          Class<?> getRawType(Class<?> type) {
1233            return type;
1234          }
1235
1236          @Override
1237          Iterable<? extends Class<?>> getInterfaces(Class<?> type) {
1238            return Arrays.asList(type.getInterfaces());
1239          }
1240
1241          @NullableDecl
1242          @Override
1243          Class<?> getSuperclass(Class<?> type) {
1244            return type.getSuperclass();
1245          }
1246        };
1247
1248    /** For just classes, we don't have to traverse interfaces. */
1249    final TypeCollector<K> classesOnly() {
1250      return new ForwardingTypeCollector<K>(this) {
1251        @Override
1252        Iterable<? extends K> getInterfaces(K type) {
1253          return ImmutableSet.of();
1254        }
1255
1256        @Override
1257        ImmutableList<K> collectTypes(Iterable<? extends K> types) {
1258          ImmutableList.Builder<K> builder = ImmutableList.builder();
1259          for (K type : types) {
1260            if (!getRawType(type).isInterface()) {
1261              builder.add(type);
1262            }
1263          }
1264          return super.collectTypes(builder.build());
1265        }
1266      };
1267    }
1268
1269    final ImmutableList<K> collectTypes(K type) {
1270      return collectTypes(ImmutableList.of(type));
1271    }
1272
1273    ImmutableList<K> collectTypes(Iterable<? extends K> types) {
1274      // type -> order number. 1 for Object, 2 for anything directly below, so on so forth.
1275      Map<K, Integer> map = Maps.newHashMap();
1276      for (K type : types) {
1277        collectTypes(type, map);
1278      }
1279      return sortKeysByValue(map, Ordering.natural().reverse());
1280    }
1281
1282    /** Collects all types to map, and returns the total depth from T up to Object. */
1283    @CanIgnoreReturnValue
1284    private int collectTypes(K type, Map<? super K, Integer> map) {
1285      Integer existing = map.get(type);
1286      if (existing != null) {
1287        // short circuit: if set contains type it already contains its supertypes
1288        return existing;
1289      }
1290      // Interfaces should be listed before Object.
1291      int aboveMe = getRawType(type).isInterface() ? 1 : 0;
1292      for (K interfaceType : getInterfaces(type)) {
1293        aboveMe = Math.max(aboveMe, collectTypes(interfaceType, map));
1294      }
1295      K superclass = getSuperclass(type);
1296      if (superclass != null) {
1297        aboveMe = Math.max(aboveMe, collectTypes(superclass, map));
1298      }
1299      /*
1300       * TODO(benyu): should we include Object for interface? Also, CharSequence[] and Object[] for
1301       * String[]?
1302       *
1303       */
1304      map.put(type, aboveMe + 1);
1305      return aboveMe + 1;
1306    }
1307
1308    private static <K, V> ImmutableList<K> sortKeysByValue(
1309        final Map<K, V> map, final Comparator<? super V> valueComparator) {
1310      Ordering<K> keyOrdering =
1311          new Ordering<K>() {
1312            @Override
1313            public int compare(K left, K right) {
1314              return valueComparator.compare(map.get(left), map.get(right));
1315            }
1316          };
1317      return keyOrdering.immutableSortedCopy(map.keySet());
1318    }
1319
1320    abstract Class<?> getRawType(K type);
1321
1322    abstract Iterable<? extends K> getInterfaces(K type);
1323
1324    @NullableDecl
1325    abstract K getSuperclass(K type);
1326
1327    private static class ForwardingTypeCollector<K> extends TypeCollector<K> {
1328
1329      private final TypeCollector<K> delegate;
1330
1331      ForwardingTypeCollector(TypeCollector<K> delegate) {
1332        this.delegate = delegate;
1333      }
1334
1335      @Override
1336      Class<?> getRawType(K type) {
1337        return delegate.getRawType(type);
1338      }
1339
1340      @Override
1341      Iterable<? extends K> getInterfaces(K type) {
1342        return delegate.getInterfaces(type);
1343      }
1344
1345      @Override
1346      K getSuperclass(K type) {
1347        return delegate.getSuperclass(type);
1348      }
1349    }
1350  }
1351}