public async Task WriteInvocationDescriptorAsync(InvocationDescriptor invocationDescriptor, Stream stream)
        {
            var outputStream = new CodedOutputStream(stream, leaveOpen: true);

            outputStream.WriteMessage(new RpcMessageKind()
            {
                MessageKind = RpcMessageKind.Types.Kind.Invocation
            });

            var invocationHeader = new RpcInvocationHeader()
            {
                Id      = 0,
                Name    = invocationDescriptor.Method,
                NumArgs = invocationDescriptor.Arguments.Length
            };

            outputStream.WriteMessage(invocationHeader);

            foreach (var arg in invocationDescriptor.Arguments)
            {
                if (arg.GetType() == typeof(int))
                {
                    outputStream.WriteMessage(new PrimitiveValue {
                        Int32Value = (int)arg
                    });
                }
                else if (arg.GetType() == typeof(string))
                {
                    outputStream.WriteMessage(new PrimitiveValue {
                        StringValue = (string)arg
                    });
                }
                else
                {
                    var serializer = _serviceProvider.GetRequiredService <ProtobufSerializer>();
                    var message    = serializer.GetMessage(arg);
                    outputStream.WriteMessage(message);
                }
            }

            outputStream.Flush();
            await stream.FlushAsync();
        }
        private Task <InvocationDescriptor> CreateInvocationDescriptorInt(Stream stream, Func <string, Type[]> getParams)
        {
            var inputStream      = new CodedInputStream(stream, leaveOpen: true);
            var invocationHeader = new RpcInvocationHeader();

            inputStream.ReadMessage(invocationHeader);
            var argumentTypes = getParams(invocationHeader.Name);

            var invocationDescriptor = new InvocationDescriptor();

            invocationDescriptor.Method    = invocationHeader.Name;
            invocationDescriptor.Id        = invocationHeader.Id.ToString();
            invocationDescriptor.Arguments = new object[argumentTypes.Length];

            var primitiveParser = PrimitiveValue.Parser;

            for (var i = 0; i < argumentTypes.Length; i++)
            {
                if (typeof(int) == argumentTypes[i])
                {
                    var value = new PrimitiveValue();
                    inputStream.ReadMessage(value);
                    invocationDescriptor.Arguments[i] = value.Int32Value;
                }
                else if (typeof(string) == argumentTypes[i])
                {
                    var value = new PrimitiveValue();
                    inputStream.ReadMessage(value);
                    invocationDescriptor.Arguments[i] = value.StringValue;
                }
                else
                {
                    var serializer = _serviceProvider.GetRequiredService <ProtobufSerializer>();
                    invocationDescriptor.Arguments[i] = serializer.GetValue(inputStream, argumentTypes[i]);
                }
            }

            return(Task.FromResult(invocationDescriptor));
        }