public void RecursiveTypeTest() { ThriftCatalog catalog = new ThriftCatalog(); ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(catalog, typeof(RecursiveStruct)); var metadata = builder.Build(); Assert.Equal(1, metadata.Fields.Count()); }
public void InvalidRecursiveTypeTest() { ThriftCatalog catalog = new ThriftCatalog(); Assert.Throws <ThriftyException>(() => { ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(catalog, typeof(InvalidRecursiveStruct)); builder.Build(); }); }
public void ComplexTypeTest() { ThriftCatalog catalog = new ThriftCatalog(); ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(catalog, typeof(ComplexStruct)); ThriftStructMetadata metadata = builder.Build(); var properties = typeof(ComplexStruct).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly); Assert.Equal(properties.Length, metadata.Fields.Count()); Assert.Equal(false, metadata.IsException); Assert.Equal(false, metadata.IsUnion); Assert.Equal(MetadataType.Struct, metadata.MetadataType); Assert.Equal(0, metadata.MethodInjections.Count()); Assert.Equal(null, metadata.BuilderType); }
private ThriftStructMetadata StructTest <T>() { ThriftCatalog catalog = new ThriftCatalog(); ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(catalog, typeof(T)); ThriftStructMetadata metadata = builder.Build(); var properties = typeof(T).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); Assert.Equal(properties.Length, metadata.Fields.Count()); Assert.Equal(false, metadata.IsException); Assert.Equal(false, metadata.IsUnion); Assert.Equal(MetadataType.Struct, metadata.MetadataType); Assert.Equal(0, metadata.MethodInjections.Count()); Assert.Equal(null, metadata.BuilderType); return(metadata); }
internal ThriftMethodMetadata(String serviceName, MethodInfo method, ThriftCatalog catalog) { Guard.ArgumentNullOrWhiteSpaceString(serviceName, nameof(serviceName)); Guard.ArgumentNotNull(method, nameof(method)); Guard.ArgumentNotNull(catalog, nameof(catalog)); this.Order = (ThriftCatalog.GetMethodOrder(method) ?? int.MaxValue); ThriftMethodAttribute thriftMethod = method.GetCustomAttribute <ThriftMethodAttribute>(); if (thriftMethod == null) { throw new ArgumentException($"Method '{method.DeclaringType.Name}.{method.Name}' is not annotated with {nameof(ThriftMethodAttribute)}.", nameof(method)); } if (method.IsStatic) { throw new ArgumentException($"Method '{method.DeclaringType.Name}.{method.Name} is a static method.", nameof(method)); } this.Name = String.IsNullOrWhiteSpace(thriftMethod.Name) ? method.Name : thriftMethod.Name.Trim(); this.QualifiedName = GetQualifiedName(serviceName, Name); //this.QualifiedName = $"{serviceName}.{this.Name}"; this.ReturnType = catalog.GetThriftType(method.ReturnType); var builder = ImmutableList.CreateBuilder <ThriftFieldMetadata>(); var parameters = method.GetParameters(); int index = 0; foreach (var p in parameters) { ThriftFieldMetadata fieldMetadata = CreateFieldMetadata(catalog, index, p); builder.Add(fieldMetadata); index++; } this.Parameters = builder.ToImmutableList(); this.IsOneWay = thriftMethod.OneWay; this.Method = method; this.Exceptions = BuildExceptions(catalog, method); }
private static ThriftFieldMetadata CreateFieldMetadata(ThriftCatalog catalog, int index, ParameterInfo parameterInfo) { ThriftFieldAttribute thriftField = parameterInfo.GetCustomAttribute <ThriftFieldAttribute>(); short parameterId = short.MinValue; String parameterName = parameterInfo.Name; Requiredness parameterRequiredness = Requiredness.Unspecified; if (thriftField != null) { parameterId = thriftField.Id; parameterRequiredness = thriftField.Required; if (!String.IsNullOrWhiteSpace(thriftField.Name)) { parameterName = thriftField.Name.Trim(); } } if (parameterId == short.MinValue) { parameterId = (short)(index + 1); } ThriftType thriftType = catalog.GetThriftType(parameterInfo.ParameterType); var parameterInjection = new ThriftParameterInjection(parameterId, parameterName, index, parameterInfo.ParameterType); if (parameterRequiredness == Requiredness.Unspecified) { // There is only one field injection used to build metadata for method parameters, and if a // single injection point has UNSPECIFIED requiredness, that resolves to NONE. parameterRequiredness = Requiredness.None; } ThriftFieldMetadata fieldMetadata = new ThriftFieldMetadata( parameterId, false /* recursiveness */, parameterRequiredness, new DefaultThriftTypeReference(thriftType), parameterName, FieldKind.ThriftField, new IThriftInjection[] { parameterInjection }); return(fieldMetadata); }
//private readonly IEnumerable<String> documentation; public ThriftServiceMetadata(Type serviceClass, ThriftCatalog catalog) { this.Name = ParseServiceName(serviceClass); var builder = ImmutableDictionary.CreateBuilder <String, ThriftMethodMetadata>(); foreach (var method in serviceClass.FindAttributedMethods(typeof(ThriftMethodAttribute))) { ThriftMethodMetadata methodMetadata = new ThriftMethodMetadata(this.Name, method, catalog); if (builder.ContainsKey(methodMetadata.QualifiedName)) { throw new ThriftyException($"duplicate thrift method : {method.DeclaringType.FullName}.{method.Name} ."); } builder[methodMetadata.QualifiedName] = methodMetadata; } this.Methods = builder.ToImmutable(); //A multimap from order to method name. Sorted by key (order), with nulls (i.e. no order) last. //Within each key, values(ThriftMethodMetadata) are sorted by method name. this.DeclaredMethods = builder .OrderBy(kp => kp.Value.Order).ThenBy(kp => kp.Key) .ToArray() .ToImmutableDictionary(kp => kp.Key, kp => kp.Value); List <ThriftServiceMetadata> parentServices = new List <ThriftServiceMetadata>(); foreach (var parent in serviceClass.GetTypeInfo().GetInterfaces()) { var attributes = parent.GetEffectiveClassAnnotations <ThriftServiceAttribute>(); if (attributes.Any()) { parentServices.Add(new ThriftServiceMetadata(parent, catalog)); } } this.ParentServices = parentServices.ToImmutableList(); }
private IDictionary <short, ThriftType> BuildExceptions(ThriftCatalog catalog, MethodInfo method) { var exceptions = ImmutableDictionary.CreateBuilder <short, ThriftType>(); HashSet <Type> exceptionTypes = new HashSet <Type>(); var exceptionAttributes = method.GetCustomAttributes <ThriftExceptionAttribute>(true); foreach (var thriftException in exceptionAttributes) { if (!exceptionTypes.Add(thriftException.ExceptionType)) { throw new ThriftyException($"ThriftExceptionAttribute on method {method.DeclaringType}.{method.Name} contains more than one value for {thriftException.ExceptionType} ."); } if (exceptions.ContainsKey(thriftException.Id)) { throw new ThriftyException($"ThriftExceptionAttribute on method {method.DeclaringType}.{method.Name} has duplicate id: {thriftException.Id} ."); } exceptions.Add(thriftException.Id, catalog.GetThriftType(thriftException.ExceptionType)); } foreach (var exceptionType in exceptionAttributes.Select(a => a.ExceptionType)) { if (exceptionType.GetTypeInfo().IsAssignableFrom(typeof(TException))) { // the built-in exception types don't need special treatment continue; } ThriftStructAttribute attribute = exceptionType.GetTypeInfo().GetCustomAttribute <ThriftStructAttribute>(); if (attribute == null) { throw new ThriftyException($"ThriftExceptionAttribute on method {method.DeclaringType}.{method.Name} with {exceptionType.FullName} need {nameof(ThriftStructAttribute)} ."); } } return(exceptions.ToImmutableDictionary()); }
public ThriftCodecManager(IEnumerable <IThriftCodec> codecs = null, IThriftCodecFactory factory = null, ThriftCatalog catalog = null) { _typeCodecs = new ConcurrentDictionary <ThriftType, IThriftCodec>(); _stack = new ThreadLocal <Stack <ThriftType> >(() => new Stack <ThriftType>()); _deferredTypesWorkList = new ThreadLocal <Stack <ThriftType> >(() => new Stack <ThriftType>()); this.Catalog = catalog ?? new ThriftCatalog(); this._factory = factory ?? new ReflectionThriftCodecFactory(); AddBuiltinCodec(new BooleanThriftCodec()); AddBuiltinCodec(new ByteThriftCodec()); AddBuiltinCodec(new ShortThriftCodec()); AddBuiltinCodec(new IntThriftCodec()); AddBuiltinCodec(new LongThriftCodec()); AddBuiltinCodec(new DoubleThriftCodec()); AddBuiltinCodec(new ByteBufferThriftCodec()); AddBuiltinCodec(new StringThriftCodec()); AddBuiltinCodec(new VoidThriftCodec()); AddBuiltinCodec(new BooleanArrayThriftCodec()); AddBuiltinCodec(new ShortArrayThriftCodec()); AddBuiltinCodec(new IntArrayThriftCodec()); AddBuiltinCodec(new LongArrayThriftCodec()); AddBuiltinCodec(new DoubleArrayThriftCodec()); AddBuiltinCodec(new FloatThriftCodec()); AddBuiltinCodec(new FloatArrayThriftCodec()); AddBuiltinCodec(new DateTimeThriftCodec()); AddBuiltinCodec(new DateTimeArrayThriftCodec()); AddBuiltinCodec(new GuidThriftCodec()); AddBuiltinCodec(new DecimalThriftCodec()); var codecArray = codecs ?? Enumerable.Empty <IThriftCodec>(); foreach (var codec in codecArray) { AddCodec(codec); } }