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