Exemplo n.º 1
0
        /// <summary>
        /// This is the main loop of the wrapper, which listens for messages from the VS extension and
        /// responds to them.
        /// </summary>
        public void ProcessMessageLoop()
        {
            // This will hold the length of incoming messages on the pipe
            byte[] sizeBuffer = new byte[sizeof(int)];

            // This is going to hold the signature string sent from the extension. 64k would be a ridiculously
            // big signature, so this is a fine default; if it ever got bigger than this, it's more likely that
            // something went wrong on the extension's side.
            byte[] messageBuffer = new byte[ushort.MaxValue];

            while (Stream.IsConnected)
            {
                // Get the size of the incoming message
                if (!ReadFromPipe(sizeBuffer, sizeBuffer.Length))
                {
                    continue;
                }
                int messageLength = BitConverter.ToInt32(sizeBuffer);

                // Get the signature sent by the extension
                if (messageLength > messageBuffer.Length)
                {
                    // This is here just in case there is a legitimate need for a larger message buffer, for future-proofing
                    // the extension
                    messageBuffer = new byte[messageLength];
                }
                if (!ReadFromPipe(messageBuffer, messageLength))
                {
                    continue;
                }
                Logger.Debug($"Got a message of length {messageLength} bytes.");

                // Process the message
                IMessage response;
                try
                {
                    Message message = Message.Parser.ParseFrom(messageBuffer, 0, messageLength);
                    Logger.Debug($"Message type: {message.Type}");

                    switch (message.Type)
                    {
                    case MessageType.MethodSignatureRequest:
                        MethodSignatureRequest request = MethodSignatureRequest.Parser.ParseFrom(message.MessageBody);
                        response = HandleMethodSignatureRequest(request);
                        break;

                    default:
                        Logger.Warn($"Warning: got a message of unknown type ({message.Type}).");
                        response = new Error
                        {
                            Message = $"Unknown message type ({message.Type})"
                        };
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error($"Error handling message: {ex.GetType().Name} - {ex.Message}.");
                    Logger.Trace(ex.StackTrace);

                    response = new Error
                    {
                        ErrorType  = ex.GetType().Name,
                        Message    = ex.Message,
                        StackTrace = ex.StackTrace
                    };
                }

                // Write the response back to the extension.
                try
                {
                    if (response != null)
                    {
                        Message wrapperMessage = MessageManager.WrapMessage(response);
                        byte[]  responseBuffer = wrapperMessage.ToByteArray();
                        byte[]  responseLength = BitConverter.GetBytes(responseBuffer.Length);
                        Stream.Write(responseLength);
                        Stream.Flush();
                        Stream.Write(responseBuffer);
                        Stream.Flush();
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error($"Error writing response to extension: {ex.GetType().Name} - {ex.Message}.");
                    Logger.Trace(ex.StackTrace);
                    Stream.Close();
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Sends a new parsing request to the parser application, and returns its response.
        /// </summary>
        /// <param name="MethodSignature">The signature string of the method (the operation or
        /// function) to parse.</param>
        /// <returns>The parsed message signature response from the parser, or null if something
        /// went wrong.</returns>
        public MethodSignatureResponse RequestMethodSignatureParse(string MethodSignature)
        {
            if (Stream == null || !Stream.IsConnected)
            {
                Logger.Debug($"Tried to send a {nameof(MethodSignatureRequest)} to the parser but " +
                             $"it isn't connected.");
                return(null);
            }

            try
            {
                // Create and wrap the request message
                MethodSignatureRequest request = new MethodSignatureRequest
                {
                    MethodSignature = MethodSignature
                };
                Message message = MessageManager.WrapMessage(request);

                // Send the message to the parser
                byte[] requestBuffer = message.ToByteArray();
                byte[] bufferSize    = BitConverter.GetBytes(requestBuffer.Length);
                Stream.Write(bufferSize, 0, bufferSize.Length);
                Stream.Flush();
                Stream.Write(requestBuffer, 0, requestBuffer.Length);
                Stream.Flush();

                // Wait for a response, and read how big it is
                byte[] lengthBuffer = new byte[sizeof(int)];
                if (!ReadFromPipe(lengthBuffer, lengthBuffer.Length))
                {
                    Logger.Warn("Method parsing request failed, something went wrong while reading from the pipe.");
                    return(null);
                }

                // Get the actual response from the parser
                int    responseLength = BitConverter.ToInt32(lengthBuffer, 0);
                byte[] responseBuffer = new byte[responseLength];
                if (!ReadFromPipe(responseBuffer, responseLength))
                {
                    Logger.Warn("Method parsing request failed, something went wrong while reading from the pipe.");
                    return(null);
                }

                // Deserialize the response
                Message response = Message.Parser.ParseFrom(responseBuffer);
                switch (response.Type)
                {
                case MessageType.Error:
                    Error error = Error.Parser.ParseFrom(response.MessageBody);
                    Logger.Warn($"Parser failed during method signature processing: {error.ErrorType} - {error.Message}");
                    Logger.Trace(error.StackTrace);
                    return(null);

                case MessageType.MethodSignatureResponse:
                    MethodSignatureResponse signatureResponse = MethodSignatureResponse.Parser.ParseFrom(response.MessageBody);
                    return(signatureResponse);

                default:
                    throw new Exception($"Unexpected message response type: {response.Type}");
                }
            }
            catch (Exception ex)
            {
                Logger.Error($"Error during method signature processing: {ex.GetType().Name} - {ex.Message}");
                Logger.Trace(ex.StackTrace);
                return(null);
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Handles a request for parsing a method signature.
 /// </summary>
 /// <param name="Request">The signature parsing request</param>
 /// <returns>A <see cref="MethodSignatureResponse"/> if parsing was successful, or a
 /// <see cref="ErrorMessage"/> if something went wrong.</returns>
 private IMessage HandleMethodSignatureRequest(MethodSignatureRequest Request)
 {
     return(Parser.ParseMethodSignature(Request.MethodSignature));
 }