예제 #1
0
        public override TMessage?Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var message = new TMessage();

            JsonConverterHelper.PopulateList(ref reader, options, message, message.Descriptor.Fields[ListValue.ValuesFieldNumber]);

            return(message);
        }
예제 #2
0
        public override TMessage?Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var message         = new TMessage();
            var valueDescriptor = message.Descriptor.Fields[JsonConverterHelper.WrapperValueFieldNumber];
            var t     = JsonConverterHelper.GetFieldType(valueDescriptor);
            var value = JsonSerializer.Deserialize(ref reader, t, options);

            valueDescriptor.Accessor.SetValue(message, value);

            return(message);
        }
예제 #3
0
        public override TMessage Read(
            ref Utf8JsonReader reader,
            Type typeToConvert,
            JsonSerializerOptions options)
        {
            var message = new TMessage();

            if (reader.TokenType != JsonTokenType.StartObject)
            {
                throw new InvalidOperationException($"Unexpected JSON token: {reader.TokenType}");
            }

            while (reader.Read())
            {
                switch (reader.TokenType)
                {
                case JsonTokenType.EndObject:
                    return(message);

                case JsonTokenType.PropertyName:
                    if (_jsonFieldMap.TryGetValue(reader.GetString() !, out var fieldDescriptor))
                    {
                        if (fieldDescriptor.ContainingOneof != null)
                        {
                            if (fieldDescriptor.ContainingOneof.Accessor.GetCaseFieldDescriptor(message) != null)
                            {
                                throw new InvalidOperationException($"Multiple values specified for oneof {fieldDescriptor.ContainingOneof.Name}");
                            }
                        }

                        if (fieldDescriptor.IsMap)
                        {
                            JsonConverterHelper.PopulateMap(ref reader, options, message, fieldDescriptor);
                        }
                        else if (fieldDescriptor.IsRepeated)
                        {
                            JsonConverterHelper.PopulateList(ref reader, options, message, fieldDescriptor);
                        }
                        else
                        {
                            var fieldType     = JsonConverterHelper.GetFieldType(fieldDescriptor);
                            var propertyValue = JsonSerializer.Deserialize(ref reader, fieldType, options);
                            fieldDescriptor.Accessor.SetValue(message, propertyValue);
                        }
                    }
                    else
                    {
                        reader.Skip();
                    }
                    break;
예제 #4
0
        public override JsonConverter CreateConverter(
            Type typeToConvert, JsonSerializerOptions options)
        {
            var descriptor    = JsonConverterHelper.GetMessageDescriptor(typeToConvert) !;
            var converterType = WellKnownTypeNames[descriptor.FullName];

            var converter = (JsonConverter)Activator.CreateInstance(
                converterType.MakeGenericType(new Type[] { typeToConvert }),
                BindingFlags.Instance | BindingFlags.Public,
                binder: null,
                args: new object[] { _settings },
                culture: null) !;

            return(converter);
        }
예제 #5
0
        public override bool CanConvert(Type typeToConvert)
        {
            if (!typeof(IMessage).IsAssignableFrom(typeToConvert))
            {
                return(false);
            }

            var descriptor = JsonConverterHelper.GetMessageDescriptor(typeToConvert);

            if (descriptor == null)
            {
                return(false);
            }

            return(JsonConverterHelper.IsWrapperType(descriptor));
        }
예제 #6
0
        public override bool CanConvert(Type typeToConvert)
        {
            if (!typeof(IMessage).IsAssignableFrom(typeToConvert))
            {
                return(false);
            }

            var descriptor = JsonConverterHelper.GetMessageDescriptor(typeToConvert);

            if (descriptor == null)
            {
                return(false);
            }

            return(WellKnownTypeNames.ContainsKey(descriptor.FullName));
        }
예제 #7
0
        private static EnumDescriptor?ResolveEnumDescriptor(Type typeToConvert)
        {
            var containingType = typeToConvert?.DeclaringType?.DeclaringType;

            if (containingType != null)
            {
                var messageDescriptor = JsonConverterHelper.GetMessageDescriptor(containingType);
                if (messageDescriptor != null)
                {
                    for (var i = 0; i < messageDescriptor.EnumTypes.Count; i++)
                    {
                        if (messageDescriptor.EnumTypes[i].ClrType == typeToConvert)
                        {
                            return(messageDescriptor.EnumTypes[i]);
                        }
                    }
                }
            }

            return(null);
        }
예제 #8
0
        public override TMessage?Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            using var d = JsonDocument.ParseValue(ref reader);
            if (!d.RootElement.TryGetProperty(AnyTypeUrlField, out var urlField))
            {
                throw new InvalidOperationException("Any message with no @type");
            }

            var message  = new TMessage();
            var typeUrl  = urlField.GetString();
            var typeName = Any.GetTypeName(typeUrl);

            var descriptor = _settings.TypeRegistry.Find(typeName);

            if (descriptor == null)
            {
                throw new InvalidOperationException($"Type registry has no descriptor for type name '{typeName}'");
            }

            IMessage data;

            if (JsonConverterHelper.IsWellKnownType(descriptor))
            {
                if (!d.RootElement.TryGetProperty(AnyWellKnownTypeValueField, out var valueField))
                {
                    throw new InvalidOperationException($"Expected '{AnyWellKnownTypeValueField}' property for well-known type Any body");
                }

                data = (IMessage)JsonSerializer.Deserialize(valueField, descriptor.ClrType, options) !;
            }
            else
            {
                data = (IMessage)JsonSerializer.Deserialize(d.RootElement, descriptor.ClrType, options) !;
            }

            message.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.SetValue(message, typeUrl);
            message.Descriptor.Fields[Any.ValueFieldNumber].Accessor.SetValue(message, data.ToByteString());

            return(message);
        }
예제 #9
0
        public override void Write(Utf8JsonWriter writer, TMessage value, JsonSerializerOptions options)
        {
            var typeUrl    = (string)value.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.GetValue(value);
            var data       = (ByteString)value.Descriptor.Fields[Any.ValueFieldNumber].Accessor.GetValue(value);
            var typeName   = Any.GetTypeName(typeUrl);
            var descriptor = _settings.TypeRegistry.Find(typeName);

            if (descriptor == null)
            {
                throw new InvalidOperationException($"Type registry has no descriptor for type name '{typeName}'");
            }
            var valueMessage = descriptor.Parser.ParseFrom(data);

            writer.WriteStartObject();
            writer.WriteString(AnyTypeUrlField, typeUrl);

            if (JsonConverterHelper.IsWellKnownType(descriptor))
            {
                writer.WritePropertyName(AnyWellKnownTypeValueField);
                if (JsonConverterHelper.IsWrapperType(descriptor))
                {
                    var wrappedValue = valueMessage.Descriptor.Fields[JsonConverterHelper.WrapperValueFieldNumber].Accessor.GetValue(valueMessage);
                    JsonSerializer.Serialize(writer, wrappedValue, wrappedValue.GetType(), options);
                }
                else
                {
                    JsonSerializer.Serialize(writer, valueMessage, valueMessage.GetType(), options);
                }
            }
            else
            {
                MessageConverter <Any> .WriteMessageFields(writer, valueMessage, _settings, options);
            }

            writer.WriteEndObject();
        }