View Javadoc
1   /*
2    * Copyright (C) 2012 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.testing;
18  
19  import static com.google.common.base.Preconditions.checkNotNull;
20  import static com.google.common.base.Throwables.throwIfUnchecked;
21  
22  import com.google.common.annotations.GwtIncompatible;
23  import com.google.common.base.CharMatcher;
24  import com.google.common.base.Charsets;
25  import com.google.common.base.Equivalence;
26  import com.google.common.base.Joiner;
27  import com.google.common.base.Splitter;
28  import com.google.common.base.Ticker;
29  import com.google.common.collect.ArrayListMultimap;
30  import com.google.common.collect.BiMap;
31  import com.google.common.collect.HashBasedTable;
32  import com.google.common.collect.HashBiMap;
33  import com.google.common.collect.HashMultimap;
34  import com.google.common.collect.HashMultiset;
35  import com.google.common.collect.ImmutableBiMap;
36  import com.google.common.collect.ImmutableCollection;
37  import com.google.common.collect.ImmutableList;
38  import com.google.common.collect.ImmutableListMultimap;
39  import com.google.common.collect.ImmutableMap;
40  import com.google.common.collect.ImmutableMultimap;
41  import com.google.common.collect.ImmutableMultiset;
42  import com.google.common.collect.ImmutableSet;
43  import com.google.common.collect.ImmutableSetMultimap;
44  import com.google.common.collect.ImmutableSortedMap;
45  import com.google.common.collect.ImmutableSortedMultiset;
46  import com.google.common.collect.ImmutableSortedSet;
47  import com.google.common.collect.ImmutableTable;
48  import com.google.common.collect.Iterables;
49  import com.google.common.collect.LinkedHashMultimap;
50  import com.google.common.collect.LinkedHashMultiset;
51  import com.google.common.collect.ListMultimap;
52  import com.google.common.collect.Lists;
53  import com.google.common.collect.Maps;
54  import com.google.common.collect.Multimap;
55  import com.google.common.collect.Multiset;
56  import com.google.common.collect.Ordering;
57  import com.google.common.collect.Range;
58  import com.google.common.collect.RowSortedTable;
59  import com.google.common.collect.SetMultimap;
60  import com.google.common.collect.Sets;
61  import com.google.common.collect.SortedMultiset;
62  import com.google.common.collect.Table;
63  import com.google.common.collect.TreeBasedTable;
64  import com.google.common.collect.TreeMultiset;
65  import com.google.common.primitives.Primitives;
66  import com.google.common.primitives.UnsignedInteger;
67  import com.google.common.primitives.UnsignedLong;
68  import com.google.common.reflect.AbstractInvocationHandler;
69  import com.google.common.reflect.Invokable;
70  import com.google.common.reflect.Parameter;
71  import com.google.common.reflect.Reflection;
72  import com.google.common.reflect.TypeToken;
73  import java.io.ByteArrayInputStream;
74  import java.io.File;
75  import java.io.InputStream;
76  import java.io.Reader;
77  import java.io.StringReader;
78  import java.lang.annotation.ElementType;
79  import java.lang.annotation.Retention;
80  import java.lang.annotation.RetentionPolicy;
81  import java.lang.annotation.Target;
82  import java.lang.reflect.Array;
83  import java.lang.reflect.InvocationTargetException;
84  import java.lang.reflect.Method;
85  import java.lang.reflect.Type;
86  import java.lang.reflect.TypeVariable;
87  import java.math.BigDecimal;
88  import java.math.BigInteger;
89  import java.nio.Buffer;
90  import java.nio.ByteBuffer;
91  import java.nio.CharBuffer;
92  import java.nio.DoubleBuffer;
93  import java.nio.FloatBuffer;
94  import java.nio.IntBuffer;
95  import java.nio.LongBuffer;
96  import java.nio.ShortBuffer;
97  import java.nio.charset.Charset;
98  import java.util.ArrayList;
99  import java.util.Arrays;
100 import java.util.Collection;
101 import java.util.Comparator;
102 import java.util.Currency;
103 import java.util.HashMap;
104 import java.util.HashSet;
105 import java.util.LinkedHashMap;
106 import java.util.LinkedHashSet;
107 import java.util.LinkedList;
108 import java.util.List;
109 import java.util.Locale;
110 import java.util.Map;
111 import java.util.NavigableMap;
112 import java.util.NavigableSet;
113 import java.util.Optional;
114 import java.util.OptionalDouble;
115 import java.util.OptionalInt;
116 import java.util.OptionalLong;
117 import java.util.Set;
118 import java.util.SortedMap;
119 import java.util.SortedSet;
120 import java.util.TreeMap;
121 import java.util.TreeSet;
122 import java.util.concurrent.ConcurrentMap;
123 import java.util.concurrent.atomic.AtomicInteger;
124 import java.util.regex.Pattern;
125 import javax.annotation.Nullable;
126 
127 /**
128  * Generates fresh instances of types that are different from each other (if possible).
129  *
130  * @author Ben Yu
131  */
132 @GwtIncompatible
133 class FreshValueGenerator {
134 
135   private static final ImmutableMap<Class<?>, Method> GENERATORS;
136   static {
137     ImmutableMap.Builder<Class<?>, Method> builder =
138         ImmutableMap.builder();
139     for (Method method : FreshValueGenerator.class.getDeclaredMethods()) {
140       if (method.isAnnotationPresent(Generates.class)) {
141         builder.put(method.getReturnType(), method);
142       }
143     }
144     GENERATORS = builder.build();
145   }
146 
147   private static final ImmutableMap<Class<?>, Method> EMPTY_GENERATORS;
148   static {
149     ImmutableMap.Builder<Class<?>, Method> builder =
150         ImmutableMap.builder();
151     for (Method method : FreshValueGenerator.class.getDeclaredMethods()) {
152       if (method.isAnnotationPresent(Empty.class)) {
153         builder.put(method.getReturnType(), method);
154       }
155     }
156     EMPTY_GENERATORS = builder.build();
157   }
158 
159   private final AtomicInteger freshness = new AtomicInteger(1);
160   private final ListMultimap<Class<?>, Object> sampleInstances = ArrayListMultimap.create();
161 
162   /**
163    * The freshness level at which the {@link Empty @Empty} annotated method was invoked to generate
164    * instance.
165    */
166   private final Map<Type, Integer> emptyInstanceGenerated = new HashMap<>();
167 
168   final <T> void addSampleInstances(Class<T> type, Iterable<? extends T> instances) {
169     sampleInstances.putAll(checkNotNull(type), checkNotNull(instances));
170   }
171 
172   /**
173    * Returns a fresh instance for {@code type} if possible. The returned instance could be:
174    * <ul>
175    * <li>exactly of the given type, including generic type parameters, such as
176    *     {@code ImmutableList<String>};
177    * <li>of the raw type;
178    * <li>null if no value can be generated.
179    * </ul>
180    */
181   @Nullable final Object generateFresh(TypeToken<?> type) {
182     Object generated = generate(type);
183     if (generated != null) {
184       freshness.incrementAndGet();
185     }
186     return generated;
187   }
188 
189   @Nullable final <T> T generateFresh(Class<T> type) {
190     return Primitives.wrap(type).cast(generateFresh(TypeToken.of(type)));
191   }
192 
193   final <T> T newFreshProxy(final Class<T> interfaceType) {
194     T proxy = newProxy(interfaceType);
195     freshness.incrementAndGet();
196     return proxy;
197   }
198 
199   /**
200    * Generates an instance for {@code type} using the current {@link #freshness}.
201    * The generated instance may or may not be unique across different calls.
202    */
203   private Object generate(TypeToken<?> type) {
204     Class<?> rawType = type.getRawType();
205     List<Object> samples = sampleInstances.get(rawType);
206     Object sample = pickInstance(samples, null);
207     if (sample != null) {
208       return sample;
209     }
210     if (rawType.isEnum()) {
211       return pickInstance(rawType.getEnumConstants(), null);
212     }
213     if (type.isArray()) {
214       TypeToken<?> componentType = type.getComponentType();
215       Object array = Array.newInstance(componentType.getRawType(), 1);
216       Array.set(array, 0, generate(componentType));
217       return array;
218     }
219     Method emptyGenerate = EMPTY_GENERATORS.get(rawType);
220     if (emptyGenerate != null) {
221       if (emptyInstanceGenerated.containsKey(type.getType())) {
222         // empty instance already generated
223         if (emptyInstanceGenerated.get(type.getType()).intValue() == freshness.get()) {
224           // same freshness, generate again.
225           return invokeGeneratorMethod(emptyGenerate);
226         } else {
227           // Cannot use empty generator. Proceed with other generators.
228         }
229       } else {
230         // never generated empty instance for this type before.
231         Object emptyInstance = invokeGeneratorMethod(emptyGenerate);
232         emptyInstanceGenerated.put(type.getType(), freshness.get());
233         return emptyInstance;
234       }
235     }
236     Method generate = GENERATORS.get(rawType);
237     if (generate != null) {
238       ImmutableList<Parameter> params = Invokable.from(generate).getParameters();
239       List<Object> args = Lists.newArrayListWithCapacity(params.size());
240       TypeVariable<?>[] typeVars = rawType.getTypeParameters();
241       for (int i = 0; i < params.size(); i++) {
242         TypeToken<?> paramType = type.resolveType(typeVars[i]);
243         // We require all @Generates methods to either be parameter-less or accept non-null
244         // values for their generic parameter types.
245         Object argValue = generate(paramType);
246         if (argValue == null) {
247           // When a parameter of a @Generates method cannot be created,
248           // The type most likely is a collection.
249           // Our distinct proxy doesn't work for collections.
250           // So just refuse to generate.
251           return null;
252         }
253         args.add(argValue);
254       }
255       return invokeGeneratorMethod(generate, args.toArray());
256     }
257     return defaultGenerate(rawType);
258   }
259 
260   private <T> T defaultGenerate(Class<T> rawType) {
261     if (rawType.isInterface()) {
262       // always create a new proxy
263       return newProxy(rawType);
264     }
265     return ArbitraryInstances.get(rawType);
266   }
267 
268   private <T> T newProxy(final Class<T> interfaceType) {
269     return Reflection.newProxy(interfaceType, new FreshInvocationHandler(interfaceType));
270   }
271 
272   private Object invokeGeneratorMethod(Method generator, Object... args) {
273     try {
274       return generator.invoke(this, args);
275     } catch (InvocationTargetException e) {
276       throwIfUnchecked(e.getCause());
277       throw new RuntimeException(e.getCause());
278     } catch (Exception e) {
279       throwIfUnchecked(e);
280       throw new RuntimeException(e);
281     }
282   }
283 
284   private final class FreshInvocationHandler extends AbstractInvocationHandler {
285     private final int identity = generateInt();
286     private final Class<?> interfaceType;
287 
288     FreshInvocationHandler(Class<?> interfaceType) {
289       this.interfaceType = interfaceType;
290     }
291 
292     @Override protected Object handleInvocation(Object proxy, Method method, Object[] args) {
293       return interfaceMethodCalled(interfaceType, method);
294     }
295 
296     @Override public int hashCode() {
297       return identity;
298     }
299 
300     @Override public boolean equals(@Nullable Object obj) {
301       if (obj instanceof FreshInvocationHandler) {
302         FreshInvocationHandler that = (FreshInvocationHandler) obj;
303         return identity == that.identity;
304       }
305       return false;
306     }
307 
308     @Override public String toString() {
309       return paramString(interfaceType, identity);
310     }
311   }
312 
313   /** Subclasses can override to provide different return value for proxied interface methods. */
314   Object interfaceMethodCalled(Class<?> interfaceType, Method method) {
315     throw new UnsupportedOperationException();
316   }
317 
318   private <T> T pickInstance(T[] instances, T defaultValue) {
319     return pickInstance(Arrays.asList(instances), defaultValue);
320   }
321 
322   private <T> T pickInstance(Collection<T> instances, T defaultValue) {
323     if (instances.isEmpty()) {
324       return defaultValue;
325     }
326     // generateInt() is 1-based.
327     return Iterables.get(instances, (generateInt() - 1) % instances.size());
328   }
329 
330   private static String paramString(Class<?> type, int i) {
331     return type.getSimpleName() + '@' + i;
332   }
333 
334   /**
335    * Annotates a method to be the instance generator of a certain type. The return type is the
336    * generated type. The method parameters correspond to the generated type's type parameters.
337    * For example, if the annotated method returns {@code Map<K, V>}, the method signature should be:
338    * {@code Map<K, V> generateMap(K key, V value)}.
339    */
340   @Target(ElementType.METHOD)
341   @Retention(RetentionPolicy.RUNTIME)
342   private @interface Generates {}
343 
344   /**
345    * Annotates a method to generate the "empty" instance of a collection. This method should accept
346    * no parameter. The value it generates should be unequal to the values generated by methods
347    * annotated with {@link Generates}.
348    */
349   @Target(ElementType.METHOD)
350   @Retention(RetentionPolicy.RUNTIME)
351   private @interface Empty {}
352 
353   @Generates private Class<?> generateClass() {
354     return pickInstance(
355         ImmutableList.of(
356             int.class, long.class, void.class,
357             Object.class, Object[].class, Iterable.class),
358         Object.class);
359   }
360 
361   @Generates private Object generateObject() {
362     return generateString();
363   }
364 
365   @Generates private Number generateNumber() {
366     return generateInt();
367   }
368 
369   @Generates private int generateInt() {
370     return freshness.get();
371   }
372 
373   @Generates private Integer generateInteger() {
374     return new Integer(generateInt());
375   }
376 
377   @Generates private long generateLong() {
378     return generateInt();
379   }
380 
381   @Generates private Long generateLongObject() {
382     return new Long(generateLong());
383   }
384 
385   @Generates private float generateFloat() {
386     return generateInt();
387   }
388 
389   @Generates private Float generateFloatObject() {
390     return new Float(generateFloat());
391   }
392 
393   @Generates private double generateDouble() {
394     return generateInt();
395   }
396 
397   @Generates private Double generateDoubleObject() {
398     return new Double(generateDouble());
399   }
400 
401   @Generates private short generateShort() {
402     return (short) generateInt();
403   }
404 
405   @Generates private Short generateShortObject() {
406     return new Short(generateShort());
407   }
408 
409   @Generates private byte generateByte() {
410     return (byte) generateInt();
411   }
412 
413   @Generates private Byte generateByteObject() {
414     return new Byte(generateByte());
415   }
416 
417   @Generates private char generateChar() {
418     return generateString().charAt(0);
419   }
420 
421   @Generates private Character generateCharacter() {
422     return new Character(generateChar());
423   }
424 
425   @Generates private boolean generateBoolean() {
426     return generateInt() % 2 == 0;
427   }
428 
429   @Generates private Boolean generateBooleanObject() {
430     return new Boolean(generateBoolean());
431   }
432 
433   @Generates private UnsignedInteger generateUnsignedInteger() {
434     return UnsignedInteger.fromIntBits(generateInt());
435   }
436 
437   @Generates private UnsignedLong generateUnsignedLong() {
438     return UnsignedLong.fromLongBits(generateLong());
439   }
440 
441   @Generates private BigInteger generateBigInteger() {
442     return BigInteger.valueOf(generateInt());
443   }
444 
445   @Generates private BigDecimal generateBigDecimal() {
446     return BigDecimal.valueOf(generateInt());
447   }
448 
449   @Generates private CharSequence generateCharSequence() {
450     return generateString();
451   }
452 
453   @Generates private String generateString() {
454     return Integer.toString(generateInt());
455   }
456 
457   @Generates private Comparable<?> generateComparable() {
458     return generateString();
459   }
460 
461   @Generates private Pattern generatePattern() {
462     return Pattern.compile(generateString());
463   }
464 
465   @Generates private Charset generateCharset() {
466     return pickInstance(Charset.availableCharsets().values(), Charsets.UTF_8);
467   }
468 
469   @Generates private Locale generateLocale() {
470     return pickInstance(Locale.getAvailableLocales(), Locale.US);
471   }
472 
473   @Generates private Currency generateCurrency() {
474     try {
475       Method method = Currency.class.getMethod("getAvailableCurrencies");
476       @SuppressWarnings("unchecked") // getAvailableCurrencies() returns Set<Currency>.
477       Set<Currency> currencies = (Set<Currency>) method.invoke(null);
478       return pickInstance(currencies, Currency.getInstance(Locale.US));
479     } catch (NoSuchMethodException | InvocationTargetException notJava7) {
480       return preJava7FreshCurrency();
481     } catch (IllegalAccessException impossible) {
482       throw new AssertionError(impossible);
483     }
484   }
485 
486   private Currency preJava7FreshCurrency() {
487     for (Set<Locale> uselessLocales = Sets.newHashSet(); ; ) {
488       Locale locale = generateLocale();
489       if (uselessLocales.contains(locale)) { // exhausted all locales
490         return Currency.getInstance(Locale.US);
491       }
492       try {
493         return Currency.getInstance(locale);
494       } catch (IllegalArgumentException e) {
495         uselessLocales.add(locale);
496       }
497     }
498   }
499 
500   @Empty
501   private <T> Optional<T> generateJavaOptional() {
502     return Optional.empty();
503   }
504 
505   @Generates
506   private <T> Optional<T> generateJavaOptional(T value) {
507     return Optional.of(value);
508   }
509 
510   @Generates
511   private OptionalInt generateOptionalInt() {
512     return OptionalInt.of(generateInt());
513   }
514 
515   @Generates
516   private OptionalLong generateOptionalLong() {
517     return OptionalLong.of(generateLong());
518   }
519 
520   @Generates
521   private OptionalDouble generateOptionalDouble() {
522     return OptionalDouble.of(generateDouble());
523   }
524 
525   // common.base
526   @Empty
527   private <T> com.google.common.base.Optional<T> generateGoogleOptional() {
528     return com.google.common.base.Optional.absent();
529   }
530 
531   @Generates
532   private <T> com.google.common.base.Optional<T> generateGoogleOptional(T value) {
533     return com.google.common.base.Optional.of(value);
534   }
535 
536   @Generates private Joiner generateJoiner() {
537     return Joiner.on(generateString());
538   }
539 
540   @Generates private Splitter generateSplitter() {
541     return Splitter.on(generateString());
542   }
543 
544   @Generates private <T> Equivalence<T> generateEquivalence() {
545     return new Equivalence<T>() {
546       @Override protected boolean doEquivalent(T a, T b) {
547         return false;
548       }
549       @Override protected int doHash(T t) {
550         return 0;
551       }
552       final String string = paramString(Equivalence.class, generateInt());
553       @Override public String toString() {
554         return string;
555       }
556     };
557   }
558 
559   @Generates private CharMatcher generateCharMatcher() {
560     return new CharMatcher() {
561       @Override public boolean matches(char c) {
562         return false;
563       }
564       final String string = paramString(CharMatcher.class, generateInt());
565       @Override public String toString() {
566         return string;
567       }
568     };
569   }
570 
571   @Generates private Ticker generateTicker() {
572     return new Ticker() {
573       @Override public long read() {
574         return 0;
575       }
576       final String string = paramString(Ticker.class, generateInt());
577       @Override public String toString() {
578         return string;
579       }
580     };
581   }
582 
583   // collect
584   @Generates private <T> Comparator<T> generateComparator() {
585     return generateOrdering();
586   }
587 
588   @Generates private <T> Ordering<T> generateOrdering() {
589     return new Ordering<T>() {
590       @Override public int compare(T left, T right) {
591         return 0;
592       }
593       final String string = paramString(Ordering.class, generateInt());
594       @Override public String toString() {
595         return string;
596       }
597     };
598   }
599 
600   @Empty private static <C extends Comparable<?>> Range<C> generateRange() {
601     return Range.all();
602   }
603 
604   @Generates private static <C extends Comparable<?>> Range<C> generateRange(C freshElement) {
605     return Range.singleton(freshElement);
606   }
607 
608   @Generates private static <E> Iterable<E> generateIterable(E freshElement) {
609     return generateList(freshElement);
610   }
611 
612   @Generates private static <E> Collection<E> generateCollection(E freshElement) {
613     return generateList(freshElement);
614   }
615 
616   @Generates private static <E> List<E> generateList(E freshElement) {
617     return generateArrayList(freshElement);
618   }
619 
620   @Generates private static <E> ArrayList<E> generateArrayList(E freshElement) {
621     ArrayList<E> list = Lists.newArrayList();
622     list.add(freshElement);
623     return list;
624   }
625 
626   @Generates private static <E> LinkedList<E> generateLinkedList(E freshElement) {
627     LinkedList<E> list = Lists.newLinkedList();
628     list.add(freshElement);
629     return list;
630   }
631 
632   @Generates private static <E> ImmutableList<E> generateImmutableList(E freshElement) {
633     return ImmutableList.of(freshElement);
634   }
635 
636   @Generates private static <E> ImmutableCollection<E> generateImmutableCollection(E freshElement) {
637     return generateImmutableList(freshElement);
638   }
639 
640   @Generates private static <E> Set<E> generateSet(E freshElement) {
641     return generateHashSet(freshElement);
642   }
643 
644   @Generates private static <E> HashSet<E> generateHashSet(E freshElement) {
645     return generateLinkedHashSet(freshElement);
646   }
647 
648   @Generates private static <E> LinkedHashSet<E> generateLinkedHashSet(E freshElement) {
649     LinkedHashSet<E> set = Sets.newLinkedHashSet();
650     set.add(freshElement);
651     return set;
652   }
653 
654   @Generates private static <E> ImmutableSet<E> generateImmutableSet(E freshElement) {
655     return ImmutableSet.of(freshElement);
656   }
657 
658   @Generates private static <E extends Comparable<? super E>> SortedSet<E>
659       generateSortedSet(E freshElement) {
660     return generateNavigableSet(freshElement);
661   }
662 
663   @Generates private static <E extends Comparable<? super E>> NavigableSet<E>
664       generateNavigableSet(E freshElement) {
665     return generateTreeSet(freshElement);
666   }
667 
668   @Generates private static <E extends Comparable<? super E>> TreeSet<E> generateTreeSet(
669       E freshElement) {
670     TreeSet<E> set = Sets.newTreeSet();
671     set.add(freshElement);
672     return set;
673   }
674 
675   @Generates private static <E extends Comparable<? super E>> ImmutableSortedSet<E>
676       generateImmutableSortedSet(E freshElement) {
677     return ImmutableSortedSet.of(freshElement);
678   }
679 
680   @Generates private static <E> Multiset<E> generateMultiset(E freshElement) {
681     return generateHashMultiset(freshElement);
682   }
683 
684   @Generates private static <E> HashMultiset<E> generateHashMultiset(E freshElement) {
685     HashMultiset<E> multiset = HashMultiset.create();
686     multiset.add(freshElement);
687     return multiset;
688   }
689 
690   @Generates private static <E> LinkedHashMultiset<E> generateLinkedHashMultiset(E freshElement) {
691     LinkedHashMultiset<E> multiset = LinkedHashMultiset.create();
692     multiset.add(freshElement);
693     return multiset;
694   }
695 
696   @Generates private static <E> ImmutableMultiset<E> generateImmutableMultiset(E freshElement) {
697     return ImmutableMultiset.of(freshElement);
698   }
699 
700   @Generates private static <E extends Comparable<E>> SortedMultiset<E> generateSortedMultiset(
701       E freshElement) {
702     return generateTreeMultiset(freshElement);
703   }
704 
705   @Generates private static <E extends Comparable<E>> TreeMultiset<E> generateTreeMultiset(
706       E freshElement) {
707     TreeMultiset<E> multiset = TreeMultiset.create();
708     multiset.add(freshElement);
709     return multiset;
710   }
711 
712   @Generates private static <E extends Comparable<E>> ImmutableSortedMultiset<E>
713       generateImmutableSortedMultiset(E freshElement) {
714     return ImmutableSortedMultiset.of(freshElement);
715   }
716 
717   @Generates private static <K, V> Map<K, V> generateMap(K key, V value) {
718     return generateHashdMap(key, value);
719   }
720 
721   @Generates private static <K, V> HashMap<K, V> generateHashdMap(K key, V value) {
722     return generateLinkedHashMap(key, value);
723   }
724 
725   @Generates private static <K, V> LinkedHashMap<K, V> generateLinkedHashMap(K key, V value) {
726     LinkedHashMap<K, V> map = Maps.newLinkedHashMap();
727     map.put(key, value);
728     return map;
729   }
730 
731   @Generates private static <K, V> ImmutableMap<K, V> generateImmutableMap(K key, V value) {
732     return ImmutableMap.of(key, value);
733   }
734 
735   @Empty private static <K, V> ConcurrentMap<K, V> generateConcurrentMap() {
736     return Maps.newConcurrentMap();
737   }
738 
739   @Generates private static <K, V> ConcurrentMap<K, V> generateConcurrentMap(K key, V value) {
740     ConcurrentMap<K, V> map = Maps.newConcurrentMap();
741     map.put(key, value);
742     return map;
743   }
744 
745   @Generates private static <K extends Comparable<? super K>, V> SortedMap<K, V>
746       generateSortedMap(K key, V value) {
747     return generateNavigableMap(key, value);
748   }
749 
750   @Generates private static <K extends Comparable<? super K>, V> NavigableMap<K, V>
751       generateNavigableMap(K key, V value) {
752     return generateTreeMap(key, value);
753   }
754 
755   @Generates private static <K extends Comparable<? super K>, V> TreeMap<K, V> generateTreeMap(
756       K key, V value) {
757     TreeMap<K, V> map = Maps.newTreeMap();
758     map.put(key, value);
759     return map;
760   }
761 
762   @Generates private static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
763       generateImmutableSortedMap(K key, V value) {
764     return ImmutableSortedMap.of(key, value);
765   }
766 
767   @Generates private static <K, V> Multimap<K, V> generateMultimap(K key, V value) {
768     return generateListMultimap(key, value);
769   }
770 
771   @Generates private static <K, V> ImmutableMultimap<K, V> generateImmutableMultimap(
772       K key, V value) {
773     return ImmutableMultimap.of(key, value);
774   }
775 
776   @Generates private static <K, V> ListMultimap<K, V> generateListMultimap(K key, V value) {
777     return generateArrayListMultimap(key, value);
778   }
779 
780   @Generates private static <K, V> ArrayListMultimap<K, V> generateArrayListMultimap(
781       K key, V value) {
782     ArrayListMultimap<K, V> multimap = ArrayListMultimap.create();
783     multimap.put(key, value);
784     return multimap;
785   }
786 
787   @Generates private static <K, V> ImmutableListMultimap<K, V> generateImmutableListMultimap(
788       K key, V value) {
789     return ImmutableListMultimap.of(key, value);
790   }
791 
792   @Generates private static <K, V> SetMultimap<K, V> generateSetMultimap(K key, V value) {
793     return generateLinkedHashMultimap(key, value);
794   }
795 
796   @Generates private static <K, V> HashMultimap<K, V> generateHashMultimap(K key, V value) {
797     HashMultimap<K, V> multimap = HashMultimap.create();
798     multimap.put(key, value);
799     return multimap;
800   }
801 
802   @Generates private static <K, V> LinkedHashMultimap<K, V> generateLinkedHashMultimap(
803       K key, V value) {
804     LinkedHashMultimap<K, V> multimap = LinkedHashMultimap.create();
805     multimap.put(key, value);
806     return multimap;
807   }
808 
809   @Generates private static <K, V> ImmutableSetMultimap<K, V> generateImmutableSetMultimap(
810       K key, V value) {
811     return ImmutableSetMultimap.of(key, value);
812   }
813 
814   @Generates private static <K, V> BiMap<K, V> generateBimap(K key, V value) {
815     return generateHashBiMap(key, value);
816   }
817 
818   @Generates private static <K, V> HashBiMap<K, V> generateHashBiMap(K key, V value) {
819     HashBiMap<K, V> bimap = HashBiMap.create();
820     bimap.put(key, value);
821     return bimap;
822   }
823 
824   @Generates private static <K, V> ImmutableBiMap<K, V> generateImmutableBimap(
825       K key, V value) {
826     return ImmutableBiMap.of(key, value);
827   }
828 
829   @Generates private static <R, C, V> Table<R, C, V> generateTable(R row, C column, V value) {
830     return generateHashBasedTable(row, column, value);
831   }
832 
833   @Generates private static <R, C, V> HashBasedTable<R, C, V> generateHashBasedTable(
834       R row, C column, V value) {
835     HashBasedTable<R, C, V> table = HashBasedTable.create();
836     table.put(row, column, value);
837     return table;
838   }
839 
840   @SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such
841   @Generates private static <R extends Comparable, C extends Comparable, V> RowSortedTable<R, C, V>
842       generateRowSortedTable(R row, C column, V value) {
843     return generateTreeBasedTable(row, column, value);
844   }
845 
846   @SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such
847   @Generates private static <R extends Comparable, C extends Comparable, V> TreeBasedTable<R, C, V>
848       generateTreeBasedTable(R row, C column, V value) {
849     TreeBasedTable<R, C, V> table = TreeBasedTable.create();
850     table.put(row, column, value);
851     return table;
852   }
853 
854   @Generates private static <R, C, V> ImmutableTable<R, C, V> generateImmutableTable(
855       R row, C column, V value) {
856     return ImmutableTable.of(row, column, value);
857   }
858 
859   // common.reflect
860   @Generates private TypeToken<?> generateTypeToken() {
861     return TypeToken.of(generateClass());
862   }
863 
864   // io types
865   @Generates private File generateFile() {
866     return new File(generateString());
867   }
868 
869   @Generates private static ByteArrayInputStream generateByteArrayInputStream() {
870     return new ByteArrayInputStream(new byte[0]);
871   }
872 
873   @Generates private static InputStream generateInputStream() {
874     return generateByteArrayInputStream();
875   }
876 
877   @Generates private StringReader generateStringReader() {
878     return new StringReader(generateString());
879   }
880 
881   @Generates private Reader generateReader() {
882     return generateStringReader();
883   }
884 
885   @Generates private Readable generateReadable() {
886     return generateReader();
887   }
888 
889   @Generates private Buffer generateBuffer() {
890     return generateCharBuffer();
891   }
892 
893   @Generates private CharBuffer generateCharBuffer() {
894     return CharBuffer.allocate(generateInt());
895   }
896 
897   @Generates private ByteBuffer generateByteBuffer() {
898     return ByteBuffer.allocate(generateInt());
899   }
900 
901   @Generates private ShortBuffer generateShortBuffer() {
902     return ShortBuffer.allocate(generateInt());
903   }
904 
905   @Generates private IntBuffer generateIntBuffer() {
906     return IntBuffer.allocate(generateInt());
907   }
908 
909   @Generates private LongBuffer generateLongBuffer() {
910     return LongBuffer.allocate(generateInt());
911   }
912 
913   @Generates private FloatBuffer generateFloatBuffer() {
914     return FloatBuffer.allocate(generateInt());
915   }
916 
917   @Generates private DoubleBuffer generateDoubleBuffer() {
918     return DoubleBuffer.allocate(generateInt());
919   }
920 }