@Override public Optional<Boolean> apply(@Nullable T input) { if (input == null) { return Optional.absent(); } Boolean value = input.isLegacyId(); if (input.getId() == null || input.getId().shortValue() == Short.MIN_VALUE) { if (value != null && value.booleanValue() == false) { return Optional.absent(); } } return Optional.fromNullable(value); } };
@Override public String apply(@Nullable T input) { if (input == null) { return null; } String name = input.getName(); if (name == null) { name = input.extractName(); } if (name == null) { throw new NullPointerException(String.valueOf("name is null")); } return name; } };
protected final String extractFieldName(short id, Collection<FieldMetadata> fields) { // get the names used by these fields Set<String> names = ImmutableSet.copyOf(filter(transform(fields, getThriftFieldName()), notNull())); String name; if (!names.isEmpty()) { if (names.size() > 1) { metadataErrors.addWarning("Thrift class %s field %s has multiple names %s", structName, id, names); } name = names.iterator().next(); } else { // pick a name for this field name = Iterables.find(transform(fields, extractThriftFieldName()), notNull()); } return name; }
public ThriftTypeReference getFieldThriftTypeReference(FieldMetadata fieldMetadata) { Boolean isRecursive = fieldMetadata.isRecursiveReference(); if (isRecursive == null) { throw new IllegalStateException( "Field normalization should have set a non-null value for isRecursiveReference"); } return getThriftTypeReference(fieldMetadata.getJavaType(), isRecursive ? Recursiveness.FORCED : Recursiveness.NOT_ALLOWED); }
ThriftExtraction extraction = null; for (FieldMetadata fieldMetadata : input) { id = fieldMetadata.getId(); isLegacyId = fieldMetadata.isLegacyId(); name = fieldMetadata.getName(); recursive = fieldMetadata.isRecursiveReference(); requiredness = fieldMetadata.getRequiredness(); idlAnnotations = fieldMetadata.getIdlAnnotations(); thriftTypeReference = catalog.getFieldThriftTypeReference(fieldMetadata); parameterInjection.getName(), parameterInjection.getParameterIndex(), fieldMetadata.getJavaType() ));
ThriftExtraction extraction = null; for (FieldMetadata fieldMetadata : input) { id = fieldMetadata.getId(); name = fieldMetadata.getName(); requiredness = fieldMetadata.getRequiredness(); type = catalog.getThriftType(fieldMetadata.getJavaType()); parameterInjection.getName(), parameterInjection.getParameterIndex(), fieldMetadata.getJavaType() ));
Multimap<Optional<Short>, FieldMetadata> fieldsById = Multimaps.index(fields, getThriftFieldId()); for (Entry<Optional<Short>, Collection<FieldMetadata>> entry : fieldsById.asMap().entrySet()) { Collection<FieldMetadata> fields = entry.getValue(); for (String fieldName : newTreeSet(transform(fields, getOrExtractThriftFieldName()))) { metadataErrors.addError("Thrift class '%s' fields %s do not have an id", structName, newTreeSet(transform(fields, getOrExtractThriftFieldName()))); field.setName(fieldName); field.setRequiredness(requiredness); field.setIsLegacyId(isLegacyId); field.setIdlAnnotations(idlAnnotations); field.setIsRecursiveReference(isRecursiveReference);
Multimap<Optional<Short>, FieldMetadata> fieldsById = Multimaps.index(fields, getThriftFieldId()); for (Entry<Optional<Short>, Collection<FieldMetadata>> entry : fieldsById.asMap().entrySet()) { Collection<FieldMetadata> fields = entry.getValue(); for (String fieldName : newTreeSet(transform(fields, getOrExtractThriftFieldName()))) { metadataErrors.addError("Thrift class '%s' fields %s do not have an id", structName, newTreeSet(transform(fields, getOrExtractThriftFieldName()))); field.setName(fieldName); field.setRequiredness(requiredness);
String name = field.getName(); short id = field.getId(); boolean legacy = field.isLegacyId();
Set<Short> ids = ImmutableSet.copyOf(Optional.presentInstances(transform(fields, getThriftFieldId()))); field.setId(id); field.setIsLegacyId(isLegacyId);
/** * Assigns all fields an id if possible. Fields are grouped by name and for each group, if there * is a single id, all fields in the group are assigned this id. If the group has multiple ids, * an error is reported. */ protected final Set<String> inferThriftFieldIds() { Set<String> fieldsWithConflictingIds = new HashSet<>(); // group fields by explicit name or by name extracted from field, method or property Multimap<String, FieldMetadata> fieldsByExplicitOrExtractedName = Multimaps.index(fields, getOrExtractThriftFieldName()); inferThriftFieldIds(fieldsByExplicitOrExtractedName, fieldsWithConflictingIds); // group fields by name extracted from field, method or property // this allows thrift name to be set explicitly without having to duplicate the name on getters and setters // todo should this be the only way this works? Multimap<String, FieldMetadata> fieldsByExtractedName = Multimaps.index(fields, extractThriftFieldName()); inferThriftFieldIds(fieldsByExtractedName, fieldsWithConflictingIds); return fieldsWithConflictingIds; }
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); } } } }
@Override public String apply(@Nullable T input) { if (input == null) { return null; } return input.getName(); } };
@Override public Optional<Short> apply(@Nullable T input) { if (input == null) { return Optional.absent(); } Short value = input.getId(); return Optional.fromNullable(value); } };
@Override public String apply(@Nullable T input) { if (input == null) { return null; } return input.extractName(); } };
@Nullable @Override public Requiredness apply(@Nullable T input) { return input.getRequiredness(); } };
protected final Iterable<ThriftFieldMetadata> buildFieldInjections() { Multimap<Optional<Short>, FieldMetadata> fieldsById = Multimaps.index(fields, getThriftFieldId()); return Iterables.transform(fieldsById.asMap().values(), new Function<Collection<FieldMetadata>, ThriftFieldMetadata>() { @Override public ThriftFieldMetadata apply(Collection<FieldMetadata> input) { checkArgument(!input.isEmpty(), "input is empty"); return buildField(input); } }); }
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; }
/** * 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); } } }
ThriftExtraction extraction = null; for (FieldMetadata fieldMetadata : input) { id = fieldMetadata.getId(); isLegacyId = fieldMetadata.isLegacyId(); name = fieldMetadata.getName(); recursiveness = fieldMetadata.isRecursiveReference(); requiredness = fieldMetadata.getRequiredness(); idlAnnotations = fieldMetadata.getIdlAnnotations(); fieldType = fieldMetadata.getType(); thriftTypeReference = catalog.getFieldThriftTypeReference(fieldMetadata); parameterInjection.getName(), parameterInjection.getParameterIndex(), fieldMetadata.getJavaType() ); injections.add(thriftParameterInjection);