@Override protected void validateConstructors() { if (constructorInjections.size() > 1) { metadataErrors.addError("Multiple constructors are annotated with @ThriftConstructor ", constructorInjections); } }
@Override protected void validateConstructors() { if (constructorInjections.size() > 1) { metadataErrors.addError("Multiple constructors are annotated with @ThriftConstructor ", constructorInjections); } }
protected final boolean extractFieldIsLegacyId(short id, String fieldName, Collection<FieldMetadata> fields) { Set<Boolean> isLegacyIds = ImmutableSet.copyOf(Optional.presentInstances(transform(fields, getThriftFieldIsLegacyId()))); if (isLegacyIds.size() > 1) { metadataErrors.addError("Thrift class '%s' field '%s' has both isLegacyId=true and isLegacyId=false", structName, fieldName); } if (id < 0) { if (! isLegacyIds.contains(true)) { metadataErrors.addError("Thrift class '%s' field '%s' has a negative field id but not isLegacyId=true", structName, fieldName); } } else { if (isLegacyIds.contains(true)) { metadataErrors.addError("Thrift class '%s' field '%s' has isLegacyId=true but not a negative field id", structName, fieldName); } } return id < 0; }
protected final void verifyClass(Class<? extends Annotation> annotation) { String annotationName = annotation.getSimpleName(); String structClassName = getStructClass().getName(); // Verify struct class is public and final if (!Modifier.isPublic(getStructClass().getModifiers())) { metadataErrors.addError("%s class '%s' is not public", annotationName, structClassName); } if (!getStructClass().isAnnotationPresent(annotation)) { metadataErrors.addError("%s class '%s' does not have a @%s annotation", annotationName, structClassName, annotationName); } }
protected final boolean extractFieldIsRecursiveReference(short fieldId, Collection<FieldMetadata> fields) { Set<Boolean> isRecursiveReferences = fields.stream() .map(FieldMetadata::isRecursiveReference) .filter(value -> value != null) .collect(toImmutableSet()); if (isRecursiveReferences.isEmpty()) { return false; } if (isRecursiveReferences.size() > 1) { metadataErrors.addError("Thrift class '%s' field '%s' has both isRecursiveReference=TRUE and isRecursiveReference=FALSE", structName, fieldId); } return isRecursiveReferences.iterator().next(); }
protected final Map<String, String> extractFieldIdlAnnotations(short fieldId, Collection<FieldMetadata> fields) { Set<Map<String, String>> idlAnnotationMaps = fields.stream() .map(field -> field == null ? null : field.getIdlAnnotations()) .filter(annotationMap -> annotationMap != null && !annotationMap.isEmpty()) .collect(toImmutableSet()); if (idlAnnotationMaps.isEmpty()) { return ImmutableMap.of(); } if (idlAnnotationMaps.size() > 1) { metadataErrors.addError("Thrift class '%s' field '%s' has conflicting IDL annotation maps", structName, fieldId); } return idlAnnotationMaps.iterator().next(); }
protected final void verifyClass(Class<? extends Annotation> annotation) { String annotationName = annotation.getSimpleName(); String structClassName = getStructClass().getName(); // Verify struct class is public and final if (!Modifier.isPublic(getStructClass().getModifiers())) { metadataErrors.addError("%s class '%s' is not public", annotationName, structClassName); } if (!Modifier.isFinal(getStructClass().getModifiers())) { metadataErrors.addError("%s class '%s' is not final (thrift does not support polymorphic data types)", annotationName, structClassName); } if (!getStructClass().isAnnotationPresent(annotation)) { metadataErrors.addError("%s class '%s' does not have a @%s annotation", annotationName, structClassName, annotationName); } }
protected final Requiredness extractFieldRequiredness(short fieldId, String fieldName, Collection<FieldMetadata> fields) { Predicate<Requiredness> specificRequiredness = new Predicate<Requiredness>() { @Override public boolean apply(@Nullable Requiredness input) { return (input != null) && (input != Requiredness.UNSPECIFIED); } }; Set<Requiredness> requirednessValues = ImmutableSet.copyOf(filter(transform(fields, getThriftFieldRequiredness()), specificRequiredness)); if (requirednessValues.size() > 1) { metadataErrors.addError("Thrift class '%s' field '%s(%d)' has multiple requiredness values: %s", structName, fieldName, fieldId, requirednessValues.toString()); } Requiredness resolvedRequiredness; if (requirednessValues.isEmpty()) { resolvedRequiredness = Requiredness.NONE; } else { resolvedRequiredness = requirednessValues.iterator().next(); } return resolvedRequiredness; }
protected final Requiredness extractFieldRequiredness(short fieldId, String fieldName, Collection<FieldMetadata> fields) { Predicate<Requiredness> specificRequiredness = new Predicate<Requiredness>() { @Override public boolean apply(@Nullable Requiredness input) { return (input != null) && (input != Requiredness.UNSPECIFIED); } }; Set<Requiredness> requirednessValues = ImmutableSet.copyOf(filter(transform(fields, getThriftFieldRequiredness()), specificRequiredness)); if (requirednessValues.size() > 1) { metadataErrors.addError("Thrift class '%s' field '%s(%d)' has multiple requiredness values: %s", structName, fieldName, fieldId, requirednessValues.toString()); } Requiredness resolvedRequiredness; if (requirednessValues.isEmpty()) { resolvedRequiredness = Requiredness.NONE; } else { resolvedRequiredness = requirednessValues.iterator().next(); } return resolvedRequiredness; }
protected final void addMethods(Type type, boolean allowReaders, boolean allowWriters) { Class<?> clazz = TypeToken.of(type).getRawType(); for (Method fieldMethod : findAnnotatedMethods(clazz, ThriftField.class)) { addMethod(type, fieldMethod, allowReaders, allowWriters); } // find invalid methods not skipped by findAnnotatedMethods() for (Method method : getAllDeclaredMethods(clazz)) { if (method.isAnnotationPresent(ThriftField.class) || hasThriftFieldAnnotation(method)) { if (!Modifier.isPublic(method.getModifiers())) { metadataErrors.addError("@ThriftField method '%s' is not public", method.toGenericString()); } if (Modifier.isStatic(method.getModifiers())) { metadataErrors.addError("@ThriftField method '%s' is static", method.toGenericString()); } } } }
protected final void addMethods(Type type, boolean allowReaders, boolean allowWriters) { Class<?> clazz = TypeToken.of(type).getRawType(); for (Method fieldMethod : findAnnotatedMethods(clazz, ThriftField.class)) { addMethod(type, fieldMethod, allowReaders, allowWriters); } // find invalid methods not skipped by findAnnotatedMethods() for (Method method : getAllDeclaredMethods(clazz)) { if (method.isAnnotationPresent(ThriftField.class) || hasThriftFieldAnnotation(method)) { if (!Modifier.isPublic(method.getModifiers())) { metadataErrors.addError("@ThriftField method '%s' is not public", method.toGenericString()); } if (Modifier.isStatic(method.getModifiers())) { metadataErrors.addError("@ThriftField method '%s' is static", method.toGenericString()); } } } }
protected final void addFields(Class<?> clazz, boolean allowReaders, boolean allowWriters) { for (Field fieldField : ReflectionHelper.findAnnotatedFields(clazz, ThriftField.class)) { addField(fieldField, allowReaders, allowWriters); } // find invalid fields not skipped by findAnnotatedFields() for (Field field : getAllDeclaredFields(clazz)) { if (field.isAnnotationPresent(ThriftField.class)) { if (!Modifier.isPublic(field.getModifiers())) { metadataErrors.addError("@ThriftField field '%s' is not public", field.toGenericString()); } if (Modifier.isStatic(field.getModifiers())) { metadataErrors.addError("@ThriftField field '%s' is static", field.toGenericString()); } } } }
private Type extractBuilderType() { Class<?> builderClass = extractBuilderClass(); if (builderClass == null) { return null; } if (builderClass.getTypeParameters().length == 0) { return builderClass; } if (!(structType instanceof ParameterizedType)) { metadataErrors.addError("Builder class '%s' may only be generic if the type it builds ('%s') is also generic", builderClass.getName(), getStructClass().getName()); return builderClass; } if (builderClass.getTypeParameters().length != getStructClass().getTypeParameters().length) { metadataErrors.addError("Generic builder class '%s' must have the same number of type parameters as the type it builds ('%s')", builderClass.getName(), getStructClass().getName()); return builderClass; } ParameterizedType parameterizedStructType = (ParameterizedType) structType; return new MoreTypes.ParameterizedTypeImpl(builderClass.getEnclosingClass(), builderClass, parameterizedStructType.getActualTypeArguments()); }
private Type extractBuilderType() { Class<?> builderClass = extractBuilderClass(); if (builderClass == null) { return null; } if (builderClass.getTypeParameters().length == 0) { return builderClass; } if (!(structType instanceof ParameterizedType)) { metadataErrors.addError("Builder class '%s' may only be generic if the type it builds ('%s') is also generic", builderClass.getName(), getStructClass().getName()); return builderClass; } if (builderClass.getTypeParameters().length != getStructClass().getTypeParameters().length) { metadataErrors.addError("Generic builder class '%s' must have the same number of type parameters as the type it builds ('%s')", builderClass.getName(), getStructClass().getName()); return builderClass; } ParameterizedType parameterizedStructType = (ParameterizedType) structType; return new MoreTypes.ParameterizedTypeImpl(builderClass.getEnclosingClass(), builderClass, parameterizedStructType.getActualTypeArguments()); }
protected final void addFields(Class<?> clazz, boolean allowReaders, boolean allowWriters) { for (Field fieldField : ReflectionHelper.findAnnotatedFields(clazz, ThriftField.class)) { addField(fieldField, allowReaders, allowWriters); } // find invalid fields not skipped by findAnnotatedFields() for (Field field : getAllDeclaredFields(clazz)) { if (field.isAnnotationPresent(ThriftField.class)) { if (!Modifier.isPublic(field.getModifiers())) { metadataErrors.addError("@ThriftField field '%s' is not public", field.toGenericString()); } if (Modifier.isStatic(field.getModifiers())) { metadataErrors.addError("@ThriftField field '%s' is static", field.toGenericString()); } } } }
protected final void inferThriftFieldIds(Multimap<String, FieldMetadata> fieldsByName, Set<String> fieldsWithConflictingIds) { // for each name group, set the ids on the fields without ids for (Entry<String, Collection<FieldMetadata>> entry : fieldsByName.asMap().entrySet()) { Collection<FieldMetadata> fields = entry.getValue(); // skip all entries without a name or singleton groups... we'll deal with these later if (fields.size() <= 1) { continue; } // all ids used by this named field Set<Short> ids = ImmutableSet.copyOf(Optional.presentInstances(transform(fields, getThriftFieldId()))); // multiple conflicting ids if (ids.size() > 1) { String fieldName = entry.getKey(); if (!fieldsWithConflictingIds.contains(fieldName)) { metadataErrors.addError("Thrift class '%s' field '%s' has multiple ids: %s", structName, fieldName, ids.toString()); fieldsWithConflictingIds.add(fieldName); } continue; } // single id, so set on all fields in this group (groups with no id are handled later) if (ids.size() == 1) { // propagate the id to all fields in this group short id = Iterables.getOnlyElement(ids); for (FieldMetadata field : fields) { field.setId(id); } } } }
/** * Verifies that the the fields all have a supported Java type and that all fields map to the * exact same ThriftType. */ protected final void verifyFieldType(short id, String name, Collection<FieldMetadata> fields, ThriftCatalog catalog) { boolean isSupportedType = true; for (FieldMetadata field : fields) { if (!catalog.isSupportedStructFieldType(field.getJavaType())) { metadataErrors.addError("Thrift class '%s' field '%s(%s)' type '%s' is not a supported Java type", structName, name, id, TypeToken.of(field.getJavaType())); isSupportedType = false; // only report the error once break; } } // fields must have the same type if (isSupportedType) { Set<ThriftTypeReference> types = new HashSet<>(); for (FieldMetadata field : fields) { types.add(catalog.getFieldThriftTypeReference(field)); } if (types.size() > 1) { metadataErrors.addError("Thrift class '%s' field '%s(%s)' has multiple types: %s", structName, name, id, types); } } }
@Override protected void validateConstructors() { for (ConstructorInjection constructorInjection : constructorInjections) { if (constructorInjection.getParameters().size() > 1) { metadataErrors.addError("@ThriftConstructor [%s] takes %d arguments, this is illegal for an union", constructorInjection.getConstructor().toGenericString(), constructorInjection.getParameters().size()); } } }
@Override protected void validateConstructors() { for (ConstructorInjection constructorInjection : constructorInjections) { if (constructorInjection.getParameters().size() > 1) { metadataErrors.addError("@ThriftConstructor [%s] takes %d arguments, this is illegal for an union", constructorInjection.getConstructor().toGenericString(), constructorInjection.getParameters().size()); } } }
/** * Verifies that the the fields all have a supported Java type and that all fields map to the * exact same ThriftType. */ protected final void verifyFieldType(short id, String name, Collection<FieldMetadata> fields, ThriftCatalog catalog) { boolean isSupportedType = true; for (FieldMetadata field : fields) { if (!catalog.isSupportedStructFieldType(field.getJavaType())) { metadataErrors.addError("Thrift class '%s' field '%s(%s)' type '%s' is not a supported Java type", structName, name, id, TypeToken.of(field.getJavaType())); isSupportedType = false; // only report the error once break; } } // fields must have the same type if (isSupportedType) { Set<ThriftType> types = new HashSet<>(); for (FieldMetadata field : fields) { types.add(catalog.getThriftType(field.getJavaType())); } if (types.size() > 1) { metadataErrors.addError("Thrift class '%s' field '%s(%s)' has multiple types: %s", structName, name, id, types); } } }