private protected async ValueTask DeserializeMessageAsync()

in src/StreamJsonRpc/PipeMessageHandler.cs [222:285]


        private protected async ValueTask<JsonRpcMessage> DeserializeMessageAsync(int contentLength, Encoding? specificEncoding, Encoding? defaultEncoding, CancellationToken cancellationToken)
        {
            Requires.Range(contentLength > 0, nameof(contentLength));
            Assumes.NotNull(this.Reader);
            Assumes.Null(this.deserializationReservedBuffer.Message); // Previous message holds buffers must have been released by now.
            Encoding? contentEncoding = specificEncoding ?? defaultEncoding;

            // Being async during deserialization increases GC pressure,
            // so prefer getting all bytes into a buffer first if the message is a reasonably small size.
            if (contentLength >= LargeMessageThreshold && this.Formatter is IJsonRpcAsyncMessageFormatter asyncFormatter)
            {
                PipeReader slice = this.Reader.ReadSlice(contentLength);
                if (contentEncoding is not null && asyncFormatter is IJsonRpcAsyncMessageTextFormatter asyncTextFormatter)
                {
                    return await asyncTextFormatter.DeserializeAsync(slice, contentEncoding, cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    if (specificEncoding is not null)
                    {
                        this.ThrowNoTextEncoder();
                    }

                    return await asyncFormatter.DeserializeAsync(slice, cancellationToken).ConfigureAwait(false);
                }
            }
            else
            {
                ReadResult readResult = await this.ReadAtLeastAsync(contentLength, allowEmpty: false, cancellationToken).ConfigureAwait(false);
                ReadOnlySequence<byte> contentBuffer = readResult.Buffer.Slice(0, contentLength);
                try
                {
                    JsonRpcMessage message;
                    if (contentEncoding is not null && this.Formatter is IJsonRpcMessageTextFormatter textFormatter)
                    {
                        message = textFormatter.Deserialize(contentBuffer, contentEncoding);
                    }
                    else
                    {
                        if (specificEncoding is not null)
                        {
                            this.ThrowNoTextEncoder();
                        }

                        message = this.Formatter.Deserialize(contentBuffer);
                    }

                    if (message is IJsonRpcMessageBufferManager bufferedMessage)
                    {
                        this.deserializationReservedBuffer = (bufferedMessage, contentBuffer.End);
                    }

                    return message;
                }
                finally
                {
                    if (this.deserializationReservedBuffer.Message is null)
                    {
                        // We're now done reading from the pipe's buffer. We can release it now.
                        this.Reader.AdvanceTo(contentBuffer.End);
                    }
                }
            }
        }