/// <summary> /// Gets the Thrift wire type associated with the specified type. /// </summary> public static ThriftType Get(Type type) { if (!_knownTypes.ContainsKey(type)) { var thriftType = new ThriftType(type); _knownTypes.TryAdd(type, thriftType); // This has to be done this way because otherwise self-referencing types will loop // since they'd call ThriftType.Get before they were themselves added to _knownTypes switch (thriftType.Id) { case ThriftTypeId.Map: thriftType.KeyType = ThriftType.Get(thriftType._collectionGenericArgs[0]); thriftType.ValueType = ThriftType.Get(thriftType._collectionGenericArgs[1]); break; case ThriftTypeId.List: case ThriftTypeId.Set: if (thriftType.TypeInfo.IsArray) { thriftType.ElementType = ThriftType.Get(thriftType.TypeInfo.GetElementType()); } else { thriftType.ElementType = ThriftType.Get(thriftType._collectionGenericArgs[0]); } break; } } return(_knownTypes[type]); }
/// <summary> /// Initializes a new instance of the ThriftType class from the specified .NET type. /// </summary> private ThriftType(Type type) { Id = ThriftTypeId.Empty; TypeInfo = type.GetTypeInfo(); if (type == typeof(void)) { return; } var underlyingNullableType = Nullable.GetUnderlyingType(type); if (underlyingNullableType != null) { NullableType = ThriftType.Get(underlyingNullableType); Id = NullableType.Id; IsEnum = NullableType.IsEnum; return; } if (PrimitiveIds.ContainsKey(type)) { Id = PrimitiveIds[type]; return; } if (TypeInfo.IsEnum) { if (TypeInfo.GetCustomAttribute <ThriftEnumAttribute>() == null) { throw ThriftParsingException.EnumWithoutAttribute(TypeInfo); } if (Enum.GetUnderlyingType(type) != typeof(int)) { throw ThriftParsingException.NonInt32Enum(TypeInfo); } Id = ThriftTypeId.Int32; IsEnum = true; return; } if (TypeInfo.IsValueType) { throw ThriftParsingException.UnknownValueType(TypeInfo); } if (TypeInfo.IsArray) { Id = ThriftTypeId.List; return; } var mapInterfaceAndArgs = GetInstantiableVersion(TypeInfo, typeof(IDictionary <,>), typeof(Dictionary <,>), p => ThriftParsingException.UnsupportedMap(p)); if (mapInterfaceAndArgs != null) { Id = ThriftTypeId.Map; TypeInfo = mapInterfaceAndArgs.Item1; _collectionGenericArgs = mapInterfaceAndArgs.Item2; } var setInterfaceAndArgs = GetInstantiableVersion(TypeInfo, typeof(ISet <>), typeof(HashSet <>), p => ThriftParsingException.UnsupportedSet(p)); if (setInterfaceAndArgs != null) { if (mapInterfaceAndArgs != null) { throw ThriftParsingException.CollectionWithOrthogonalInterfaces(TypeInfo); } Id = ThriftTypeId.Set; TypeInfo = setInterfaceAndArgs.Item1; _collectionGenericArgs = setInterfaceAndArgs.Item2; } var listInterfaceAndArgs = GetInstantiableVersion(TypeInfo, typeof(IList <>), typeof(List <>), p => ThriftParsingException.UnsupportedList(p)); if (listInterfaceAndArgs != null) { if (mapInterfaceAndArgs != null || setInterfaceAndArgs != null) { throw ThriftParsingException.CollectionWithOrthogonalInterfaces(TypeInfo); } Id = ThriftTypeId.List; TypeInfo = listInterfaceAndArgs.Item1; _collectionGenericArgs = listInterfaceAndArgs.Item2; } if (Id == ThriftTypeId.Empty) { Id = ThriftTypeId.Struct; } }
/// <summary> /// Initializes a new instance of the ThriftConvertibleValue class with the specified underlying type and converter. /// </summary> protected ThriftConvertibleValue(TypeInfo typeInfo, ThriftConverter converter) { WireType = ThriftType.Get(converter?.FromType ?? typeInfo.AsType()); Converter = converter; }