File: Protocol\Converters\NaturalObjectConverter.cs
Web Access
Project: src\src\LanguageServer\Protocol\Microsoft.CodeAnalysis.LanguageServer.Protocol.csproj (Microsoft.CodeAnalysis.LanguageServer.Protocol)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
 
namespace Roslyn.LanguageServer.Protocol;
 
// copied from https://github.com/dotnet/runtime/issues/98038 to match newtonsoft behavior
internal class NaturalObjectConverter : JsonConverter<object>
{
    public override object? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        => ReadObjectCore(ref reader);
 
    public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
    {
        var runtimeType = value.GetType();
        if (runtimeType == typeof(object))
        {
            writer.WriteStartObject();
            writer.WriteEndObject();
        }
        else
        {
            JsonSerializer.Serialize(writer, value, runtimeType, options);
        }
    }
 
    private static object? ReadObjectCore(ref Utf8JsonReader reader)
    {
        switch (reader.TokenType)
        {
            case JsonTokenType.Null:
                return null;
 
            case JsonTokenType.False or JsonTokenType.True:
                return reader.GetBoolean();
 
            case JsonTokenType.Number:
                if (reader.TryGetInt32(out var intValue))
                {
                    return intValue;
                }
                if (reader.TryGetInt64(out var longValue))
                {
                    return longValue;
                }
 
                return reader.GetDouble();
 
            case JsonTokenType.String:
                return reader.GetString();
 
            case JsonTokenType.StartArray:
                var list = new List<object?>();
                while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
                {
                    var element = ReadObjectCore(ref reader);
                    list.Add(element);
                }
                return list;
 
            case JsonTokenType.StartObject:
                return JsonSerializer.Deserialize<JsonElement>(ref reader);
 
            default:
                throw new JsonException();
        }
    }
}