public static ThriftType Enum(ThriftEnumMetadata enumMetadata, bool isNullable = false) { Guard.ArgumentNotNull(enumMetadata, nameof(enumMetadata)); var tt = new ThriftType(enumMetadata); return(isNullable ? tt.CoerceTo(typeof(Nullable <>).MakeGenericType(enumMetadata.EnumType)) : tt); }
public static ThriftType Dictionary(ThriftType keyType, ThriftType valueType) { Guard.ArgumentNotNull(keyType, nameof(keyType)); Guard.ArgumentNotNull(valueType, nameof(valueType)); return(Dictionary(new DefaultThriftTypeReference(keyType), new DefaultThriftTypeReference(valueType))); }
private ThriftType BuildThriftType(Type csharpType) { ThriftType thriftType = _typeCache.GetOrAdd(csharpType, t => BuildThriftTypeInternal(csharpType)); if (_stack.Value.Count == 0) { /* * The stack represents the processing of nested types, so when the stack is empty * at this point, we've just finished processing and caching the originally requested * type. There may be some unresolved type references we should revisit now. */ var unresolvedCSharpTypes = _deferredTypesWorkList.Value; do { if (unresolvedCSharpTypes.Count == 0) { break; } Type unresolvedType = unresolvedCSharpTypes.Pop(); if (!_typeCache.ContainsKey(unresolvedType)) { _typeCache.GetOrAdd(unresolvedType, t => BuildThriftTypeInternal(unresolvedType)); } } while (true); } return(thriftType); }
public ThriftType GetThriftTypeFromCache(Type csharpType) { ThriftType tt = null; _typeCache.TryGetValue(csharpType, out tt); return(tt); }
public TypeCoercion(ThriftType thriftType) { Guard.ArgumentNotNull(thriftType, nameof(thriftType)); var typeInfo = thriftType.CSharpType.GetTypeInfo(); if (!typeInfo.IsGenericType || !typeInfo.GetGenericTypeDefinition().Equals(typeof(Nullable <>))) { throw new ArgumentException($"only nullable type can be used by {nameof(TypeCoercion)}, actual thrift type is: {thriftType.CSharpType.FullName}"); } _underlyingType = Nullable.GetUnderlyingType(thriftType.CSharpType); this.ThriftType = thriftType; var p = Expression.Parameter(thriftType.CSharpType); var methodName = nameof(Nullable <int> .GetValueOrDefault); var m = thriftType.CSharpType.GetMethod(methodName, new Type[0]); var call = Expression.Call(p, m); this.ToThrift = Expression.Lambda(call, p).Compile(); var p1 = Expression.Parameter(_underlyingType, "v"); var ctor = typeInfo.GetConstructor(new Type[] { _underlyingType }); var newExp = Expression.New(ctor, p1); this.FromThrift = Expression.Lambda(newExp, p1).Compile(); }
/// <summary> /// Gets the ThriftType for the specified Java type. The native Thrift type for the Java type will /// be inferred from the Java type, and if necessary type coercions will be applied. /// </summary> /// <param name="csharpType"></param> /// <returns>the ThriftType for the specified csharp type; never null</returns> public ThriftType GetThriftType(Type csharpType) { ThriftType thriftType = GetThriftTypeFromCache(csharpType); if (thriftType == null) { thriftType = BuildThriftType(csharpType); } return(thriftType); }
public ThriftType Get() { ThriftType resolvedType = catalog.GetThriftTypeFromCache(this.CSharpType); if (resolvedType == null) { throw new NotSupportedException( $"Attempted to resolve a recursive reference to type '{this.CSharpType.FullName}' before the referenced type was cached (most likely a recursive type support bug)"); } return(resolvedType); }
private ThriftType(ThriftType underlyingType, Type nullableType) { this.CSharpType = nullableType; this.UncoercedType = underlyingType; this.ProtocolType = underlyingType.ProtocolType; keyTypeReference = null; valueTypeReference = null; structMetadata = null; enumMetadata = underlyingType.enumMetadata; }
private IThriftTypeReference GetThriftTypeReference(Type csharpType, Recursiveness recursiveness) { ThriftType thriftType = GetThriftTypeFromCache(csharpType); if (thriftType == null) { if (recursiveness == Recursiveness.Forced || (recursiveness == Recursiveness.Allowed && _stack.Value.Contains(csharpType))) { // recursion: return an unresolved ThriftTypeReference _deferredTypesWorkList.Value.Push(csharpType); return(new RecursiveThriftTypeReference(this, csharpType)); } else { thriftType = _typeCache.GetOrAdd(csharpType, t => BuildThriftType(t)); } } return(new DefaultThriftTypeReference(thriftType)); }
public override bool Equals(object o) { if (this != null && o != null && Object.ReferenceEquals(this, o)) { return(true); } if (o == null || !this.GetType().Equals(o.GetType())) { return(false); } ThriftType that = (ThriftType)o; if (this.CSharpType != null ? !this.CSharpType.Equals(that.CSharpType) : that.CSharpType != null) { return(false); } if (!this.ProtocolType.Equals(that.ProtocolType)) { return(false); } return(true); }
public DefaultThriftTypeReference(ThriftType thriftType) { this.thriftType = thriftType; }
public static ThriftType Array(ThriftType valueType) { Guard.ArgumentNotNull(valueType, nameof(valueType)); return(Array(new DefaultThriftTypeReference(valueType))); }
public void AddThriftType(ThriftType thriftType) { _manualTypes.AddOrUpdate(thriftType.CSharpType, thriftType, (ket, old) => thriftType); }
// 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}"); }