Exemplo n.º 1
0
        public override int GetHashCode()
        {
            int hash = 1;

            if (Code != global::Google.Cloud.Spanner.V1.TypeCode.Unspecified)
            {
                hash ^= Code.GetHashCode();
            }
            if (arrayElementType_ != null)
            {
                hash ^= ArrayElementType.GetHashCode();
            }
            if (structType_ != null)
            {
                hash ^= StructType.GetHashCode();
            }
            if (TypeAnnotation != global::Google.Cloud.Spanner.V1.TypeAnnotationCode.Unspecified)
            {
                hash ^= TypeAnnotation.GetHashCode();
            }
            if (_unknownFields != null)
            {
                hash ^= _unknownFields.GetHashCode();
            }
            return(hash);
        }
Exemplo n.º 2
0
 public void MergeFrom(Type other)
 {
     if (other == null)
     {
         return;
     }
     if (other.Code != 0)
     {
         Code = other.Code;
     }
     if (other.arrayElementType_ != null)
     {
         if (arrayElementType_ == null)
         {
             arrayElementType_ = new global::Google.Cloud.Spanner.V1.Type();
         }
         ArrayElementType.MergeFrom(other.ArrayElementType);
     }
     if (other.structType_ != null)
     {
         if (structType_ == null)
         {
             structType_ = new global::Google.Cloud.Spanner.V1.StructType();
         }
         StructType.MergeFrom(other.StructType);
     }
 }
Exemplo n.º 3
0
 public void MergeFrom(Type other)
 {
     if (other == null)
     {
         return;
     }
     if (other.Code != global::Google.Cloud.Spanner.V1.TypeCode.Unspecified)
     {
         Code = other.Code;
     }
     if (other.arrayElementType_ != null)
     {
         if (arrayElementType_ == null)
         {
             ArrayElementType = new global::Google.Cloud.Spanner.V1.Type();
         }
         ArrayElementType.MergeFrom(other.ArrayElementType);
     }
     if (other.structType_ != null)
     {
         if (structType_ == null)
         {
             StructType = new global::Google.Cloud.Spanner.V1.StructType();
         }
         StructType.MergeFrom(other.StructType);
     }
     _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
 }
Exemplo n.º 4
0
        public void MergeFrom(StandardSqlDataType other)
        {
            if (other == null)
            {
                return;
            }
            if (other.TypeKind != global::Google.Cloud.Bigquery.V2.StandardSqlDataType.Types.TypeKind.Unspecified)
            {
                TypeKind = other.TypeKind;
            }
            switch (other.SubTypeCase)
            {
            case SubTypeOneofCase.ArrayElementType:
                if (ArrayElementType == null)
                {
                    ArrayElementType = new global::Google.Cloud.Bigquery.V2.StandardSqlDataType();
                }
                ArrayElementType.MergeFrom(other.ArrayElementType);
                break;

            case SubTypeOneofCase.StructType:
                if (StructType == null)
                {
                    StructType = new global::Google.Cloud.Bigquery.V2.StandardSqlStructType();
                }
                StructType.MergeFrom(other.StructType);
                break;
            }

            _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Returns a string representation of the current object.
 /// </summary>
 /// <returns>A string representation of the current object.</returns>
 public override string ToString()
 {
     return(string.Format(System.Globalization.CultureInfo.InvariantCulture,
                          "[CodeTypeInfo: Namespace={0} TypeNames={1} TypeArgumentCount={2} ArrayElementType={3} ArrayDimensions={4}]",
                          Namespace,
                          String.Join("+", TypeNames),
                          String.Join("+", Array.ConvertAll <int, string>(TypeArgumentCount, IntToString)),
                          ArrayElementType == null ? "<null>" : ArrayElementType.ToString(),
                          ArrayDimensions));
 }
        private void OnArraySizeChanged(int size)
        {
            var length = ArraySize;

            if (length != size)
            {
                var array = Value;
                if (PropertyType.IsArray)
                {
                    var newArray = System.Array.CreateInstance(ArrayElementType, size);
                    if (length < size)
                    {
                        System.Array.Copy(array as System.Array, newArray, length);
                        if (length > 0)
                        {
                            for (int i = length; i < size; i++)
                            {
                                System.Array.Copy(array as System.Array, length - 1, newArray, i, 1);
                            }
                        }
                    }
                    else
                    {
                        System.Array.Copy(array as System.Array, newArray, size);
                    }
                    Value = newArray;
                }
                else
                {
                    if (length < size)
                    {
                        object lastObject = null;
                        if (length > 0)
                        {
                            lastObject = getMethod.Invoke(array, new object[] { length - 1 });
                        }
                        else
                        {
                            lastObject = ArrayElementType.GetDefaultValue();
                        }
                        for (int i = length; i < size; i++)
                        {
                            addMethod.Invoke(array, new object[] { lastObject });
                        }
                    }
                    else
                    {
                        removerangeMethod.Invoke(array, new object[] { size, length - size });
                    }
                    Value = array;
                }
            }
            ApplyModifiedArray();
        }
Exemplo n.º 7
0
        public override int GetHashCode()
        {
            int hash = 1;

            if (Code != 0)
            {
                hash ^= Code.GetHashCode();
            }
            if (arrayElementType_ != null)
            {
                hash ^= ArrayElementType.GetHashCode();
            }
            if (structType_ != null)
            {
                hash ^= StructType.GetHashCode();
            }
            return(hash);
        }
Exemplo n.º 8
0
        public override int GetHashCode()
        {
            int hash = 1;

            if (TypeKind != global::Google.Cloud.Bigquery.V2.StandardSqlDataType.Types.TypeKind.Unspecified)
            {
                hash ^= TypeKind.GetHashCode();
            }
            if (subTypeCase_ == SubTypeOneofCase.ArrayElementType)
            {
                hash ^= ArrayElementType.GetHashCode();
            }
            if (subTypeCase_ == SubTypeOneofCase.StructType)
            {
                hash ^= StructType.GetHashCode();
            }
            hash ^= (int)subTypeCase_;
            if (_unknownFields != null)
            {
                hash ^= _unknownFields.GetHashCode();
            }
            return(hash);
        }
Exemplo n.º 9
0
 public static extern IntPtr op_core_Array_toString(IntPtr array, ArrayElementType elementType);
Exemplo n.º 10
0
        private object ConvertToClrTypeImpl(Value wireValue, System.Type targetClrType, SpannerConversionOptions options)
        {
            //If the wireValue itself is assignable to the target type, just return it
            //This covers both typeof(Value) and typeof(object).
            if (wireValue == null || targetClrType == null || targetClrType == typeof(Value))
            {
                return(wireValue);
            }

            if (wireValue.KindCase == Value.KindOneofCase.StructValue)
            {
                throw new InvalidOperationException($"google.protobuf.Struct values are invalid in Spanner");
            }

            // targetClrType should be one of the values returned by DefaultClrType
            if (targetClrType == typeof(bool))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(default(bool));

                case Value.KindOneofCase.StringValue:
                    if (TypeCode == TypeCode.Int64)
                    {
                        return(Convert.ToBoolean(Convert.ToInt64(wireValue.StringValue, InvariantCulture)));
                    }
                    return(Convert.ToBoolean(wireValue.StringValue));

                case Value.KindOneofCase.BoolValue:
                    return(wireValue.BoolValue);

                case Value.KindOneofCase.NumberValue:
                    return(Convert.ToBoolean(wireValue.NumberValue));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(char))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.BoolValue:
                    return(Convert.ToChar(wireValue.BoolValue));

                case Value.KindOneofCase.NumberValue:
                    return(Convert.ToChar(wireValue.NumberValue));

                case Value.KindOneofCase.NullValue:
                    return(default(char));

                case Value.KindOneofCase.StringValue:
                    if (TypeCode == TypeCode.Int64)
                    {
                        return(Convert.ToChar(Convert.ToInt64(wireValue.StringValue, InvariantCulture)));
                    }
                    return(Convert.ToChar(wireValue.StringValue));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(long))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.BoolValue:
                    return(Convert.ToInt64(wireValue.BoolValue));

                case Value.KindOneofCase.NumberValue:
                    return(Convert.ToInt64(wireValue.NumberValue));

                case Value.KindOneofCase.NullValue:
                    return(default(long));

                case Value.KindOneofCase.StringValue:
                    return(Convert.ToInt64(wireValue.StringValue, InvariantCulture));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(ulong))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.BoolValue:
                    return(Convert.ToUInt64(wireValue.BoolValue));

                case Value.KindOneofCase.NumberValue:
                    return(Convert.ToUInt64(wireValue.NumberValue));

                case Value.KindOneofCase.NullValue:
                    return(default(ulong));

                case Value.KindOneofCase.StringValue:
                    return(Convert.ToUInt64(wireValue.StringValue, InvariantCulture));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(decimal))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.BoolValue:
                    return(Convert.ToDecimal(wireValue.BoolValue));

                case Value.KindOneofCase.NumberValue:
                    return(Convert.ToDecimal(wireValue.NumberValue));

                case Value.KindOneofCase.NullValue:
                    return(default(decimal));

                case Value.KindOneofCase.StringValue:
                    return(Convert.ToDecimal(wireValue.StringValue, InvariantCulture));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(double))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.BoolValue:
                    return(Convert.ToDouble(wireValue.BoolValue));

                case Value.KindOneofCase.NullValue:
                    return(default(double));

                case Value.KindOneofCase.NumberValue:
                    return(wireValue.NumberValue);

                case Value.KindOneofCase.StringValue:
                    if (string.Compare(wireValue.StringValue, "NaN", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return(double.NaN);
                    }

                    if (string.Compare(wireValue.StringValue, "Infinity", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return(double.PositiveInfinity);
                    }

                    if (string.Compare(wireValue.StringValue, "-Infinity", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return(double.NegativeInfinity);
                    }

                    return(Convert.ToDouble(wireValue.StringValue, InvariantCulture));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(DateTime))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.StringValue:
                    return(XmlConvert.ToDateTime(wireValue.StringValue, XmlDateTimeSerializationMode.Utc));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(Timestamp))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.StringValue:
                    return(Protobuf.WellKnownTypes.Timestamp.Parser.ParseJson(wireValue.StringValue));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(string))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.NumberValue:
                    return(wireValue.NumberValue.ToString(InvariantCulture));

                case Value.KindOneofCase.StringValue:
                    return(wireValue.StringValue);

                case Value.KindOneofCase.BoolValue:
                    return(wireValue.BoolValue.ToString());

                default:
                    return(wireValue.ToString());
                }
            }

            if (targetClrType == typeof(byte[]))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.StringValue:
                    return(Convert.FromBase64String(wireValue.StringValue));

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            if (targetClrType == typeof(SpannerStruct))
            {
                if (TypeCode != TypeCode.Struct)
                {
                    throw new ArgumentException(
                              $"{targetClrType.FullName} can only be used for struct results");
                }
                if (wireValue.KindCase != Value.KindOneofCase.ListValue)
                {
                    throw new ArgumentException(
                              $"Invalid conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
                var values = wireValue.ListValue.Values;
                // StructFields will definitely be non-null, as we can only construct SpannerDbTypes of structs
                // by passing them fields.
                var ret = new SpannerStruct();
                if (StructFields.Count != values.Count)
                {
                    throw new InvalidOperationException(
                              $"Incorrect number of struct fields. SpannerDbType has {StructFields.Count}; list has {values.Count}");
                }
                // Could use Zip, but this is probably simpler.
                for (int i = 0; i < values.Count; i++)
                {
                    var field = StructFields[i];
                    ret.Add(field.Name, field.Type, field.Type.ConvertToClrType(values[i], typeof(object), options, topLevel: false));
                }
                return(ret);
            }

            // It's questionable as to whether we want to support this, but it does no harm to do so.
            if (typeof(IDictionary).IsAssignableFrom(targetClrType))
            {
                if (targetClrType == typeof(IDictionary))
                {
                    // Default type depends on whether it's a struct or not.
                    targetClrType = TypeCode == TypeCode.Struct
                        ? typeof(Dictionary <string, object>)
                        : typeof(Dictionary <int, object>);
                }
                //a bit of recursion here...
                IDictionary dictionary = (IDictionary)Activator.CreateInstance(targetClrType);
                var         itemType   = targetClrType.GetGenericArguments().Skip(1).FirstOrDefault() ?? typeof(object);
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.ListValue:
                    if (TypeCode == TypeCode.Struct)
                    {
                        for (int i = 0; i < StructFields.Count; i++)
                        {
                            var elementValue = wireValue.ListValue.Values[i];
                            var field        = StructFields[i];
                            dictionary[field.Name] = field.Type.ConvertToClrType(elementValue, itemType, options, topLevel: false);
                        }
                    }
                    else
                    {
                        var i = 0;
                        foreach (var listItemValue in wireValue.ListValue.Values)
                        {
                            dictionary[i] = ArrayElementType.ConvertToClrType(listItemValue, itemType, options, topLevel: false);
                            i++;
                        }
                    }
                    return(dictionary);

                default:
                    throw new ArgumentException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }
            if (targetClrType.IsArray)
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue: return(null);

                case Value.KindOneofCase.ListValue:
                    var newArray = Array.CreateInstance(
                        targetClrType.GetElementType(),
                        wireValue.ListValue.Values.Count);

                    var i = 0;
                    foreach (var obj in wireValue.ListValue.Values.Select(
                                 x => ArrayElementType.ConvertToClrType(x, targetClrType.GetElementType(), options, topLevel: false)))
                    {
                        newArray.SetValue(obj, i);
                        i++;
                    }
                    return(newArray);

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }
            if (targetClrType == typeof(SpannerNumeric))
            {
                if (TypeCode != TypeCode.Numeric)
                {
                    throw new ArgumentException($"{targetClrType.FullName} can only be used for numeric results");
                }
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.StringValue:
                    return(SpannerNumeric.Parse(wireValue.StringValue));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }
            if (typeof(IList).IsAssignableFrom(targetClrType))
            {
                if (targetClrType == typeof(IList))
                {
                    targetClrType = typeof(List <object>);
                }
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue: return(null);

                case Value.KindOneofCase.ListValue:
                    var newList  = (IList)Activator.CreateInstance(targetClrType);
                    var itemType = targetClrType.GetGenericArguments().FirstOrDefault() ?? typeof(object);
                    foreach (var obj in wireValue.ListValue.Values.Select(
                                 x => ArrayElementType.ConvertToClrType(x, itemType, options, topLevel: false)))
                    {
                        newList.Add(obj);
                    }
                    return(newList);

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }
            throw new ArgumentException(
                      $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
        }
Exemplo n.º 11
0
        // Note: the options can *currently* be null because we're not using them, but
        // every call site should check that it could provide options if they become required.
        internal Value ToProtobufValue(object value, SpannerConversionOptions options)
        {
            if (value == null || value is DBNull)
            {
                return(Value.ForNull());
            }

            // If we add any other special values, we can create an interface to delegate to instead.
            if (value is CommitTimestamp ts)
            {
                return(ts.ToProtobufValue(this));
            }

            switch (TypeCode)
            {
            case TypeCode.Bytes:
                if (value is string s)
                {
                    return(new Value {
                        StringValue = s
                    });
                }
                if (value is byte[] bArray)
                {
                    return(new Value {
                        StringValue = Convert.ToBase64String(bArray)
                    });
                }
                throw new ArgumentException("TypeCode.Bytes only supports string and byte[]", nameof(value));

            case TypeCode.Bool:
                return(new Value {
                    BoolValue = Convert.ToBoolean(value)
                });

            case TypeCode.String:
                if (value is DateTime dateTime)
                {
                    // If the value is a DateTime, we always convert using XmlConvert.
                    // This allows us to convert back to a datetime reliably from the
                    // resulting string (so roundtrip works properly if the developer uses
                    // a string as a backing field for a datetime for whatever reason).
                    return(new Value {
                        StringValue = XmlConvert.ToString(dateTime, XmlDateTimeSerializationMode.Utc)
                    });
                }
                // All the other conversions will fail naturally, but let's make sure we don't convert structs
                // to strings.
                if (value is SpannerStruct)
                {
                    throw new ArgumentException("SpannerStruct cannot be used for string parameters", nameof(value));
                }
                return(new Value {
                    StringValue = Convert.ToString(value, InvariantCulture)
                });

            case TypeCode.Int64:
                return(new Value {
                    StringValue = Convert.ToInt64(value, InvariantCulture)
                                  .ToString(InvariantCulture)
                });

            case TypeCode.Float64:
                return(new Value {
                    NumberValue = Convert.ToDouble(value, InvariantCulture)
                });

            case TypeCode.Timestamp:
                return(new Value
                {
                    StringValue = XmlConvert.ToString(Convert.ToDateTime(value, InvariantCulture), XmlDateTimeSerializationMode.Utc)
                });

            case TypeCode.Date:
                return(new Value
                {
                    StringValue = StripTimePart(
                        XmlConvert.ToString(Convert.ToDateTime(value, InvariantCulture), XmlDateTimeSerializationMode.Utc))
                });

            case TypeCode.Array:
                if (value is IEnumerable enumerable)
                {
                    return(Value.ForList(
                               enumerable.Cast <object>()
                               .Select(x => ArrayElementType.ToProtobufValue(x, options)).ToArray()));
                }
                throw new ArgumentException("The given array instance needs to implement IEnumerable.");

            case TypeCode.Struct:
                if (value is SpannerStruct spannerStruct)
                {
                    return(new Value
                    {
                        ListValue = new ListValue
                        {
                            Values = { spannerStruct.Select(f => f.Type.ToProtobufValue(f.Value, options)) }
                        }
                    });
                }
                throw new ArgumentException("Struct parameters must be of type SpannerStruct");

            case TypeCode.Numeric:
                if (value is SpannerNumeric spannerNumeric)
                {
                    return(Value.ForString(spannerNumeric.ToString()));
                }
                if (value is string str)
                {
                    return(Value.ForString(SpannerNumeric.Parse(str).ToString()));
                }
                if (value is float || value is double || value is decimal)
                {
                    // We throw if there's a loss of precision. We could use
                    // LossOfPrecisionHandling.Truncate but GoogleSQL documentation requests to
                    // use half-away-from-zero rounding but the SpannerNumeric implementation
                    // truncates instead.
                    return(Value.ForString(SpannerNumeric.FromDecimal(
                                               Convert.ToDecimal(value, InvariantCulture), LossOfPrecisionHandling.Throw).ToString()));
                }
                if (value is sbyte || value is short || value is int || value is long)
                {
                    SpannerNumeric numericValue = Convert.ToInt64(value, InvariantCulture);
                    return(Value.ForString(numericValue.ToString()));
                }
                if (value is byte || value is ushort || value is uint || value is ulong)
                {
                    SpannerNumeric numericValue = Convert.ToUInt64(value, InvariantCulture);
                    return(Value.ForString(numericValue.ToString()));
                }
                throw new ArgumentException("Numeric parameters must be of type SpannerNumeric or string");

            default:
                throw new ArgumentOutOfRangeException(nameof(TypeCode), TypeCode, null);
            }
        }
Exemplo n.º 12
0
        private object ConvertToClrTypeImpl(Value wireValue, System.Type targetClrType)
        {
            //If the wireValue itself is assignable to the target type, just return it
            //This covers both typeof(Value) and typeof(object).
            if (wireValue == null || targetClrType == null || targetClrType == typeof(Value))
            {
                return(wireValue);
            }

            //targetClrType should be one of the values returned by GetDefaultClrTypeFromSpannerType
            if (targetClrType == typeof(bool))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(default(bool));

                case Value.KindOneofCase.StringValue:
                    if (TypeCode == TypeCode.Int64)
                    {
                        return(Convert.ToBoolean(Convert.ToInt64(wireValue.StringValue, InvariantCulture)));
                    }
                    return(Convert.ToBoolean(wireValue.StringValue));

                case Value.KindOneofCase.BoolValue:
                    return(wireValue.BoolValue);

                case Value.KindOneofCase.NumberValue:
                    return(Convert.ToBoolean(wireValue.NumberValue));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(char))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.BoolValue:
                    return(Convert.ToChar(wireValue.BoolValue));

                case Value.KindOneofCase.NumberValue:
                    return(Convert.ToChar(wireValue.NumberValue));

                case Value.KindOneofCase.NullValue:
                    return(default(char));

                case Value.KindOneofCase.StringValue:
                    if (TypeCode == TypeCode.Int64)
                    {
                        return(Convert.ToChar(Convert.ToInt64(wireValue.StringValue, InvariantCulture)));
                    }
                    return(Convert.ToChar(wireValue.StringValue));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(long))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.BoolValue:
                    return(Convert.ToInt64(wireValue.BoolValue));

                case Value.KindOneofCase.NumberValue:
                    return(Convert.ToInt64(wireValue.NumberValue));

                case Value.KindOneofCase.NullValue:
                    return(default(long));

                case Value.KindOneofCase.StringValue:
                    return(Convert.ToInt64(wireValue.StringValue, InvariantCulture));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(ulong))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.BoolValue:
                    return(Convert.ToUInt64(wireValue.BoolValue));

                case Value.KindOneofCase.NumberValue:
                    return(Convert.ToUInt64(wireValue.NumberValue));

                case Value.KindOneofCase.NullValue:
                    return(default(ulong));

                case Value.KindOneofCase.StringValue:
                    return(Convert.ToUInt64(wireValue.StringValue, InvariantCulture));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(decimal))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.BoolValue:
                    return(Convert.ToDecimal(wireValue.BoolValue));

                case Value.KindOneofCase.NumberValue:
                    return(Convert.ToDecimal(wireValue.NumberValue));

                case Value.KindOneofCase.NullValue:
                    return(default(decimal));

                case Value.KindOneofCase.StringValue:
                    return(Convert.ToDecimal(wireValue.StringValue, InvariantCulture));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(double))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.BoolValue:
                    return(Convert.ToDouble(wireValue.BoolValue));

                case Value.KindOneofCase.NullValue:
                    return(default(double));

                case Value.KindOneofCase.NumberValue:
                    return(wireValue.NumberValue);

                case Value.KindOneofCase.StringValue:
                    if (string.Compare(wireValue.StringValue, "NaN", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return(double.NaN);
                    }

                    if (string.Compare(wireValue.StringValue, "Infinity", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return(double.PositiveInfinity);
                    }

                    if (string.Compare(wireValue.StringValue, "-Infinity", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return(double.NegativeInfinity);
                    }

                    return(Convert.ToDouble(wireValue.StringValue, InvariantCulture));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(DateTime))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.StringValue:
                    return(XmlConvert.ToDateTime(wireValue.StringValue, XmlDateTimeSerializationMode.Utc));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(Timestamp))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.StringValue:
                    return(Protobuf.WellKnownTypes.Timestamp.Parser.ParseJson(wireValue.StringValue));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(string))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.NumberValue:
                    return(wireValue.NumberValue.ToString(InvariantCulture));

                case Value.KindOneofCase.StringValue:
                    return(wireValue.StringValue);

                case Value.KindOneofCase.BoolValue:
                    return(wireValue.BoolValue.ToString());

                default:
                    return(wireValue.ToString());
                }
            }

            if (targetClrType == typeof(byte[]))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.StringValue:
                    return(Convert.FromBase64String(wireValue.StringValue));

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            if (typeof(IDictionary).IsAssignableFrom(targetClrType))
            {
                if (targetClrType == typeof(IDictionary))
                {
#pragma warning disable DE0006
                    targetClrType = typeof(Hashtable);
#pragma warning restore DE0006
                }
                //a bit of recursion here...
                IDictionary dictionary = (IDictionary)Activator.CreateInstance(targetClrType);
                var         itemType   = targetClrType.GetGenericArguments().Skip(1).FirstOrDefault() ?? typeof(object);
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.StructValue:
                    foreach (var structField in StructMembers)
                    {
                        dictionary[structField.Key] = structField.Value.ConvertToClrType(
                            wireValue.StructValue.Fields[structField.Key], itemType);
                    }

                    return(dictionary);

                case Value.KindOneofCase.ListValue:
                    if (TypeCode == TypeCode.Struct)
                    {
                        for (var i = 0; i < StructOrder?.Count; i++)
                        {
                            dictionary[StructOrder[i]] =
                                StructMembers[StructOrder[i]].ConvertToClrType(wireValue
                                                                               .ListValue.Values[i], itemType);
                        }
                    }
                    else
                    {
                        var i = 0;
                        foreach (var listItemValue in wireValue.ListValue.Values)
                        {
                            dictionary[i] = ArrayElementType.ConvertToClrType(listItemValue, itemType);
                            i++;
                        }
                    }
                    return(dictionary);

                default:
                    throw new ArgumentException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }
            if (targetClrType.IsArray)
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue: return(null);

                case Value.KindOneofCase.ListValue:
                    var newArray = Array.CreateInstance(
                        targetClrType.GetElementType(),
                        wireValue.ListValue.Values.Count);

                    var i = 0;
                    foreach (var obj in wireValue.ListValue.Values.Select(
                                 x => ArrayElementType.ConvertToClrType(x, targetClrType.GetElementType())))
                    {
                        newArray.SetValue(obj, i);
                        i++;
                    }
                    return(newArray);

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }
            if (typeof(IList).IsAssignableFrom(targetClrType))
            {
                if (targetClrType == typeof(IList))
                {
                    targetClrType = typeof(List <object>);
                }
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue: return(null);

                case Value.KindOneofCase.ListValue:
                    var newList  = (IList)Activator.CreateInstance(targetClrType);
                    var itemType = targetClrType.GetGenericArguments().FirstOrDefault() ?? typeof(object);
                    foreach (var obj in wireValue.ListValue.Values.Select(
                                 x => ArrayElementType.ConvertToClrType(x, itemType)))
                    {
                        newList.Add(obj);
                    }
                    return(newList);

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }
            throw new ArgumentException(
                      $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
        }
Exemplo n.º 13
0
        internal Value ToProtobufValue(object value)
        {
            if (value == null || value is DBNull)
            {
                return(Value.ForNull());
            }

            switch (TypeCode)
            {
            case TypeCode.Bytes:
                if (value is string s)
                {
                    return(new Value {
                        StringValue = s
                    });
                }
                if (value is byte[] bArray)
                {
                    return(new Value {
                        StringValue = Convert.ToBase64String(bArray)
                    });
                }
                throw new ArgumentException("TypeCode.Bytes only supports string and byte[]", nameof(value));

            case TypeCode.Bool:
                return(new Value {
                    BoolValue = Convert.ToBoolean(value)
                });

            case TypeCode.String:
                if (value is DateTime dateTime)
                {
                    // If the value is a DateTime, we always convert using XmlConvert.
                    // This allows us to convert back to a datetime reliably from the
                    // resulting string (so roundtrip works properly if the developer uses
                    // a string as a backing field for a datetime for whatever reason).
                    return(new Value {
                        StringValue = XmlConvert.ToString(dateTime, XmlDateTimeSerializationMode.Utc)
                    });
                }
                return(new Value {
                    StringValue = Convert.ToString(value, InvariantCulture)
                });

            case TypeCode.Int64:
                return(new Value {
                    StringValue = Convert.ToInt64(value, InvariantCulture)
                                  .ToString(InvariantCulture)
                });

            case TypeCode.Float64:
                return(new Value {
                    NumberValue = Convert.ToDouble(value, InvariantCulture)
                });

            case TypeCode.Timestamp:
                return(new Value
                {
                    StringValue = XmlConvert.ToString(Convert.ToDateTime(value, InvariantCulture), XmlDateTimeSerializationMode.Utc)
                });

            case TypeCode.Date:
                return(new Value
                {
                    StringValue = StripTimePart(
                        XmlConvert.ToString(Convert.ToDateTime(value, InvariantCulture), XmlDateTimeSerializationMode.Utc))
                });

            case TypeCode.Array:
                if (value is IEnumerable enumerable)
                {
                    return(Value.ForList(
                               enumerable.Cast <object>()
                               .Select(x => ArrayElementType.ToProtobufValue(x)).ToArray()));
                }
                throw new ArgumentException("The given array instance needs to implement IEnumerable.");

            case TypeCode.Struct:
                if (value is IDictionary dictionary)
                {
                    var structValue = new Struct();
                    foreach (var key in dictionary.Keys)
                    {
                        string keyString = Convert.ToString(key, InvariantCulture);
                        if (!StructMembers.ContainsKey(keyString))
                        {
                            throw new ArgumentException("The given struct instance has members not defined in the Struct.", nameof(value));
                        }
                        structValue.Fields[keyString] = StructMembers[keyString].ToProtobufValue(
                            dictionary[key]);
                    }
                    return(Value.ForStruct(structValue));
                }
                throw new ArgumentException("The given struct instance needs to implement IDictionary.");

            default:
                throw new ArgumentOutOfRangeException(nameof(TypeCode), TypeCode, null);
            }
        }
Exemplo n.º 14
0
        public void Generate(CodeGenerator generator)
        {
            generator.EnterElement(this);

            if (ArrayElementType != null)
            {
                ArrayElementType.Generate(generator);
                generator.Write(TokenType.Punctuation, ArraySuffix);
                generator.ExitElement();
                return;
            }

            var name = RawName;

            if (SimplifiedBuiltinTypeNames.TryGetValue(name, out var simplifiedBuiltinTypeName))
            {
                generator.Write(TokenType.Keyword, simplifiedBuiltinTypeName);
                generator.ExitElement();
                return;
            }

            if (name == "var")
            {
                generator.Write(TokenType.Keyword, name);
                generator.ExitElement();
                return;
            }

            if (Global)
            {
                generator.Write(TokenType.Keyword, "global");
                generator.Write(TokenType.Punctuation, "::");
            }

            var nameBuilder         = new StringBuilder();
            var namespaceNameLength = 0;

            {
                var previousIndex = 0;

                for (var i = 0; i < name.Length; i++)
                {
                    var c = name[i];
                    if (c == '.')
                    {
                        nameBuilder.Append(name.Substring(previousIndex, i - previousIndex).EscapeIdentifier());
                        namespaceNameLength = nameBuilder.Length;
                        nameBuilder.Append('.');
                        previousIndex = i + 1;
                    }
                    else if (c == '+')
                    {
                        nameBuilder.Append(name.Substring(previousIndex, i - previousIndex).EscapeIdentifier()).Append('.');
                        previousIndex = i + 1;
                    }
                }

                nameBuilder.Append(previousIndex > 0 ? name.Substring(previousIndex).EscapeIdentifier() : name.EscapeUnqualifiedTypeIdentifier());
            }

            if (namespaceNameLength > 0)
            {
                var namespaceRef = new CodeUsingImport(nameBuilder.ToString(0, namespaceNameLength));

                var usingSets = generator.UsingSets;

                foreach (var usingSet in usingSets)
                {
                    if (usingSet.Contains(namespaceRef))
                    {
                        var ambiguityDetected            = false;
                        var unqualifiedTypeName          = nameBuilder.ToString(namespaceNameLength + 1, nameBuilder.Length - namespaceNameLength - 1);
                        var unqualifiedTypeNameWithArity = unqualifiedTypeName + (TypeArguments != null && TypeArguments.Count != 0 ? "`" + TypeArguments.Count : "");

                        if (TypesByNames.TryGetValue(unqualifiedTypeNameWithArity, out var types))
                        {
                            foreach (var type in types)
                            {
                                var otherNamespaceRef = new CodeUsingImport(type.NamespaceName);

                                if (namespaceRef != otherNamespaceRef)
                                {
                                    foreach (var otherUsingSet in usingSets)
                                    {
                                        if (otherUsingSet.Contains(otherNamespaceRef))
                                        {
                                            ambiguityDetected = true;
                                            break;
                                        }
                                    }
                                }

                                if (ambiguityDetected)
                                {
                                    break;
                                }
                            }
                        }

                        ambiguityDetected = ambiguityDetected || generator.Options.PredeclaredTypes.Where(type => type.NamespaceName != namespaceRef.Name && type.TypeName == unqualifiedTypeNameWithArity).Any();

                        if (!ambiguityDetected)
                        {
                            nameBuilder.Length = 0;
                            nameBuilder.Append(unqualifiedTypeName);
                        }

                        break;
                    }
                }
            }

            {
                var previousIndex = 0;

                var typeArgumentStart = 0;

                for (var characterIndex = 0; characterIndex < nameBuilder.Length;)
                {
                    if (nameBuilder[characterIndex] == '`')
                    {
                        generator.OutputQualifiedName(TokenType.TypeIdentifier, nameBuilder, previousIndex, characterIndex);

                        characterIndex++;

                        var arity = 0;

                        while (characterIndex < nameBuilder.Length && '0' <= nameBuilder[characterIndex] && nameBuilder[characterIndex] <= '9')
                        {
                            arity = arity * 10 + (nameBuilder[characterIndex] - '0');
                            characterIndex++;
                        }

                        previousIndex = characterIndex;

                        generator.Write(TokenType.Punctuation, '<');

                        var first = true;

                        for (var typeArgumentIndex = typeArgumentStart; typeArgumentIndex < typeArgumentStart + arity; typeArgumentIndex++)
                        {
                            var typeArgument = TypeArguments[typeArgumentIndex];

                            if (first)
                            {
                                first = false;
                            }
                            else
                            {
                                generator.Write(TokenType.Punctuation, ',');
                                if (typeArgument != null)
                                {
                                    generator.Write(TokenType.Space, ' ');
                                }
                            }

                            if (typeArgument != null)
                            {
                                typeArgument.Generate(generator);
                            }
                        }

                        typeArgumentStart += arity;

                        generator.Write(TokenType.Punctuation, '>');
                    }
                    else
                    {
                        characterIndex++;
                    }
                }

                if (previousIndex < nameBuilder.Length)
                {
                    generator.OutputQualifiedName(TokenType.TypeIdentifier, nameBuilder, previousIndex);
                }
            }

            generator.ExitElement();
        }