Home | History | Annotate | Download | only in reflect
      1 /*
      2  * Copyright (C) 2006 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.reflect;
     18 
     19 import static com.google.common.base.Preconditions.checkArgument;
     20 import static com.google.common.base.Preconditions.checkNotNull;
     21 import static com.google.common.base.Preconditions.checkState;
     22 
     23 import com.google.common.annotations.Beta;
     24 import com.google.common.annotations.VisibleForTesting;
     25 import com.google.common.base.Joiner;
     26 import com.google.common.base.Predicate;
     27 import com.google.common.collect.FluentIterable;
     28 import com.google.common.collect.ForwardingSet;
     29 import com.google.common.collect.ImmutableList;
     30 import com.google.common.collect.ImmutableMap;
     31 import com.google.common.collect.ImmutableSet;
     32 import com.google.common.collect.Maps;
     33 import com.google.common.collect.Ordering;
     34 import com.google.common.primitives.Primitives;
     35 
     36 import java.io.Serializable;
     37 import java.lang.reflect.Constructor;
     38 import java.lang.reflect.GenericArrayType;
     39 import java.lang.reflect.Method;
     40 import java.lang.reflect.ParameterizedType;
     41 import java.lang.reflect.Type;
     42 import java.lang.reflect.TypeVariable;
     43 import java.lang.reflect.WildcardType;
     44 import java.util.Arrays;
     45 import java.util.Comparator;
     46 import java.util.Map;
     47 import java.util.Set;
     48 
     49 import javax.annotation.Nullable;
     50 
     51 /**
     52  * A {@link Type} with generics.
     53  *
     54  * <p>Operations that are otherwise only available in {@link Class} are implemented to support
     55  * {@code Type}, for example {@link #isAssignableFrom}, {@link #isArray} and {@link
     56  * #getComponentType}. It also provides additional utilities such as {@link #getTypes} and {@link
     57  * #resolveType} etc.
     58  *
     59  * <p>There are three ways to get a {@code TypeToken} instance: <ul>
     60  * <li>Wrap a {@code Type} obtained via reflection. For example: {@code
     61  * TypeToken.of(method.getGenericReturnType())}.
     62  * <li>Capture a generic type with a (usually anonymous) subclass. For example: <pre>   {@code
     63  *   new TypeToken<List<String>>() {}}</pre>
     64  * <p>Note that it's critical that the actual type argument is carried by a subclass.
     65  * The following code is wrong because it only captures the {@code <T>} type variable
     66  * of the {@code listType()} method signature; while {@code <String>} is lost in erasure:
     67  * <pre>   {@code
     68  *   class Util {
     69  *     static <T> TypeToken<List<T>> listType() {
     70  *       return new TypeToken<List<T>>() {};
     71  *     }
     72  *   }
     73  *
     74  *   TypeToken<List<String>> stringListType = Util.<String>listType();}</pre>
     75  * <li>Capture a generic type with a (usually anonymous) subclass and resolve it against
     76  * a context class that knows what the type parameters are. For example: <pre>   {@code
     77  *   abstract class IKnowMyType<T> {
     78  *     TypeToken<T> type = new TypeToken<T>(getClass()) {};
     79  *   }
     80  *   new IKnowMyType<String>() {}.type => String}</pre>
     81  * </ul>
     82  *
     83  * <p>{@code TypeToken} is serializable when no type variable is contained in the type.
     84  *
     85  * <p>Note to Guice users: {@code} TypeToken is similar to Guice's {@code TypeLiteral} class
     86  * except that it is serializable and offers numerous additional utility methods.
     87  *
     88  * @author Bob Lee
     89  * @author Sven Mawson
     90  * @author Ben Yu
     91  * @since 12.0
     92  */
     93 @Beta
     94 @SuppressWarnings("serial") // SimpleTypeToken is the serialized form.
     95 public abstract class TypeToken<T> extends TypeCapture<T> implements Serializable {
     96 
     97   private final Type runtimeType;
     98 
     99   /** 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     Class<?> rawType = getRawType(runtimeType);
    178     @SuppressWarnings("unchecked") // raw type is |T|
    179     Class<? super T> result = (Class<? super T>) rawType;
    180     return result;
    181   }
    182 
    183   /**
    184    * Returns the raw type of the class or parameterized type; if {@code T} is type variable or
    185    * wildcard type, the raw types of all its upper bounds are returned.
    186    */
    187   private ImmutableSet<Class<? super T>> getImmediateRawTypes() {
    188     // Cast from ImmutableSet<Class<?>> to ImmutableSet<Class<? super T>>
    189     @SuppressWarnings({"unchecked", "rawtypes"})
    190     ImmutableSet<Class<? super T>> result = (ImmutableSet) getRawTypes(runtimeType);
    191     return result;
    192   }
    193 
    194   /** Returns the represented type. */
    195   public final Type getType() {
    196     return runtimeType;
    197   }
    198 
    199   /**
    200    * <p>Returns a new {@code TypeToken} where type variables represented by {@code typeParam}
    201    * are substituted by {@code typeArg}. For example, it can be used to construct
    202    * {@code Map<K, V>} for any {@code K} and {@code V} type: <pre>   {@code
    203    *   static <K, V> TypeToken<Map<K, V>> mapOf(
    204    *       TypeToken<K> keyType, TypeToken<V> valueType) {
    205    *     return new TypeToken<Map<K, V>>() {}
    206    *         .where(new TypeParameter<K>() {}, keyType)
    207    *         .where(new TypeParameter<V>() {}, valueType);
    208    *   }}</pre>
    209    *
    210    * @param <X> The parameter type
    211    * @param typeParam the parameter type variable
    212    * @param typeArg the actual type to substitute
    213    */
    214   public final <X> TypeToken<T> where(TypeParameter<X> typeParam, TypeToken<X> typeArg) {
    215     TypeResolver resolver = new TypeResolver()
    216         .where(ImmutableMap.of(
    217             new TypeResolver.TypeVariableKey(typeParam.typeVariable),
    218             typeArg.runtimeType));
    219     // If there's any type error, we'd report now rather than later.
    220     return new SimpleTypeToken<T>(resolver.resolveType(runtimeType));
    221   }
    222 
    223   /**
    224    * <p>Returns a new {@code TypeToken} where type variables represented by {@code typeParam}
    225    * are substituted by {@code typeArg}. For example, it can be used to construct
    226    * {@code Map<K, V>} for any {@code K} and {@code V} type: <pre>   {@code
    227    *   static <K, V> TypeToken<Map<K, V>> mapOf(
    228    *       Class<K> keyType, Class<V> valueType) {
    229    *     return new TypeToken<Map<K, V>>() {}
    230    *         .where(new TypeParameter<K>() {}, keyType)
    231    *         .where(new TypeParameter<V>() {}, valueType);
    232    *   }}</pre>
    233    *
    234    * @param <X> The parameter type
    235    * @param typeParam the parameter type variable
    236    * @param typeArg the actual type to substitute
    237    */
    238   public final <X> TypeToken<T> where(TypeParameter<X> typeParam, Class<X> typeArg) {
    239     return where(typeParam, of(typeArg));
    240   }
    241 
    242   /**
    243    * <p>Resolves the given {@code type} against the type context represented by this type.
    244    * For example: <pre>   {@code
    245    *   new TypeToken<List<String>>() {}.resolveType(
    246    *       List.class.getMethod("get", int.class).getGenericReturnType())
    247    *   => String.class}</pre>
    248    */
    249   public final TypeToken<?> resolveType(Type type) {
    250     checkNotNull(type);
    251     TypeResolver resolver = typeResolver;
    252     if (resolver == null) {
    253       resolver = (typeResolver = TypeResolver.accordingTo(runtimeType));
    254     }
    255     return of(resolver.resolveType(type));
    256   }
    257 
    258   private Type[] resolveInPlace(Type[] types) {
    259     for (int i = 0; i < types.length; i++) {
    260       types[i] = resolveType(types[i]).getType();
    261     }
    262     return types;
    263   }
    264 
    265   private TypeToken<?> resolveSupertype(Type type) {
    266     TypeToken<?> supertype = resolveType(type);
    267     // super types' type mapping is a subset of type mapping of this type.
    268     supertype.typeResolver = typeResolver;
    269     return supertype;
    270   }
    271 
    272   /**
    273    * Returns the generic superclass of this type or {@code null} if the type represents
    274    * {@link Object} or an interface. This method is similar but different from {@link
    275    * Class#getGenericSuperclass}. For example, {@code
    276    * new TypeToken<StringArrayList>() {}.getGenericSuperclass()} will return {@code
    277    * new TypeToken<ArrayList<String>>() {}}; while {@code
    278    * StringArrayList.class.getGenericSuperclass()} will return {@code ArrayList<E>}, where {@code E}
    279    * is the type variable declared by class {@code ArrayList}.
    280    *
    281    * <p>If this type is a type variable or wildcard, its first upper bound is examined and returned
    282    * if the bound is a class or extends from a class. This means that the returned type could be a
    283    * type variable too.
    284    */
    285   @Nullable
    286   final TypeToken<? super T> getGenericSuperclass() {
    287     if (runtimeType instanceof TypeVariable) {
    288       // First bound is always the super class, if one exists.
    289       return boundAsSuperclass(((TypeVariable<?>) runtimeType).getBounds()[0]);
    290     }
    291     if (runtimeType instanceof WildcardType) {
    292       // wildcard has one and only one upper bound.
    293       return boundAsSuperclass(((WildcardType) runtimeType).getUpperBounds()[0]);
    294     }
    295     Type superclass = getRawType().getGenericSuperclass();
    296     if (superclass == null) {
    297       return null;
    298     }
    299     @SuppressWarnings("unchecked") // super class of T
    300     TypeToken<? super T> superToken = (TypeToken<? super T>) resolveSupertype(superclass);
    301     return superToken;
    302   }
    303 
    304   @Nullable private TypeToken<? super T> boundAsSuperclass(Type bound) {
    305     TypeToken<?> token = of(bound);
    306     if (token.getRawType().isInterface()) {
    307       return null;
    308     }
    309     @SuppressWarnings("unchecked") // only upper bound of T is passed in.
    310     TypeToken<? super T> superclass = (TypeToken<? super T>) token;
    311     return superclass;
    312   }
    313 
    314   /**
    315    * Returns the generic interfaces that this type directly {@code implements}. This method is
    316    * similar but different from {@link Class#getGenericInterfaces()}. For example, {@code
    317    * new TypeToken<List<String>>() {}.getGenericInterfaces()} will return a list that contains
    318    * {@code new TypeToken<Iterable<String>>() {}}; while {@code List.class.getGenericInterfaces()}
    319    * will return an array that contains {@code Iterable<T>}, where the {@code T} is the type
    320    * variable declared by interface {@code Iterable}.
    321    *
    322    * <p>If this type is a type variable or wildcard, its upper bounds are examined and those that
    323    * are either an interface or upper-bounded only by interfaces are returned. This means that the
    324    * returned types could include type variables too.
    325    */
    326   final ImmutableList<TypeToken<? super T>> getGenericInterfaces() {
    327     if (runtimeType instanceof TypeVariable) {
    328       return boundsAsInterfaces(((TypeVariable<?>) runtimeType).getBounds());
    329     }
    330     if (runtimeType instanceof WildcardType) {
    331       return boundsAsInterfaces(((WildcardType) runtimeType).getUpperBounds());
    332     }
    333     ImmutableList.Builder<TypeToken<? super T>> builder = ImmutableList.builder();
    334     for (Type interfaceType : getRawType().getGenericInterfaces()) {
    335       @SuppressWarnings("unchecked") // interface of T
    336       TypeToken<? super T> resolvedInterface = (TypeToken<? super T>)
    337           resolveSupertype(interfaceType);
    338       builder.add(resolvedInterface);
    339     }
    340     return builder.build();
    341   }
    342 
    343   private ImmutableList<TypeToken<? super T>> boundsAsInterfaces(Type[] bounds) {
    344     ImmutableList.Builder<TypeToken<? super T>> builder = ImmutableList.builder();
    345     for (Type bound : bounds) {
    346       @SuppressWarnings("unchecked") // upper bound of T
    347       TypeToken<? super T> boundType = (TypeToken<? super T>) of(bound);
    348       if (boundType.getRawType().isInterface()) {
    349         builder.add(boundType);
    350       }
    351     }
    352     return builder.build();
    353   }
    354 
    355   /**
    356    * Returns the set of interfaces and classes that this type is or is a subtype of. The returned
    357    * types are parameterized with proper type arguments.
    358    *
    359    * <p>Subtypes are always listed before supertypes. But the reverse is not true. A type isn't
    360    * necessarily a subtype of all the types following. Order between types without subtype
    361    * relationship is arbitrary and not guaranteed.
    362    *
    363    * <p>If this type is a type variable or wildcard, upper bounds that are themselves type variables
    364    * aren't included (their super interfaces and superclasses are).
    365    */
    366   public final TypeSet getTypes() {
    367     return new TypeSet();
    368   }
    369 
    370   /**
    371    * Returns the generic form of {@code superclass}. For example, if this is
    372    * {@code ArrayList<String>}, {@code Iterable<String>} is returned given the
    373    * input {@code Iterable.class}.
    374    */
    375   public final TypeToken<? super T> getSupertype(Class<? super T> superclass) {
    376     checkArgument(superclass.isAssignableFrom(getRawType()),
    377         "%s is not a super class of %s", superclass, this);
    378     if (runtimeType instanceof TypeVariable) {
    379       return getSupertypeFromUpperBounds(superclass, ((TypeVariable<?>) runtimeType).getBounds());
    380     }
    381     if (runtimeType instanceof WildcardType) {
    382       return getSupertypeFromUpperBounds(superclass, ((WildcardType) runtimeType).getUpperBounds());
    383     }
    384     if (superclass.isArray()) {
    385       return getArraySupertype(superclass);
    386     }
    387     @SuppressWarnings("unchecked") // resolved supertype
    388     TypeToken<? super T> supertype = (TypeToken<? super T>)
    389         resolveSupertype(toGenericType(superclass).runtimeType);
    390     return supertype;
    391   }
    392 
    393   /**
    394    * Returns subtype of {@code this} with {@code subclass} as the raw class.
    395    * For example, if this is {@code Iterable<String>} and {@code subclass} is {@code List},
    396    * {@code List<String>} is returned.
    397    */
    398   public final TypeToken<? extends T> getSubtype(Class<?> subclass) {
    399     checkArgument(!(runtimeType instanceof TypeVariable),
    400         "Cannot get subtype of type variable <%s>", this);
    401     if (runtimeType instanceof WildcardType) {
    402       return getSubtypeFromLowerBounds(subclass, ((WildcardType) runtimeType).getLowerBounds());
    403     }
    404     checkArgument(getRawType().isAssignableFrom(subclass),
    405         "%s isn't a subclass of %s", subclass, this);
    406     // unwrap array type if necessary
    407     if (isArray()) {
    408       return getArraySubtype(subclass);
    409     }
    410     @SuppressWarnings("unchecked") // guarded by the isAssignableFrom() statement above
    411     TypeToken<? extends T> subtype = (TypeToken<? extends T>)
    412         of(resolveTypeArgsForSubclass(subclass));
    413     return subtype;
    414   }
    415 
    416   /** Returns true if this type is assignable from the given {@code type}. */
    417   public final boolean isAssignableFrom(TypeToken<?> type) {
    418     return isAssignableFrom(type.runtimeType);
    419   }
    420 
    421   /** Check if this type is assignable from the given {@code type}. */
    422   public final boolean isAssignableFrom(Type type) {
    423     return isAssignable(checkNotNull(type), runtimeType);
    424   }
    425 
    426   /**
    427    * Returns true if this type is known to be an array type, such as {@code int[]}, {@code T[]},
    428    * {@code <? extends Map<String, Integer>[]>} etc.
    429    */
    430   public final boolean isArray() {
    431     return getComponentType() != null;
    432   }
    433 
    434   /**
    435    * Returns true if this type is one of the nine primitive types (including {@code void}).
    436    *
    437    * @since 15.0
    438    */
    439   public final boolean isPrimitive() {
    440     return (runtimeType instanceof Class) && ((Class<?>) runtimeType).isPrimitive();
    441   }
    442 
    443   /**
    444    * Returns the corresponding wrapper type if this is a primitive type; otherwise returns
    445    * {@code this} itself. Idempotent.
    446    *
    447    * @since 15.0
    448    */
    449   public final TypeToken<T> wrap() {
    450     if (isPrimitive()) {
    451       @SuppressWarnings("unchecked") // this is a primitive class
    452       Class<T> type = (Class<T>) runtimeType;
    453       return TypeToken.of(Primitives.wrap(type));
    454     }
    455     return this;
    456   }
    457 
    458   private boolean isWrapper() {
    459     return Primitives.allWrapperTypes().contains(runtimeType);
    460   }
    461 
    462   /**
    463    * Returns the corresponding primitive type if this is a wrapper type; otherwise returns
    464    * {@code this} itself. Idempotent.
    465    *
    466    * @since 15.0
    467    */
    468   public final TypeToken<T> unwrap() {
    469     if (isWrapper()) {
    470       @SuppressWarnings("unchecked") // this is a wrapper class
    471       Class<T> type = (Class<T>) runtimeType;
    472       return TypeToken.of(Primitives.unwrap(type));
    473     }
    474     return this;
    475   }
    476 
    477   /**
    478    * Returns the array component type if this type represents an array ({@code int[]}, {@code T[]},
    479    * {@code <? extends Map<String, Integer>[]>} etc.), or else {@code null} is returned.
    480    */
    481   @Nullable public final TypeToken<?> getComponentType() {
    482     Type componentType = Types.getComponentType(runtimeType);
    483     if (componentType == null) {
    484       return null;
    485     }
    486     return of(componentType);
    487   }
    488 
    489   /**
    490    * Returns the {@link Invokable} for {@code method}, which must be a member of {@code T}.
    491    *
    492    * @since 14.0
    493    */
    494   public final Invokable<T, Object> method(Method method) {
    495     checkArgument(of(method.getDeclaringClass()).isAssignableFrom(this),
    496         "%s not declared by %s", method, this);
    497     return new Invokable.MethodInvokable<T>(method) {
    498       @Override Type getGenericReturnType() {
    499         return resolveType(super.getGenericReturnType()).getType();
    500       }
    501       @Override Type[] getGenericParameterTypes() {
    502         return resolveInPlace(super.getGenericParameterTypes());
    503       }
    504       @Override Type[] getGenericExceptionTypes() {
    505         return resolveInPlace(super.getGenericExceptionTypes());
    506       }
    507       @Override public TypeToken<T> getOwnerType() {
    508         return TypeToken.this;
    509       }
    510       @Override public String toString() {
    511         return getOwnerType() + "." + super.toString();
    512       }
    513     };
    514   }
    515 
    516   /**
    517    * Returns the {@link Invokable} for {@code constructor}, which must be a member of {@code T}.
    518    *
    519    * @since 14.0
    520    */
    521   public final Invokable<T, T> constructor(Constructor<?> constructor) {
    522     checkArgument(constructor.getDeclaringClass() == getRawType(),
    523         "%s not declared by %s", constructor, getRawType());
    524     return new Invokable.ConstructorInvokable<T>(constructor) {
    525       @Override Type getGenericReturnType() {
    526         return resolveType(super.getGenericReturnType()).getType();
    527       }
    528       @Override Type[] getGenericParameterTypes() {
    529         return resolveInPlace(super.getGenericParameterTypes());
    530       }
    531       @Override Type[] getGenericExceptionTypes() {
    532         return resolveInPlace(super.getGenericExceptionTypes());
    533       }
    534       @Override public TypeToken<T> getOwnerType() {
    535         return TypeToken.this;
    536       }
    537       @Override public String toString() {
    538         return getOwnerType() + "(" + Joiner.on(", ").join(getGenericParameterTypes()) + ")";
    539       }
    540     };
    541   }
    542 
    543   /**
    544    * The set of interfaces and classes that {@code T} is or is a subtype of. {@link Object} is not
    545    * included in the set if this type is an interface.
    546    */
    547   public class TypeSet extends ForwardingSet<TypeToken<? super T>> implements Serializable {
    548 
    549     private transient ImmutableSet<TypeToken<? super T>> types;
    550 
    551     TypeSet() {}
    552 
    553     /** Returns the types that are interfaces implemented by this type. */
    554     public TypeSet interfaces() {
    555       return new InterfaceSet(this);
    556     }
    557 
    558     /** Returns the types that are classes. */
    559     public TypeSet classes() {
    560       return new ClassSet();
    561     }
    562 
    563     @Override protected Set<TypeToken<? super T>> delegate() {
    564       ImmutableSet<TypeToken<? super T>> filteredTypes = types;
    565       if (filteredTypes == null) {
    566         // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
    567         @SuppressWarnings({"unchecked", "rawtypes"})
    568         ImmutableList<TypeToken<? super T>> collectedTypes = (ImmutableList)
    569             TypeCollector.FOR_GENERIC_TYPE.collectTypes(TypeToken.this);
    570         return (types = FluentIterable.from(collectedTypes)
    571                 .filter(TypeFilter.IGNORE_TYPE_VARIABLE_OR_WILDCARD)
    572                 .toSet());
    573       } else {
    574         return filteredTypes;
    575       }
    576     }
    577 
    578     /** Returns the raw types of the types in this set, in the same order. */
    579     public Set<Class<? super T>> rawTypes() {
    580       // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
    581       @SuppressWarnings({"unchecked", "rawtypes"})
    582       ImmutableList<Class<? super T>> collectedTypes = (ImmutableList)
    583           TypeCollector.FOR_RAW_TYPE.collectTypes(getImmediateRawTypes());
    584       return ImmutableSet.copyOf(collectedTypes);
    585     }
    586 
    587     private static final long serialVersionUID = 0;
    588   }
    589 
    590   private final class InterfaceSet extends TypeSet {
    591 
    592     private transient final TypeSet allTypes;
    593     private transient ImmutableSet<TypeToken<? super T>> interfaces;
    594 
    595     InterfaceSet(TypeSet allTypes) {
    596       this.allTypes = allTypes;
    597     }
    598 
    599     @Override protected Set<TypeToken<? super T>> delegate() {
    600       ImmutableSet<TypeToken<? super T>> result = interfaces;
    601       if (result == null) {
    602         return (interfaces = FluentIterable.from(allTypes)
    603             .filter(TypeFilter.INTERFACE_ONLY)
    604             .toSet());
    605       } else {
    606         return result;
    607       }
    608     }
    609 
    610     @Override public TypeSet interfaces() {
    611       return this;
    612     }
    613 
    614     @Override public Set<Class<? super T>> rawTypes() {
    615       // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
    616       @SuppressWarnings({"unchecked", "rawtypes"})
    617       ImmutableList<Class<? super T>> collectedTypes = (ImmutableList)
    618           TypeCollector.FOR_RAW_TYPE.collectTypes(getImmediateRawTypes());
    619       return FluentIterable.from(collectedTypes)
    620           .filter(new Predicate<Class<?>>() {
    621             @Override public boolean apply(Class<?> type) {
    622               return type.isInterface();
    623             }
    624           })
    625           .toSet();
    626     }
    627 
    628     @Override public TypeSet classes() {
    629       throw new UnsupportedOperationException("interfaces().classes() not supported.");
    630     }
    631 
    632     private Object readResolve() {
    633       return getTypes().interfaces();
    634     }
    635 
    636     private static final long serialVersionUID = 0;
    637   }
    638 
    639   private final class ClassSet extends TypeSet {
    640 
    641     private transient ImmutableSet<TypeToken<? super T>> classes;
    642 
    643     @Override protected Set<TypeToken<? super T>> delegate() {
    644       ImmutableSet<TypeToken<? super T>> result = classes;
    645       if (result == null) {
    646         @SuppressWarnings({"unchecked", "rawtypes"})
    647         ImmutableList<TypeToken<? super T>> collectedTypes = (ImmutableList)
    648             TypeCollector.FOR_GENERIC_TYPE.classesOnly().collectTypes(TypeToken.this);
    649         return (classes = FluentIterable.from(collectedTypes)
    650             .filter(TypeFilter.IGNORE_TYPE_VARIABLE_OR_WILDCARD)
    651             .toSet());
    652       } else {
    653         return result;
    654       }
    655     }
    656 
    657     @Override public TypeSet classes() {
    658       return this;
    659     }
    660 
    661     @Override public Set<Class<? super T>> rawTypes() {
    662       // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
    663       @SuppressWarnings({"unchecked", "rawtypes"})
    664       ImmutableList<Class<? super T>> collectedTypes = (ImmutableList)
    665           TypeCollector.FOR_RAW_TYPE.classesOnly().collectTypes(getImmediateRawTypes());
    666       return ImmutableSet.copyOf(collectedTypes);
    667     }
    668 
    669     @Override public TypeSet interfaces() {
    670       throw new UnsupportedOperationException("classes().interfaces() not supported.");
    671     }
    672 
    673     private Object readResolve() {
    674       return getTypes().classes();
    675     }
    676 
    677     private static final long serialVersionUID = 0;
    678   }
    679 
    680   private enum TypeFilter implements Predicate<TypeToken<?>> {
    681 
    682     IGNORE_TYPE_VARIABLE_OR_WILDCARD {
    683       @Override public boolean apply(TypeToken<?> type) {
    684         return !(type.runtimeType instanceof TypeVariable
    685             || type.runtimeType instanceof WildcardType);
    686       }
    687     },
    688     INTERFACE_ONLY {
    689       @Override public boolean apply(TypeToken<?> type) {
    690         return type.getRawType().isInterface();
    691       }
    692     }
    693   }
    694 
    695   /**
    696    * Returns true if {@code o} is another {@code TypeToken} that represents the same {@link Type}.
    697    */
    698   @Override public boolean equals(@Nullable Object o) {
    699     if (o instanceof TypeToken) {
    700       TypeToken<?> that = (TypeToken<?>) o;
    701       return runtimeType.equals(that.runtimeType);
    702     }
    703     return false;
    704   }
    705 
    706   @Override public int hashCode() {
    707     return runtimeType.hashCode();
    708   }
    709 
    710   @Override public String toString() {
    711     return Types.toString(runtimeType);
    712   }
    713 
    714   /** Implemented to support serialization of subclasses. */
    715   protected Object writeReplace() {
    716     // TypeResolver just transforms the type to our own impls that are Serializable
    717     // except TypeVariable.
    718     return of(new TypeResolver().resolveType(runtimeType));
    719   }
    720 
    721   /**
    722    * Ensures that this type token doesn't contain type variables, which can cause unchecked type
    723    * errors for callers like {@link TypeToInstanceMap}.
    724    */
    725   final TypeToken<T> rejectTypeVariables() {
    726     new TypeVisitor() {
    727       @Override void visitTypeVariable(TypeVariable<?> type) {
    728         throw new IllegalArgumentException(
    729             runtimeType + "contains a type variable and is not safe for the operation");
    730       }
    731       @Override void visitWildcardType(WildcardType type) {
    732         visit(type.getLowerBounds());
    733         visit(type.getUpperBounds());
    734       }
    735       @Override void visitParameterizedType(ParameterizedType type) {
    736         visit(type.getActualTypeArguments());
    737         visit(type.getOwnerType());
    738       }
    739       @Override void visitGenericArrayType(GenericArrayType type) {
    740         visit(type.getGenericComponentType());
    741       }
    742     }.visit(runtimeType);
    743     return this;
    744   }
    745 
    746   private static boolean isAssignable(Type from, Type to) {
    747     if (to.equals(from)) {
    748       return true;
    749     }
    750     if (to instanceof WildcardType) {
    751       return isAssignableToWildcardType(from, (WildcardType) to);
    752     }
    753     // if "from" is type variable, it's assignable if any of its "extends"
    754     // bounds is assignable to "to".
    755     if (from instanceof TypeVariable) {
    756       return isAssignableFromAny(((TypeVariable<?>) from).getBounds(), to);
    757     }
    758     // if "from" is wildcard, it'a assignable to "to" if any of its "extends"
    759     // bounds is assignable to "to".
    760     if (from instanceof WildcardType) {
    761       return isAssignableFromAny(((WildcardType) from).getUpperBounds(), to);
    762     }
    763     if (from instanceof GenericArrayType) {
    764       return isAssignableFromGenericArrayType((GenericArrayType) from, to);
    765     }
    766     // Proceed to regular Type assignability check
    767     if (to instanceof Class) {
    768       return isAssignableToClass(from, (Class<?>) to);
    769     } else if (to instanceof ParameterizedType) {
    770       return isAssignableToParameterizedType(from, (ParameterizedType) to);
    771     } else if (to instanceof GenericArrayType) {
    772       return isAssignableToGenericArrayType(from, (GenericArrayType) to);
    773     } else { // to instanceof TypeVariable
    774       return false;
    775     }
    776   }
    777 
    778   private static boolean isAssignableFromAny(Type[] fromTypes, Type to) {
    779     for (Type from : fromTypes) {
    780       if (isAssignable(from, to)) {
    781         return true;
    782       }
    783     }
    784     return false;
    785   }
    786 
    787   private static boolean isAssignableToClass(Type from, Class<?> to) {
    788     return to.isAssignableFrom(getRawType(from));
    789   }
    790 
    791   private static boolean isAssignableToWildcardType(
    792       Type from, WildcardType to) {
    793     // if "to" is <? extends Foo>, "from" can be:
    794     // Foo, SubFoo, <? extends Foo>, <? extends SubFoo>, <T extends Foo> or
    795     // <T extends SubFoo>.
    796     // if "to" is <? super Foo>, "from" can be:
    797     // Foo, SuperFoo, <? super Foo> or <? super SuperFoo>.
    798     return isAssignable(from, supertypeBound(to)) && isAssignableBySubtypeBound(from, to);
    799   }
    800 
    801   private static boolean isAssignableBySubtypeBound(Type from, WildcardType to) {
    802     Type toSubtypeBound = subtypeBound(to);
    803     if (toSubtypeBound == null) {
    804       return true;
    805     }
    806     Type fromSubtypeBound = subtypeBound(from);
    807     if (fromSubtypeBound == null) {
    808       return false;
    809     }
    810     return isAssignable(toSubtypeBound, fromSubtypeBound);
    811   }
    812 
    813   private static boolean isAssignableToParameterizedType(Type from, ParameterizedType to) {
    814     Class<?> matchedClass = getRawType(to);
    815     if (!matchedClass.isAssignableFrom(getRawType(from))) {
    816       return false;
    817     }
    818     Type[] typeParams = matchedClass.getTypeParameters();
    819     Type[] toTypeArgs = to.getActualTypeArguments();
    820     TypeToken<?> fromTypeToken = of(from);
    821     for (int i = 0; i < typeParams.length; i++) {
    822       // If "to" is "List<? extends CharSequence>"
    823       // and "from" is StringArrayList,
    824       // First step is to figure out StringArrayList "is-a" List<E> and <E> is
    825       // String.
    826       // typeParams[0] is E and fromTypeToken.get(typeParams[0]) will resolve to
    827       // String.
    828       // String is then matched against <? extends CharSequence>.
    829       Type fromTypeArg = fromTypeToken.resolveType(typeParams[i]).runtimeType;
    830       if (!matchTypeArgument(fromTypeArg, toTypeArgs[i])) {
    831         return false;
    832       }
    833     }
    834     return true;
    835   }
    836 
    837   private static boolean isAssignableToGenericArrayType(Type from, GenericArrayType to) {
    838     if (from instanceof Class) {
    839       Class<?> fromClass = (Class<?>) from;
    840       if (!fromClass.isArray()) {
    841         return false;
    842       }
    843       return isAssignable(fromClass.getComponentType(), to.getGenericComponentType());
    844     } else if (from instanceof GenericArrayType) {
    845       GenericArrayType fromArrayType = (GenericArrayType) from;
    846       return isAssignable(fromArrayType.getGenericComponentType(), to.getGenericComponentType());
    847     } else {
    848       return false;
    849     }
    850   }
    851 
    852   private static boolean isAssignableFromGenericArrayType(GenericArrayType from, Type to) {
    853     if (to instanceof Class) {
    854       Class<?> toClass = (Class<?>) to;
    855       if (!toClass.isArray()) {
    856         return toClass == Object.class; // any T[] is assignable to Object
    857       }
    858       return isAssignable(from.getGenericComponentType(), toClass.getComponentType());
    859     } else if (to instanceof GenericArrayType) {
    860       GenericArrayType toArrayType = (GenericArrayType) to;
    861       return isAssignable(from.getGenericComponentType(), toArrayType.getGenericComponentType());
    862     } else {
    863       return false;
    864     }
    865   }
    866 
    867   private static boolean matchTypeArgument(Type from, Type to) {
    868     if (from.equals(to)) {
    869       return true;
    870     }
    871     if (to instanceof WildcardType) {
    872       return isAssignableToWildcardType(from, (WildcardType) to);
    873     }
    874     return false;
    875   }
    876 
    877   private static Type supertypeBound(Type type) {
    878     if (type instanceof WildcardType) {
    879       return supertypeBound((WildcardType) type);
    880     }
    881     return type;
    882   }
    883 
    884   private static Type supertypeBound(WildcardType type) {
    885     Type[] upperBounds = type.getUpperBounds();
    886     if (upperBounds.length == 1) {
    887       return supertypeBound(upperBounds[0]);
    888     } else if (upperBounds.length == 0) {
    889       return Object.class;
    890     } else {
    891       throw new AssertionError(
    892           "There should be at most one upper bound for wildcard type: " + type);
    893     }
    894   }
    895 
    896   @Nullable private static Type subtypeBound(Type type) {
    897     if (type instanceof WildcardType) {
    898       return subtypeBound((WildcardType) type);
    899     } else {
    900       return type;
    901     }
    902   }
    903 
    904   @Nullable private static Type subtypeBound(WildcardType type) {
    905     Type[] lowerBounds = type.getLowerBounds();
    906     if (lowerBounds.length == 1) {
    907       return subtypeBound(lowerBounds[0]);
    908     } else if (lowerBounds.length == 0) {
    909       return null;
    910     } else {
    911       throw new AssertionError(
    912           "Wildcard should have at most one lower bound: " + type);
    913     }
    914   }
    915 
    916   @VisibleForTesting static Class<?> getRawType(Type type) {
    917     // For wildcard or type variable, the first bound determines the runtime type.
    918     return getRawTypes(type).iterator().next();
    919   }
    920 
    921   @VisibleForTesting static ImmutableSet<Class<?>> getRawTypes(Type type) {
    922     checkNotNull(type);
    923     final ImmutableSet.Builder<Class<?>> builder = ImmutableSet.builder();
    924     new TypeVisitor() {
    925       @Override void visitTypeVariable(TypeVariable<?> t) {
    926         visit(t.getBounds());
    927       }
    928       @Override void visitWildcardType(WildcardType t) {
    929         visit(t.getUpperBounds());
    930       }
    931       @Override void visitParameterizedType(ParameterizedType t) {
    932         builder.add((Class<?>) t.getRawType());
    933       }
    934       @Override void visitClass(Class<?> t) {
    935         builder.add(t);
    936       }
    937       @Override void visitGenericArrayType(GenericArrayType t) {
    938         builder.add(Types.getArrayClass(getRawType(t.getGenericComponentType())));
    939       }
    940 
    941     }.visit(type);
    942     return builder.build();
    943   }
    944 
    945   /**
    946    * Returns the type token representing the generic type declaration of {@code cls}. For example:
    947    * {@code TypeToken.getGenericType(Iterable.class)} returns {@code Iterable<T>}.
    948    *
    949    * <p>If {@code cls} isn't parameterized and isn't a generic array, the type token of the class is
    950    * returned.
    951    */
    952   @VisibleForTesting static <T> TypeToken<? extends T> toGenericType(Class<T> cls) {
    953     if (cls.isArray()) {
    954       Type arrayOfGenericType = Types.newArrayType(
    955           // If we are passed with int[].class, don't turn it to GenericArrayType
    956           toGenericType(cls.getComponentType()).runtimeType);
    957       @SuppressWarnings("unchecked") // array is covariant
    958       TypeToken<? extends T> result = (TypeToken<? extends T>) of(arrayOfGenericType);
    959       return result;
    960     }
    961     TypeVariable<Class<T>>[] typeParams = cls.getTypeParameters();
    962     if (typeParams.length > 0) {
    963       @SuppressWarnings("unchecked") // Like, it's Iterable<T> for Iterable.class
    964       TypeToken<? extends T> type = (TypeToken<? extends T>)
    965           of(Types.newParameterizedType(cls, typeParams));
    966       return type;
    967     } else {
    968       return of(cls);
    969     }
    970   }
    971 
    972   private TypeToken<? super T> getSupertypeFromUpperBounds(
    973       Class<? super T> supertype, Type[] upperBounds) {
    974     for (Type upperBound : upperBounds) {
    975       @SuppressWarnings("unchecked") // T's upperbound is <? super T>.
    976       TypeToken<? super T> bound = (TypeToken<? super T>) of(upperBound);
    977       if (of(supertype).isAssignableFrom(bound)) {
    978         @SuppressWarnings({"rawtypes", "unchecked"}) // guarded by the isAssignableFrom check.
    979         TypeToken<? super T> result = bound.getSupertype((Class) supertype);
    980         return result;
    981       }
    982     }
    983     throw new IllegalArgumentException(supertype + " isn't a super type of " + this);
    984   }
    985 
    986   private TypeToken<? extends T> getSubtypeFromLowerBounds(Class<?> subclass, Type[] lowerBounds) {
    987     for (Type lowerBound : lowerBounds) {
    988       @SuppressWarnings("unchecked") // T's lower bound is <? extends T>
    989       TypeToken<? extends T> bound = (TypeToken<? extends T>) of(lowerBound);
    990       // Java supports only one lowerbound anyway.
    991       return bound.getSubtype(subclass);
    992     }
    993     throw new IllegalArgumentException(subclass + " isn't a subclass of " + this);
    994   }
    995 
    996   private TypeToken<? super T> getArraySupertype(Class<? super T> supertype) {
    997     // with component type, we have lost generic type information
    998     // Use raw type so that compiler allows us to call getSupertype()
    999     @SuppressWarnings("rawtypes")
   1000     TypeToken componentType = checkNotNull(getComponentType(),
   1001         "%s isn't a super type of %s", supertype, this);
   1002     // array is covariant. component type is super type, so is the array type.
   1003     @SuppressWarnings("unchecked") // going from raw type back to generics
   1004     TypeToken<?> componentSupertype = componentType.getSupertype(supertype.getComponentType());
   1005     @SuppressWarnings("unchecked") // component type is super type, so is array type.
   1006     TypeToken<? super T> result = (TypeToken<? super T>)
   1007         // If we are passed with int[].class, don't turn it to GenericArrayType
   1008         of(newArrayClassOrGenericArrayType(componentSupertype.runtimeType));
   1009     return result;
   1010   }
   1011 
   1012   private TypeToken<? extends T> getArraySubtype(Class<?> subclass) {
   1013     // array is covariant. component type is subtype, so is the array type.
   1014     TypeToken<?> componentSubtype = getComponentType()
   1015         .getSubtype(subclass.getComponentType());
   1016     @SuppressWarnings("unchecked") // component type is subtype, so is array type.
   1017     TypeToken<? extends T> result = (TypeToken<? extends T>)
   1018         // If we are passed with int[].class, don't turn it to GenericArrayType
   1019         of(newArrayClassOrGenericArrayType(componentSubtype.runtimeType));
   1020     return result;
   1021   }
   1022 
   1023   private Type resolveTypeArgsForSubclass(Class<?> subclass) {
   1024     if (runtimeType instanceof Class) {
   1025       // no resolution needed
   1026       return subclass;
   1027     }
   1028     // class Base<A, B> {}
   1029     // class Sub<X, Y> extends Base<X, Y> {}
   1030     // Base<String, Integer>.subtype(Sub.class):
   1031 
   1032     // Sub<X, Y>.getSupertype(Base.class) => Base<X, Y>
   1033     // => X=String, Y=Integer
   1034     // => Sub<X, Y>=Sub<String, Integer>
   1035     TypeToken<?> genericSubtype = toGenericType(subclass);
   1036     @SuppressWarnings({"rawtypes", "unchecked"}) // subclass isn't <? extends T>
   1037     Type supertypeWithArgsFromSubtype = genericSubtype
   1038         .getSupertype((Class) getRawType())
   1039         .runtimeType;
   1040     return new TypeResolver().where(supertypeWithArgsFromSubtype, runtimeType)
   1041         .resolveType(genericSubtype.runtimeType);
   1042   }
   1043 
   1044   /**
   1045    * Creates an array class if {@code componentType} is a class, or else, a
   1046    * {@link GenericArrayType}. This is what Java7 does for generic array type
   1047    * parameters.
   1048    */
   1049   private static Type newArrayClassOrGenericArrayType(Type componentType) {
   1050     return Types.JavaVersion.JAVA7.newArrayType(componentType);
   1051   }
   1052 
   1053   private static final class SimpleTypeToken<T> extends TypeToken<T> {
   1054 
   1055     SimpleTypeToken(Type type) {
   1056       super(type);
   1057     }
   1058 
   1059     private static final long serialVersionUID = 0;
   1060   }
   1061 
   1062   /**
   1063    * Collects parent types from a sub type.
   1064    *
   1065    * @param <K> The type "kind". Either a TypeToken, or Class.
   1066    */
   1067   private abstract static class TypeCollector<K> {
   1068 
   1069     static final TypeCollector<TypeToken<?>> FOR_GENERIC_TYPE =
   1070         new TypeCollector<TypeToken<?>>() {
   1071           @Override Class<?> getRawType(TypeToken<?> type) {
   1072             return type.getRawType();
   1073           }
   1074 
   1075           @Override Iterable<? extends TypeToken<?>> getInterfaces(TypeToken<?> type) {
   1076             return type.getGenericInterfaces();
   1077           }
   1078 
   1079           @Nullable
   1080           @Override TypeToken<?> getSuperclass(TypeToken<?> type) {
   1081             return type.getGenericSuperclass();
   1082           }
   1083         };
   1084 
   1085     static final TypeCollector<Class<?>> FOR_RAW_TYPE =
   1086         new TypeCollector<Class<?>>() {
   1087           @Override Class<?> getRawType(Class<?> type) {
   1088             return type;
   1089           }
   1090 
   1091           @Override Iterable<? extends Class<?>> getInterfaces(Class<?> type) {
   1092             return Arrays.asList(type.getInterfaces());
   1093           }
   1094 
   1095           @Nullable
   1096           @Override Class<?> getSuperclass(Class<?> type) {
   1097             return type.getSuperclass();
   1098           }
   1099         };
   1100 
   1101     /** For just classes, we don't have to traverse interfaces. */
   1102     final TypeCollector<K> classesOnly() {
   1103       return new ForwardingTypeCollector<K>(this) {
   1104         @Override Iterable<? extends K> getInterfaces(K type) {
   1105           return ImmutableSet.of();
   1106         }
   1107         @Override ImmutableList<K> collectTypes(Iterable<? extends K> types) {
   1108           ImmutableList.Builder<K> builder = ImmutableList.builder();
   1109           for (K type : types) {
   1110             if (!getRawType(type).isInterface()) {
   1111               builder.add(type);
   1112             }
   1113           }
   1114           return super.collectTypes(builder.build());
   1115         }
   1116       };
   1117     }
   1118 
   1119     final ImmutableList<K> collectTypes(K type) {
   1120       return collectTypes(ImmutableList.of(type));
   1121     }
   1122 
   1123     ImmutableList<K> collectTypes(Iterable<? extends K> types) {
   1124       // type -> order number. 1 for Object, 2 for anything directly below, so on so forth.
   1125       Map<K, Integer> map = Maps.newHashMap();
   1126       for (K type : types) {
   1127         collectTypes(type, map);
   1128       }
   1129       return sortKeysByValue(map, Ordering.natural().reverse());
   1130     }
   1131 
   1132     /** Collects all types to map, and returns the total depth from T up to Object. */
   1133     private int collectTypes(K type, Map<? super K, Integer> map) {
   1134       Integer existing = map.get(this);
   1135       if (existing != null) {
   1136         // short circuit: if set contains type it already contains its supertypes
   1137         return existing;
   1138       }
   1139       int aboveMe = getRawType(type).isInterface()
   1140           ? 1 // interfaces should be listed before Object
   1141           : 0;
   1142       for (K interfaceType : getInterfaces(type)) {
   1143         aboveMe = Math.max(aboveMe, collectTypes(interfaceType, map));
   1144       }
   1145       K superclass = getSuperclass(type);
   1146       if (superclass != null) {
   1147         aboveMe = Math.max(aboveMe, collectTypes(superclass, map));
   1148       }
   1149       /*
   1150        * TODO(benyu): should we include Object for interface?
   1151        * Also, CharSequence[] and Object[] for String[]?
   1152        *
   1153        */
   1154       map.put(type, aboveMe + 1);
   1155       return aboveMe + 1;
   1156     }
   1157 
   1158     private static <K, V> ImmutableList<K> sortKeysByValue(
   1159         final Map<K, V> map, final Comparator<? super V> valueComparator) {
   1160       Ordering<K> keyOrdering = new Ordering<K>() {
   1161         @Override public int compare(K left, K right) {
   1162           return valueComparator.compare(map.get(left), map.get(right));
   1163         }
   1164       };
   1165       return keyOrdering.immutableSortedCopy(map.keySet());
   1166     }
   1167 
   1168     abstract Class<?> getRawType(K type);
   1169     abstract Iterable<? extends K> getInterfaces(K type);
   1170     @Nullable abstract K getSuperclass(K type);
   1171 
   1172     private static class ForwardingTypeCollector<K> extends TypeCollector<K> {
   1173 
   1174       private final TypeCollector<K> delegate;
   1175 
   1176       ForwardingTypeCollector(TypeCollector<K> delegate) {
   1177         this.delegate = delegate;
   1178       }
   1179 
   1180       @Override Class<?> getRawType(K type) {
   1181         return delegate.getRawType(type);
   1182       }
   1183 
   1184       @Override Iterable<? extends K> getInterfaces(K type) {
   1185         return delegate.getInterfaces(type);
   1186       }
   1187 
   1188       @Override K getSuperclass(K type) {
   1189         return delegate.getSuperclass(type);
   1190       }
   1191     }
   1192   }
   1193 }
   1194