diff --git a/src/LanguageServer/Protocol/Microsoft.CodeAnalysis.LanguageServer.Protocol.csproj b/src/LanguageServer/Protocol/Microsoft.CodeAnalysis.LanguageServer.Protocol.csproj index d7404811a27fc..c85748a90fe20 100644 --- a/src/LanguageServer/Protocol/Microsoft.CodeAnalysis.LanguageServer.Protocol.csproj +++ b/src/LanguageServer/Protocol/Microsoft.CodeAnalysis.LanguageServer.Protocol.csproj @@ -38,6 +38,7 @@ + diff --git a/src/Tools/ExternalAccess/Razor/Remote/JsonSerializableDocumentId.cs b/src/Tools/ExternalAccess/Razor/Remote/JsonSerializableDocumentId.cs new file mode 100644 index 0000000000000..7ba6d956d9f4e --- /dev/null +++ b/src/Tools/ExternalAccess/Razor/Remote/JsonSerializableDocumentId.cs @@ -0,0 +1,27 @@ +// 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.Text.Json.Serialization; + +namespace Microsoft.CodeAnalysis.ExternalAccess.Razor +{ + /// + /// Represents a DocumentId that can be used by Razor for OOP services that communicate via System.Text.Json + /// + internal readonly record struct JsonSerializableDocumentId( + [property: JsonPropertyName("projectId")] Guid ProjectId, + [property: JsonPropertyName("id")] Guid Id) + { + public static implicit operator JsonSerializableDocumentId(DocumentId documentId) + { + return new JsonSerializableDocumentId(documentId.ProjectId.Id, documentId.Id); + } + + public static implicit operator DocumentId(JsonSerializableDocumentId serializableDocumentId) + { + return DocumentId.CreateFromSerialized(CodeAnalysis.ProjectId.CreateFromSerialized(serializableDocumentId.ProjectId), serializableDocumentId.Id); + } + } +} diff --git a/src/Tools/ExternalAccess/Razor/Remote/JsonSerializableRazorPinnedSolutionInfoWrapper.cs b/src/Tools/ExternalAccess/Razor/Remote/JsonSerializableRazorPinnedSolutionInfoWrapper.cs new file mode 100644 index 0000000000000..33c57d04c581b --- /dev/null +++ b/src/Tools/ExternalAccess/Razor/Remote/JsonSerializableRazorPinnedSolutionInfoWrapper.cs @@ -0,0 +1,27 @@ +// 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.Text.Json.Serialization; + +namespace Microsoft.CodeAnalysis.ExternalAccess.Razor +{ + /// + /// A wrapper for a solution that can be used by Razor for OOP services that communicate via System.Text.Json + /// + internal readonly record struct JsonSerializableRazorPinnedSolutionInfoWrapper( + [property: JsonPropertyName("data1")] long Data1, + [property: JsonPropertyName("data2")] long Data2) + { + public static implicit operator JsonSerializableRazorPinnedSolutionInfoWrapper(RazorPinnedSolutionInfoWrapper info) + { + return new JsonSerializableRazorPinnedSolutionInfoWrapper(info.UnderlyingObject.Data1, info.UnderlyingObject.Data2); + } + + public static implicit operator RazorPinnedSolutionInfoWrapper(JsonSerializableRazorPinnedSolutionInfoWrapper serializableDocumentId) + { + return new RazorPinnedSolutionInfoWrapper(new Checksum(serializableDocumentId.Data1, serializableDocumentId.Data2)); + } + } +} diff --git a/src/Tools/ExternalAccess/Razor/Remote/RazorPinnedSolutionInfoWrapper.cs b/src/Tools/ExternalAccess/Razor/Remote/RazorPinnedSolutionInfoWrapper.cs index e98a61d9448e7..eec9f59b0de71 100644 --- a/src/Tools/ExternalAccess/Razor/Remote/RazorPinnedSolutionInfoWrapper.cs +++ b/src/Tools/ExternalAccess/Razor/Remote/RazorPinnedSolutionInfoWrapper.cs @@ -3,10 +3,12 @@ // See the LICENSE file in the project root for more information. using System.Runtime.Serialization; -using Microsoft.CodeAnalysis.Remote; namespace Microsoft.CodeAnalysis.ExternalAccess.Razor { + /// + /// A wrapper for a solution that can be used by Razor for OOP services that communicate via MessagePack + /// [DataContract] internal readonly struct RazorPinnedSolutionInfoWrapper { diff --git a/src/Tools/ExternalAccess/Razor/Remote/RazorServiceDescriptorsWrapper.cs b/src/Tools/ExternalAccess/Razor/Remote/RazorServiceDescriptorsWrapper.cs index 3446e3fd31fc7..902e9645ab1bb 100644 --- a/src/Tools/ExternalAccess/Razor/Remote/RazorServiceDescriptorsWrapper.cs +++ b/src/Tools/ExternalAccess/Razor/Remote/RazorServiceDescriptorsWrapper.cs @@ -5,12 +5,13 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Runtime; +using System.Text.Json; +using System.Text.Json.Serialization; using MessagePack; using MessagePack.Formatters; +using Microsoft.CodeAnalysis.LanguageServer; using Microsoft.CodeAnalysis.Remote; using Microsoft.ServiceHub.Framework; -using Newtonsoft.Json; namespace Microsoft.CodeAnalysis.ExternalAccess.Razor { @@ -30,7 +31,7 @@ public RazorServiceDescriptorsWrapper( => UnderlyingObject = new ServiceDescriptors(componentName, featureDisplayNameProvider, new RemoteSerializationOptions(additionalFormatters, additionalResolvers), interfaces); /// - /// Creates a service descriptor set for services using JSON serialization. + /// Creates a service descriptor set for services using System.Text.Json serialization. /// public RazorServiceDescriptorsWrapper( string componentName, @@ -45,10 +46,11 @@ public RazorServiceDescriptorsWrapper( public ServiceJsonRpcDescriptor GetDescriptorForServiceFactory(Type serviceInterface) => UnderlyingObject.GetServiceDescriptorForServiceFactory(serviceInterface); - public MessagePackSerializerOptions MessagePackOptions - => UnderlyingObject.Options.MessagePackOptions; - - public ImmutableArray JsonConverters - => UnderlyingObject.Options.JsonConverters; + public static ImmutableArray GetLspConverters() + { + var options = new JsonSerializerOptions(); + ProtocolConversions.AddLspSerializerOptions(options); + return options.Converters.ToImmutableArray(); + } } } diff --git a/src/Workspaces/Remote/Core/RemoteSerializationOptions.cs b/src/Workspaces/Remote/Core/RemoteSerializationOptions.cs index df1a6c4360fac..24714062b5ed3 100644 --- a/src/Workspaces/Remote/Core/RemoteSerializationOptions.cs +++ b/src/Workspaces/Remote/Core/RemoteSerializationOptions.cs @@ -37,11 +37,21 @@ public RemoteSerializationOptions(ImmutableArray addition public RemoteSerializationOptions(ImmutableArray jsonConverters) => _options = jsonConverters; + public RemoteSerializationOptions(ImmutableArray jsonConverters) + => _options = jsonConverters; + public MessagePackSerializerOptions MessagePackOptions => (MessagePackSerializerOptions)_options; public ImmutableArray JsonConverters => (ImmutableArray)_options; + public ImmutableArray SystemTextJsonConverters => (ImmutableArray)_options; public ServiceJsonRpcDescriptor.Formatters Formatter - => _options is MessagePackSerializerOptions ? ServiceJsonRpcDescriptor.Formatters.MessagePack : ServiceJsonRpcDescriptor.Formatters.UTF8; + => _options switch + { + MessagePackSerializerOptions => ServiceJsonRpcDescriptor.Formatters.MessagePack, + ImmutableArray => ServiceJsonRpcDescriptor.Formatters.UTF8, + ImmutableArray => ServiceJsonRpcDescriptor.Formatters.UTF8SystemTextJson, + _ => throw new InvalidOperationException() + }; public ServiceJsonRpcDescriptor.MessageDelimiters MessageDelimiters => _options is MessagePackSerializerOptions @@ -58,6 +68,15 @@ internal IJsonRpcMessageFormatter ConfigureFormatter(IJsonRpcMessageFormatter fo // See https://github.com/neuecc/messagepack-csharp. messagePackFormatter.SetMessagePackSerializerOptions(MessagePackOptions); } + else if (formatter is SystemTextJsonFormatter stjFormatter) + { + var converters = stjFormatter.JsonSerializerOptions.Converters; + + foreach (var converter in SystemTextJsonConverters) + { + converters.Add(converter); + } + } else { var converters = ((JsonMessageFormatter)formatter).JsonSerializer.Converters;