/** * Generates a {@link TypeDescriptor} for {@code DoFn<InputT, OutputT>.ProcessContext} given * {@code InputT} and {@code OutputT}. */ private static <InputT, OutputT> TypeDescriptor<DoFn<InputT, OutputT>.ProcessContext> doFnProcessContextTypeOf( TypeDescriptor<InputT> inputT, TypeDescriptor<OutputT> outputT) { return new TypeDescriptor<DoFn<InputT, OutputT>.ProcessContext>() {}.where( new TypeParameter<InputT>() {}, inputT) .where(new TypeParameter<OutputT>() {}, outputT); }
/** * Generates a {@link TypeDescriptor} for {@code DoFn<InputT, OutputT>.FinishBundleContext} given * {@code InputT} and {@code OutputT}. */ private static <InputT, OutputT> TypeDescriptor<DoFn<InputT, OutputT>.FinishBundleContext> doFnFinishBundleContextTypeOf( TypeDescriptor<InputT> inputT, TypeDescriptor<OutputT> outputT) { return new TypeDescriptor<DoFn<InputT, OutputT>.FinishBundleContext>() {}.where( new TypeParameter<InputT>() {}, inputT) .where(new TypeParameter<OutputT>() {}, outputT); }
/** * Generates a {@link TypeDescriptor} for {@code DoFn<InputT, OutputT>.Context} given {@code * InputT} and {@code OutputT}. */ private static <InputT, OutputT> TypeDescriptor<DoFn<InputT, OutputT>.OnTimerContext> doFnOnTimerContextTypeOf( TypeDescriptor<InputT> inputT, TypeDescriptor<OutputT> outputT) { return new TypeDescriptor<DoFn<InputT, OutputT>.OnTimerContext>() {}.where( new TypeParameter<InputT>() {}, inputT) .where(new TypeParameter<OutputT>() {}, outputT); }
/** The {@link TypeDescriptor} for {@link Map}. */ public static <K, V> TypeDescriptor<Map<K, V>> maps( TypeDescriptor<K> keyType, TypeDescriptor<V> valueType) { TypeDescriptor<Map<K, V>> typeDescriptor = new TypeDescriptor<Map<K, V>>() {}.where(new TypeParameter<K>() {}, keyType) .where(new TypeParameter<V>() {}, valueType); return typeDescriptor; }
/** * Generates a {@link TypeDescriptor} for {@code DoFn<InputT, OutputT>.StartBundleContext} given * {@code InputT} and {@code OutputT}. */ private static <InputT, OutputT> TypeDescriptor<DoFn<InputT, OutputT>.StartBundleContext> doFnStartBundleContextTypeOf( TypeDescriptor<InputT> inputT, TypeDescriptor<OutputT> outputT) { return new TypeDescriptor<DoFn<InputT, OutputT>.StartBundleContext>() {}.where( new TypeParameter<InputT>() {}, inputT) .where(new TypeParameter<OutputT>() {}, outputT); }
/** * Returns a new {@code TypeDescriptor} where the type variable represented by {@code * typeParameter} are substituted by {@code type}. For example, it can be used to construct {@code * Map<K, V>} for any {@code K} and {@code V} type: * * <pre>{@code * static <K, V> TypeDescriptor<Map<K, V>> mapOf( * TypeDescriptor<K> keyType, TypeDescriptor<V> valueType) { * return new TypeDescriptor<Map<K, V>>() {} * .where(new TypeParameter<K>() {}, keyType) * .where(new TypeParameter<V>() {}, valueType); * } * }</pre> * * @param <X> The parameter type * @param typeParameter the parameter type variable * @param typeDescriptor the actual type to substitute */ @SuppressWarnings("unchecked") public <X> TypeDescriptor<T> where( TypeParameter<X> typeParameter, TypeDescriptor<X> typeDescriptor) { return where(typeParameter.typeVariable, typeDescriptor.getType()); }
/** * The {@link TypeDescriptor} for {@link KV}. This is the equivalent of: * * <pre> * new TypeDescriptor<KV<K,V>>() {}; * </pre> * * <p>Example of use: * * <pre>{@code * PCollection<String> words = ...; * PCollection<KV<String, String>> words = words.apply(FlatMapElements * .into(TypeDescriptors.kv(TypeDescriptors.strings(), TypeDescriptors.strings())) * .via(...)); * }</pre> * * @param key The {@link TypeDescriptor} for the key * @param value The {@link TypeDescriptor} for the value * @return A {@link TypeDescriptor} for {@link KV} */ public static <K, V> TypeDescriptor<KV<K, V>> kvs( TypeDescriptor<K> key, TypeDescriptor<V> value) { TypeDescriptor<KV<K, V>> typeDescriptor = new TypeDescriptor<KV<K, V>>() {}.where(new TypeParameter<K>() {}, key) .where(new TypeParameter<V>() {}, value); return typeDescriptor; }
@Override public TypeDescriptor<Map<K, V>> getEncodedTypeDescriptor() { return new TypeDescriptor<Map<K, V>>() {}.where( new TypeParameter<K>() {}, keyCoder.getEncodedTypeDescriptor()) .where(new TypeParameter<V>() {}, valueCoder.getEncodedTypeDescriptor()); } }
@Override public TypeDescriptor<KV<K, V>> getEncodedTypeDescriptor() { return new TypeDescriptor<KV<K, V>>() {}.where( new TypeParameter<K>() {}, keyCoder.getEncodedTypeDescriptor()) .where(new TypeParameter<V>() {}, valueCoder.getEncodedTypeDescriptor()); } }
@Override public TypeDescriptor<FailsafeElement<OriginalT, CurrentT>> getEncodedTypeDescriptor() { return new TypeDescriptor<FailsafeElement<OriginalT, CurrentT>>() {}.where( new TypeParameter<OriginalT>() {}, originalPayloadCoder.getEncodedTypeDescriptor()) .where(new TypeParameter<CurrentT>() {}, currentPayloadCoder.getEncodedTypeDescriptor()); } }
/** * Like {@link #extractFromTypeParameters(Object, Class, TypeVariableExtractor)}, but takes a * {@link TypeDescriptor} of the instance being analyzed rather than the instance itself. */ @SuppressWarnings("unchecked") public static <T, V> TypeDescriptor<V> extractFromTypeParameters( TypeDescriptor<T> type, Class<? super T> supertype, TypeVariableExtractor<T, V> extractor) { // Get the type signature of the extractor, e.g. // TypeVariableExtractor<SerializableFunction<BarT, String>, BarT> TypeDescriptor<TypeVariableExtractor<T, V>> extractorSupertype = (TypeDescriptor<TypeVariableExtractor<T, V>>) TypeDescriptor.of(extractor.getClass()).getSupertype(TypeVariableExtractor.class); // Get the actual type argument, e.g. SerializableFunction<BarT, String> Type inputT = ((ParameterizedType) extractorSupertype.getType()).getActualTypeArguments()[0]; // Get the actual supertype of the type being analyzed, hopefully with all type parameters // resolved, e.g. SerializableFunction<Integer, String> TypeDescriptor supertypeDescriptor = type.getSupertype(supertype); // Substitute actual supertype into the extractor, e.g. // TypeVariableExtractor<SerializableFunction<Integer, String>, Integer> TypeDescriptor<TypeVariableExtractor<T, V>> extractorT = extractorSupertype.where(inputT, supertypeDescriptor.getType()); // Get output of the extractor. Type outputT = ((ParameterizedType) extractorT.getType()).getActualTypeArguments()[1]; return (TypeDescriptor<V>) TypeDescriptor.of(outputT); }