Пример #1
0
        /// <summary>
        /// Gets the default TypeCoercion (and associated ThriftType) for the specified csharp type.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public TypeCoercion GetDefaultCoercion(Type type)
        {
            TypeCoercion r = null;

            _coercions.TryGetValue(type, out r);
            return(r);
        }
Пример #2
0
        protected override ThriftFieldMetadata BuildField(IEnumerable <FieldMetadata> input)
        {
            short id = -1;
            //IDictionary<String, String> idlAnnotations = null;
            String               name                = null;
            Requiredness         requiredness        = Requiredness.Unspecified;
            bool                 recursive           = false;
            IThriftTypeReference thriftTypeReference = null;

            // process field injections and extractions
            List <IThriftInjection> injections = new List <IThriftInjection>();
            IThriftExtraction       extraction = null;

            foreach (FieldMetadata fieldMetadata in input)
            {
                id           = fieldMetadata.Id;
                name         = fieldMetadata.Name;
                recursive    = fieldMetadata.IsRecursiveReference ?? false;
                requiredness = fieldMetadata.Requiredness;
                //idlAnnotations = fieldMetadata.getIdlAnnotations();
                thriftTypeReference = this.Catalog.GetFieldThriftTypeReference(fieldMetadata);

                FieldInjection fieldInjection = fieldMetadata as FieldInjection;
                if (fieldInjection != null)
                {
                    injections.Add(new ThriftFieldInjection(fieldInjection.Id,
                                                            fieldInjection.Name,
                                                            fieldInjection.Field,
                                                            fieldInjection.Type));
                }
                else if (fieldMetadata is ParameterInjection)
                {
                    ParameterInjection parameterInjection = (ParameterInjection)fieldMetadata;
                    injections.Add(new ThriftParameterInjection(
                                       parameterInjection.Id,
                                       parameterInjection.Name,
                                       parameterInjection.ParameterIndex,
                                       fieldMetadata.CSharpType
                                       ));
                }
                else if (fieldMetadata is FieldExtractor)
                {
                    FieldExtractor fieldExtractor = (FieldExtractor)fieldMetadata;
                    extraction = new ThriftFieldExtractor(
                        fieldExtractor.Id, fieldExtractor.Name,
                        fieldExtractor.Type,
                        fieldExtractor.Field,
                        fieldExtractor.CSharpType);
                }
                else if (fieldMetadata is MethodExtractor)
                {
                    MethodExtractor methodExtractor = (MethodExtractor)fieldMetadata;
                    extraction = new ThriftMethodExtractor(
                        methodExtractor.Id,
                        methodExtractor.Name,
                        methodExtractor.Type,
                        methodExtractor.Method,
                        methodExtractor.CSharpType);
                }
            }

            // add type coercion
            TypeCoercion coercion = null;

            if (!thriftTypeReference.Recursive && thriftTypeReference.Get().IsCoerced)
            {
                coercion = this.Catalog.GetDefaultCoercion(thriftTypeReference.Get().CSharpType);
            }

            if (recursive && requiredness != Requiredness.Optional)
            {
                this.MetadataErrors.AddError($"Struct '{this.StructName}' field '{name}' is recursive but not marked optional");
            }

            ThriftFieldMetadata thriftFieldMetadata = new ThriftFieldMetadata(
                id,
                recursive,
                requiredness,
                //idlAnnotations,
                thriftTypeReference,
                name,
                FieldKind.ThriftField,
                injections,
                extraction: extraction,
                coercion: coercion
                );

            return(thriftFieldMetadata);
        }
Пример #3
0
        //private IEnumerable<String> documentation;

        public ThriftFieldMetadata(
            short id,
            bool isRecursiveReference,
            Requiredness requiredness,
            //IEnumerable<KeyValuePair<String, String>> idlAnnotations,
            IThriftTypeReference thriftTypeReference,
            String name,
            FieldKind fieldKind,
            IEnumerable <IThriftInjection> injections       = null,
            ThriftConstructorInjection constructorInjection = null,
            ThriftMethodInjection methodInjection           = null,
            IThriftExtraction extraction = null,
            TypeCoercion coercion        = null
            )
        {
            Guard.ArgumentNotNull(thriftTypeReference, nameof(thriftTypeReference));
            Guard.ArgumentNotNull(fieldKind, nameof(fieldKind));
            Guard.ArgumentNullOrWhiteSpaceString(name, nameof(name));
            Guard.ArgumentNotNull(thriftTypeReference, nameof(thriftTypeReference));
            Guard.ArgumentNullOrWhiteSpaceString(name, nameof(name));
            //Guard.ArgumentNotNull(constructorInjection, nameof(constructorInjection));
            //Guard.ArgumentNotNull(methodInjection, nameof(methodInjection));
            //Guard.ArgumentNotNull(extraction, nameof(extraction));
            //Guard.ArgumentNotNull(coercion, nameof(coercion));

            this.IsRecursiveReference = isRecursiveReference;
            this.Required             = requiredness;
            this._thriftTypeReference = thriftTypeReference;
            this._fieldKind           = fieldKind;
            this.Name                  = name;
            this.Injections            = injections ?? Enumerable.Empty <IThriftInjection>();
            this._constructorInjection = constructorInjection;
            this._methodInjection      = methodInjection;

            this._extraction = extraction;
            this._coercion   = coercion;

            switch (fieldKind)
            {
            case FieldKind.ThriftField:
                Guard.ArgumentCondition(id >= 0, "isLegacyId must be specified on fields with negative IDs", nameof(id));

                break;

            case FieldKind.ThriftUnionId:
                Guard.ArgumentCondition(id == short.MinValue, "thrift union id must be short.MinValue", nameof(id));
                break;
            }

            Guard.ArgumentCondition(injections.Any() ||
                                    extraction != null ||
                                    constructorInjection != null ||
                                    methodInjection != null, "A thrift field must have an injection or extraction point");

            this.Id = id;

            if (extraction != null)
            {
                if (extraction is ThriftFieldExtractor)
                {
                    ThriftFieldExtractor e = (ThriftFieldExtractor)extraction;
                    //this.documentation = ThriftCatalog.getThriftDocumentation(e.getField());
                }
                else if (extraction != null && extraction is ThriftMethodExtractor)
                {
                    ThriftMethodExtractor e = (ThriftMethodExtractor)extraction;
                    //this.documentation = ThriftCatalog.getThriftDocumentation(e.getMethod());
                }
            }

            //this.idlAnnotations = idlAnnotations;
        }
Пример #4
0
        // This should ONLY be called from buildThriftType()
        private ThriftType BuildThriftTypeInternal(Type csharpType)
        {
            ThriftType manualType = null;
            Type       rawType    = csharpType;

            if (_manualTypes.TryGetValue(csharpType, out manualType))
            {
                return(manualType);
            }
            if (typeof(bool).Equals(rawType))
            {
                return(ThriftType.Bool);
            }
            if (typeof(byte).Equals(rawType))
            {
                return(ThriftType.Byte);
            }
            if (typeof(short).Equals(rawType))
            {
                return(ThriftType.I16);
            }
            if (typeof(int).Equals(rawType))
            {
                return(ThriftType.I32);
            }
            if (typeof(long).Equals(rawType))
            {
                return(ThriftType.I64);
            }
            if (typeof(double).Equals(rawType))
            {
                return(ThriftType.Double);
            }
            if (typeof(float).Equals(rawType))
            {
                return(ThriftType.Float);
            }
            if (typeof(String).Equals(rawType))
            {
                return(ThriftType.String);
            }
            if (typeof(Guid).Equals(rawType))
            {
                return(ThriftType.Guid);
            }
            if (typeof(DateTime).Equals(rawType))
            {
                return(ThriftType.DateTime);
            }
            if (typeof(Decimal).Equals(rawType))
            {
                return(ThriftType.Decimal);
            }
            if (typeof(byte[]).Equals(rawType))
            {
                // byte[] is encoded as BINARY and requires a coersion
                return(ThriftType.Binary);
            }
            if (rawType.GetTypeInfo().IsEnum)
            {
                return(ThriftType.Enum(new ThriftEnumMetadata(rawType)));
            }

            var dicType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&&
                                                                                                t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(IDictionary <,>)));

            if (dicType != null)
            {
                var  argTypes     = dicType.GetTypeInfo().GetGenericArguments();
                Type mapKeyType   = argTypes[0];
                Type mapValueType = argTypes[1];
                return(ThriftType.Dictionary(
                           GetMapKeyThriftTypeReference(mapKeyType),
                           GetMapValueThriftTypeReference(mapValueType)));
            }

            if (rawType.IsArray)
            {
                var elementType = rawType.GetTypeInfo().GetElementType();

                return(ThriftType.Array(GetCollectionElementThriftTypeReference(elementType)));
            }

            var setType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&&
                                                                                                t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(ISet <>)));

            if (setType != null)
            {
                Type elementType = setType.GetTypeInfo().GetGenericArguments().First();
                return(ThriftType.Set(GetCollectionElementThriftTypeReference(elementType)));
            }

            var listType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&&
                                                                                                 t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(IList <>)));

            if (listType != null)
            {
                Type elementType = listType.GetTypeInfo().GetGenericArguments().First();
                return(ThriftType.List(GetCollectionElementThriftTypeReference(elementType)));
            }

            var arrayType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&&
                                                                                                  t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(IEnumerable <>)));

            if (arrayType != null)
            {
                Type elementType = arrayType.GetTypeInfo().GetGenericArguments().First();
                return(ThriftType.Array(GetCollectionElementThriftTypeReference(elementType)));
            }

            // The void type is used by service methods and is encoded as an empty struct
            if (typeof(void).IsAssignableFrom(rawType) || typeof(Task).Equals(rawType))
            {
                return(ThriftType.Void);
            }
            if (IsStructType(rawType))
            {
                ThriftStructMetadata structMetadata = GetThriftStructMetadata(csharpType);
                // Unions are covered because a union looks like a struct with a single field.
                return(ThriftType.Struct(structMetadata));
            }

            if (rawType.GetTypeInfo().IsGenericType&&
                rawType.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(Task <>)))
            {
                Type returnType = rawType.GetTypeInfo().GetGenericArguments().First();
                // TODO: check that we aren't recursing through multiple futures
                // TODO: find a way to restrict this to return values only
                return(GetThriftType(returnType));
            }

            // coerce the type if possible
            TypeCoercion coercion = null;

            if (_coercions.TryGetValue(csharpType, out coercion))
            {
                return(coercion.ThriftType);
            }

            if (IsNullableEnum(rawType))
            {
                coercion = _coercions.GetOrAdd(rawType, t =>
                {
                    ThriftEnumMetadata m = new ThriftEnumMetadata(t.GetTypeInfo().GetGenericArguments().First());
                    var tt = ThriftType.Enum(m, true);
                    return(new TypeCoercion(tt));
                });
                return(coercion.ThriftType);
            }

            throw new ThriftyException($"Type can not be coerced to a Thrift type: {csharpType.FullName}");
        }
Пример #5
0
        public ThriftProtocolType GetThriftProtocolType(Type rawType)
        {
            if (typeof(bool).Equals(rawType))
            {
                return(ThriftProtocolType.Bool);
            }
            if (typeof(byte).Equals(rawType))
            {
                return(ThriftProtocolType.Byte);
            }
            if (typeof(short).Equals(rawType))
            {
                return(ThriftProtocolType.I16);
            }
            if (typeof(int).Equals(rawType))
            {
                return(ThriftProtocolType.I32);
            }
            if (typeof(long).Equals(rawType))
            {
                return(ThriftProtocolType.I64);
            }
            if (typeof(double).Equals(rawType))
            {
                return(ThriftProtocolType.Double);
            }
            if (typeof(float).Equals(rawType))
            {
                return(ThriftProtocolType.Double);
            }
            if (typeof(String).Equals(rawType))
            {
                return(ThriftProtocolType.String);
            }
            if (typeof(byte).Equals(rawType))
            {
                return(ThriftProtocolType.Byte);
            }
            if (typeof(DateTime).Equals(rawType))
            {
                return(ThriftProtocolType.I64);
            }
            if (typeof(Guid).Equals(rawType))
            {
                return(ThriftProtocolType.String);
            }
            if (typeof(Decimal).Equals(rawType))
            {
                return(ThriftProtocolType.String);
            }
            if (typeof(byte[]).Equals(rawType))
            {
                return(ThriftProtocolType.Binary);
            }
            if (rawType.GetTypeInfo().IsEnum)
            {
                return(ThriftProtocolType.Enum);
            }

            var dicType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&&
                                                                                                t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(IDictionary <,>)));

            if (dicType != null)
            {
                return(ThriftProtocolType.Map);
            }

            //if (rawType.IsArray) //TODO: 这里应该判断基础类型,使用 Array 协议,不符合 thrift 标准
            //{
            //    return ThriftProtocolType.List;
            //}

            var setType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&&
                                                                                                t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(ISet <>)));

            if (setType != null)
            {
                return(ThriftProtocolType.Set);
            }

            var listType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&&
                                                                                                 t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(IList <>)));

            if (listType != null)
            {
                return(ThriftProtocolType.List);
            }

            var arrayType = rawType.GetInterfaces().Concat(new Type[] { rawType }).FirstOrDefault(t => t.GetTypeInfo().IsGenericType&&
                                                                                                  t.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(IEnumerable <>)));

            if (arrayType != null)
            {
                return(ThriftProtocolType.List);
            }

            // The void type is used by service methods and is encoded as an empty struct
            if (typeof(void).IsAssignableFrom(rawType) || typeof(Task).Equals(rawType))
            {
                return(ThriftProtocolType.Struct);
            }

            if (IsStructType(rawType))
            {
                return(ThriftProtocolType.Struct);
            }

            if (rawType.GetTypeInfo().IsGenericType&&
                rawType.GetTypeInfo().GetGenericTypeDefinition().Equals(typeof(Task <>)))
            {
                Type returnType = rawType.GetTypeInfo().GetGenericArguments().First();
                // TODO: check that we aren't recursing through multiple futures
                // TODO: find a way to restrict this to return values only
                return(this.GetThriftProtocolType(returnType));
            }

            // coerce the type if possible
            TypeCoercion coercion = null;

            if (_coercions.TryGetValue(rawType, out coercion))
            {
                return(coercion.ThriftType.ProtocolType);
            }

            if (IsNullableEnum(rawType))
            {
                return(ThriftProtocolType.Enum);
            }

            return(ThriftProtocolType.Unknown);
        }