예제 #1
0
        protected AbstractThriftMetadataBuilder(ThriftCatalog catalog, Type structType)
        {
            Guard.ArgumentNotNull(catalog, nameof(catalog));
            Guard.ArgumentNotNull(structType, nameof(structType));

            this._fields     = new List <FieldMetadata>();
            this._extractors = new List <Extractor>();
            this._builderMethodInjections = new List <MethodInjection>();
            this._constructorInjections   = new List <ConstructorInjection>();
            this._fieldInjections         = new List <FieldInjection>();
            this._methodInjections        = new List <MethodInjection>();

            this.Catalog         = catalog;
            this.StructType      = structType;
            this._metadataErrors = new MetadataErrors(catalog.Monitor);

            // assign the struct name from the annotation or from the Java class
            this.StructName = ExtractName();
            // get the builder type from the annotation or from the Java class
            this.BuilderType = ExtractBuilderType();

            // extract all of the annotated constructor and report an error if
            // there is more than one or none

            // extract thrift fields from the annotated fields and verify
            ExtractFromFields();

            // also extract thrift fields from the annotated parameters and verify
            ExtractFromConstructors();

            //不考虑支持方法注入
            // extract thrift fields from the annotated methods (and parameters) and verify
            //extractFromMethods();
        }
예제 #2
0
 public ThriftStructMetadataBuilder(ThriftCatalog catalog, Type structType) : base(catalog, structType)
 {
     this.VerifyType <ThriftStructAttribute>();
     this.NormalizeThriftFields(catalog);
 }
예제 #3
0
        ///<summary>
        ///Verifies that the the fields all have a supported Java type and that all fields map to the
        ///exact same ThriftType.
        ///</summary>
        protected void VerifyFieldType(short id, String name, IEnumerable <FieldMetadata> fields, ThriftCatalog catalog)
        {
            bool isSupportedType = true;

            foreach (FieldMetadata field in fields)
            {
                if (!catalog.IsSupportedStructFieldType(field.CSharpType))
                {
                    _metadataErrors.AddError($"Thrift class '{this.StructName}' field '{name}({id})' type '{field.CSharpType}' is not a supported C# type.");
                    isSupportedType = false;
                    // only report the error once
                    break;
                }
            }

            // fields must have the same type
            if (isSupportedType)
            {
                HashSet <IThriftTypeReference> types = new HashSet <IThriftTypeReference>();
                foreach (FieldMetadata field in fields)
                {
                    types.Add(catalog.GetFieldThriftTypeReference(field));
                }
                if (types.Count > 1)
                {
                    _metadataErrors.AddError($"Thrift class '{this.StructName}' field '{name}({id})' has multiple types: {String.Join(", ", types)}");
                }
            }
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
 public RecursiveThriftTypeReference(ThriftCatalog catalog, Type javaType)
 {
     this.catalog      = catalog;
     this.CSharpType   = javaType;
     this.ProtocolType = catalog.GetThriftProtocolType(javaType);
 }