///<summary> ///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. ///</summary> protected ISet <String> InferThriftFieldIds() { ISet <String> fieldsWithConflictingIds = new HashSet <String>(); // group fields by explicit name or by name extracted from field, method or property var fieldsByExplicitOrExtractedName = this._fields.GroupBy(FieldMetadata.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? var fieldsByExtractedName = _fields.GroupBy(FieldMetadata.ExtractThriftFieldName()); InferThriftFieldIds(fieldsByExtractedName, fieldsWithConflictingIds); return(fieldsWithConflictingIds); }
protected void NormalizeThriftFields(ThriftCatalog catalog) { // assign all fields an id (if possible) var fieldsWithConflictingIds = InferThriftFieldIds(); // group fields by id var fieldsById = _fields.GroupBy(f => f.Id); foreach (var entry in fieldsById) { var fields = entry; //fields must have an id if (entry.Key == short.MinValue) { var names = fields.Select(FieldMetadata.GetOrExtractThriftFieldName()); foreach (String n in names) { // only report errors for fields that don't have conflicting ids if (!fieldsWithConflictingIds.Contains(n)) { this.MetadataErrors.AddError($"Thrift class '{StructName}' fields {String.Join(", ", names)} do not have an id."); } } continue; } short fieldId = entry.Key; // ensure all fields for this ID have the same name String fieldName = ExtractFieldName(fieldId, fields); foreach (FieldMetadata field in fields) { field.Name = fieldName; } // ensure all fields for this ID have the same requiredness ThriftFieldAttribute.Requiredness requiredness = ExtractFieldRequiredness(fieldId, fieldName, fields); foreach (FieldMetadata field in fields) { if (field.Requiredness != ThriftFieldAttribute.Requiredness.Unspecified) { field.Requiredness = requiredness; } else { field.Requiredness = (catalog.IsNullable(field.CSharpType)) ? ThriftFieldAttribute.Requiredness.Optional : ThriftFieldAttribute.Requiredness.Required; } } // We need to do the isLegacyId check in two places. We've already done this // process for fields which had multiple `@ThriftField` annotations when we // assigned them all the same ID. It doesn't hurt to do it again. On the other // hand, we need to do it now to catch the fields which only had a single // @ThriftAnnotation, because inferThriftFieldIds skipped them. //boolean isLegacyId = extractFieldIsLegacyId(fieldId, fieldName, fields); //for (FieldMetadata field : fields) //{ // field.setIsLegacyId(isLegacyId); //} var idlAnnotations = ExtractFieldIdlAnnotations(fieldId, fields); foreach (FieldMetadata field in fields) { field.IdlAnnotations = idlAnnotations; } // ensure all fields for this ID have the same non-null get for isRecursiveReference bool isRecursiveReference = ExtractFieldIsRecursiveReference(fieldId, fields); foreach (FieldMetadata field in fields) { field.IsRecursiveReference = isRecursiveReference; } // verify fields have a supported java type and all fields // for this ID have the same thrift type VerifyFieldType(fieldId, fieldName, fields, catalog); } }