@Override public TypeDescriptor<T> getEncodedTypeDescriptor() { if (typeDescriptor == null) { typeDescriptor = TypeDescriptor.of(type); } return typeDescriptor; }
public T convert(TypeDescriptor typeDescriptor) { if (typeDescriptor.isArray() && !typeDescriptor.getComponentType().getRawType().equals(byte.class)) { // Byte arrays are special, so leave those alone. return convertArray(typeDescriptor); } else if (typeDescriptor.isSubtypeOf(TypeDescriptor.of(Collection.class))) { return convertCollection(typeDescriptor); } else if (typeDescriptor.isSubtypeOf(TypeDescriptor.of(Map.class))) { return convertMap(typeDescriptor); } else if (typeDescriptor.isSubtypeOf(TypeDescriptor.of(ReadableInstant.class))) { return convertDateTime(typeDescriptor); } else if (typeDescriptor.isSubtypeOf(TypeDescriptor.of(ByteBuffer.class))) { return convertByteBuffer(typeDescriptor); } else if (typeDescriptor.isSubtypeOf(TypeDescriptor.of(CharSequence.class))) { return convertCharSequence(typeDescriptor); } else if (typeDescriptor.getRawType().isPrimitive()) { return convertPrimitive(typeDescriptor); } else { return convertDefault(typeDescriptor); } }
/** Return true if the given type token is a subtype of *any* of the listed parents. */ private static boolean isSubtypeOf(TypeDescriptor<?> type, Class<?>... parents) { for (Class<?> parent : parents) { if (type.isSubtypeOf(TypeDescriptor.of(parent))) { return true; } } return false; }
/** * If {@code coderType} is a subclass of {@code Coder<T>} for a specific type {@code T}, returns * {@code T.class}. */ @SuppressWarnings({"rawtypes", "unchecked"}) public static TypeDescriptor getCodedType(TypeDescriptor coderDescriptor) { ParameterizedType coderType = (ParameterizedType) coderDescriptor.getSupertype(Coder.class).getType(); TypeDescriptor codedType = TypeDescriptor.of(coderType.getActualTypeArguments()[0]); return codedType; } }
/** * 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()); }
private static FieldType getArrayFieldType(TypeDescriptor typeDescriptor) { if (typeDescriptor.isArray()) { if (typeDescriptor.getComponentType().getType().equals(byte.class)) { return FieldType.BYTES; } else { return FieldType.array(fieldTypeForJavaType(typeDescriptor.getComponentType())); } } if (typeDescriptor.isSubtypeOf(TypeDescriptor.of(Collection.class))) { TypeDescriptor<Collection<?>> collection = typeDescriptor.getSupertype(Collection.class); if (collection.getType() instanceof ParameterizedType) { ParameterizedType ptype = (ParameterizedType) collection.getType(); java.lang.reflect.Type[] params = ptype.getActualTypeArguments(); checkArgument(params.length == 1); return FieldType.array(fieldTypeForJavaType(TypeDescriptor.of(params[0]))); } } throw new RuntimeException("Could not determine array parameter type for field."); }
private void validateInputData(Configuration conf) { TypeDescriptor<KeyT> outputFormatKeyClass = (TypeDescriptor<KeyT>) TypeDescriptor.of(conf.getClass(OUTPUT_KEY_CLASS, null)); TypeDescriptor<ValueT> outputFormatValueClass = (TypeDescriptor<ValueT>) TypeDescriptor.of(conf.getClass(OUTPUT_VALUE_CLASS, null)); TypeDescriptor.class.getSimpleName()); checkArgument( KV.class.equals(inputTypeDescriptor.getRawType()), "%s expects %s as input type.", Write.class.getSimpleName(), KV.class); checkArgument( inputTypeDescriptor.equals( TypeDescriptors.kvs(outputFormatKeyClass, outputFormatValueClass)), "%s expects following %ss: KV(Key: %s, Value: %s) but following %ss are set: KV(Key: %s, Value: %s)", Write.class.getSimpleName(), TypeDescriptor.class.getSimpleName(), outputFormatKeyClass.getRawType(), outputFormatValueClass.getRawType(), TypeDescriptor.class.getSimpleName(), inputTypeDescriptor.resolveType(KV.class.getTypeParameters()[0]), inputTypeDescriptor.resolveType(KV.class.getTypeParameters()[1]));
@SuppressWarnings("unchecked") private static Implementation getMapType(TypeDescriptor valueType, int index) { if (valueType.isSubtypeOf(TypeDescriptor.of(Map.class))) { TypeDescriptor<Collection<?>> map = valueType.getSupertype(Map.class); if (map.getType() instanceof ParameterizedType) { ParameterizedType ptype = (ParameterizedType) map.getType(); java.lang.reflect.Type[] params = ptype.getActualTypeArguments(); return FixedValue.reference(params[index]); } else { throw new RuntimeException("Map type is not parameterized! " + map); } } return FixedValue.nullValue(); } }
@SuppressWarnings("unchecked") private <ElementT> TypeDescriptor<List<ElementT>> createListType(TypeDescriptor<?> type) { TypeDescriptor componentType = TypeDescriptor.of(ClassUtils.primitiveToWrapper(type.getComponentType().getRawType())); return new TypeDescriptor<List<ElementT>>() {}.where( new TypeParameter<ElementT>() {}, componentType); } }
/** * 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); }
private void checkString(String context, TypeDescriptor<?> type) { // For types that are encoded as strings, we need to make sure they're in an approved // whitelist. For other types that are annotated @Stringable, Avro will just use the // #toString() methods, which has no guarantees of determinism. if (!DETERMINISTIC_STRINGABLE_CLASSES.contains(type.getRawType())) { reportError(context, "%s may not have deterministic #toString()", type); } }
@VisibleForTesting static DoFnSignature.GetRestrictionCoderMethod analyzeGetRestrictionCoderMethod( ErrorReporter errors, TypeDescriptor<? extends DoFn> fnT, Method m) { errors.checkArgument(m.getParameterTypes().length == 0, "Must have zero arguments"); TypeDescriptor<?> resT = fnT.resolveType(m.getGenericReturnType()); errors.checkArgument( resT.isSubtypeOf(TypeDescriptor.of(Coder.class)), "Must return a Coder, but returns %s", formatType(resT)); return DoFnSignature.GetRestrictionCoderMethod.create(m, resT); }
/** Get a {@link FieldType} from a {@link TypeDescriptor}. */ public static FieldType fieldTypeForJavaType(TypeDescriptor typeDescriptor) { if (typeDescriptor.isArray() || typeDescriptor.isSubtypeOf(TypeDescriptor.of(Collection.class))) { return getArrayFieldType(typeDescriptor); } else if (typeDescriptor.isSubtypeOf(TypeDescriptor.of(Map.class))) { return getMapFieldType(typeDescriptor); } else if (typeDescriptor.isSubtypeOf(TypeDescriptor.of(Row.class))) { throw new IllegalArgumentException( "Cannot automatically determine a field type from a Row class" + " as we cannot determine the schema. You should set a field type explicitly."); } else { TypeName typeName = PRIMITIVE_MAPPING.inverse().get(typeDescriptor); if (typeName == null) { throw new RuntimeException("Couldn't find field type for " + typeDescriptor); } FieldType fieldType = FieldType.of(typeName); return fieldType; } }
@Test public void testTypeDescriptorOfRawType() throws Exception { assertEquals( TypeToken.of(String.class).getRawType(), TypeDescriptor.of(String.class).getRawType()); }
@Test public void testGetTypeParameterGood() throws Exception { @SuppressWarnings("rawtypes") TypeVariable<Class<? super GenericClass>> bizzleT = TypeDescriptor.of(GenericClass.class).getTypeParameter("BizzleT"); assertEquals(GenericClass.class.getTypeParameters()[0], bizzleT); }
@Nullable private static TypeDescriptor<? extends BoundedWindow> getWindowType( TypeDescriptor<?> fnClass, Method method) { Type[] params = method.getGenericParameterTypes(); for (Type param : params) { TypeDescriptor<?> paramT = fnClass.resolveType(param); if (BoundedWindow.class.isAssignableFrom(paramT.getRawType())) { return (TypeDescriptor<? extends BoundedWindow>) paramT; } } return null; }
@Override public <T> Coder<T> coderFor(TypeDescriptor<T> typeDescriptor, List<? extends Coder<?>> componentCoders) throws CannotProvideCoderException { Type t = typeDescriptor.getType(); if (IndexedRecord.class.isAssignableFrom(typeDescriptor.getRawType())) { Coder<T> c = LazyAvroCoder.<T> of(); return c; } throw new CannotProvideCoderException(String.format("Cannot provide %s because %s is not implement IndexedRecord", LazyAvroCoder.class.getSimpleName(), typeDescriptor)); } }
/** Validates translation function given for key/value translation. */ private void validateTranslationFunction( TypeDescriptor<?> inputType, SimpleFunction<?, ?> simpleFunction, String errorMsg) { if (simpleFunction != null && !simpleFunction.getInputTypeDescriptor().equals(inputType)) { throw new IllegalArgumentException( String.format(errorMsg, getinputFormatClass().getRawType(), inputType.getRawType())); } }