diff --git a/command_line.cc b/command_line.cc index 4642aff0..ffe3937e 100644 --- a/command_line.cc +++ b/command_line.cc @@ -1027,17 +1027,28 @@ void PreMain() { MessageRegistry::instance()->Register(); } -struct MyMessageType { - static const lsMethodId id = lsMethodId::CancelRequest; -}; - int main(int argc, char** argv) { // TODO: real impl const int kQueueSize = 128; - TypedBidiMessageQueue t("foo", kQueueSize); - MyMessageType mm; - t.SendMessage(&t.for_client, lsMethodId::Initialize, &mm); - t.GetMessages(&t.for_client); + TypedBidiMessageQueue t("foo", kQueueSize); + + // TODO: We can make this entire function a template. + t.RegisterId(In_DocumentSymbolRequest::kMethod, + [](Writer& visitor, lsBaseMessage& message) { + In_DocumentSymbolRequest& m = static_cast(message); + Reflect(visitor, m); + }, [](Reader& visitor) { + auto m = MakeUnique(); + Reflect(visitor, *m); + return m; + }); + + //struct In_DocumentSymbolRequest : public InRequestMessage { + // const static lsMethodId kMethod = lsMethodId::TextDocumentDocumentSymbol; + + //MyMessageType mm; + //t.SendMessage(&t.for_client, lsMethodId::Initialize, &mm); + //t.GetMessages(&t.for_client); bool loop = false; while (loop) diff --git a/language_server_api.h b/language_server_api.h index 460a253a..3f9aea2e 100644 --- a/language_server_api.h +++ b/language_server_api.h @@ -62,127 +62,6 @@ void Reflect(Reader& visitor, RequestId& id) { std::cerr << "Unable to deserialize id" << std::endl; } -struct OutMessage { - // Write out the body of the message. The writer expects object key/value - // pairs. - virtual void WriteMessageBody(Writer& writer) = 0; - - // Send the message to the language client by writing it to stdout. - void Send() { - rapidjson::StringBuffer output; - Writer writer(output); - writer.StartObject(); - writer.Key("jsonrpc"); - writer.String("2.0"); - WriteMessageBody(writer); - writer.EndObject(); - - std::cout << "Content-Length: " << output.GetSize(); - std::cout << (char)13 << char(10) << char(13) << char(10); - std::cout << output.GetString(); - std::cout.flush(); - } -}; - -struct OutRequestMessage : public OutMessage { - RequestId id; - - virtual std::string Method() = 0; - virtual void SerializeParams(Writer& visitor) = 0; - - // Message: - void WriteMessageBody(Writer& visitor) override { - auto& value = *this; - auto method = Method(); - - REFLECT_MEMBER(id); - REFLECT_MEMBER2("method", method); - - visitor.Key("params"); - SerializeParams(visitor); - } -}; - - -struct lsResponseError { - struct Data { - virtual void Write(Writer& writer) = 0; - }; - - enum class lsErrorCodes : int { - ParseError = -32700, - InvalidRequest = -32600, - MethodNotFound = -32601, - InvalidParams = -32602, - InternalError = -32603, - serverErrorStart = -32099, - serverErrorEnd = -32000, - ServerNotInitialized = -32002, - UnknownErrorCode = -32001 - }; - - lsErrorCodes code; - // Short description. - std::string message; - std::unique_ptr data; - - void Write(Writer& visitor) { - auto& value = *this; - int code = static_cast(this->code); - - visitor.StartObject(); - REFLECT_MEMBER2("code", code); - REFLECT_MEMBER(message); - if (data) { - visitor.Key("data"); - data->Write(visitor); - } - visitor.EndObject(); - } -}; - -struct OutResponseMessage : public OutMessage { - RequestId id; - - virtual optional Error() { - return nullopt; - } - virtual void WriteResult(Writer& visitor) = 0; - - // Message: - void WriteMessageBody(Writer& visitor) override { - auto& value = *this; - - REFLECT_MEMBER(id); - - optional error = Error(); - if (error) { - visitor.Key("error"); - error->Write(visitor); - } - else { - visitor.Key("result"); - WriteResult(visitor); - } - } -}; - -struct OutNotificationMessage : public OutMessage { - virtual std::string Method() = 0; - virtual void SerializeParams(Writer& writer) = 0; - - // Message: - void WriteMessageBody(Writer& visitor) override { - visitor.Key("method"); - std::string method = Method(); - ::Reflect(visitor, method); - - visitor.Key("params"); - SerializeParams(visitor); - } -}; - - @@ -313,8 +192,9 @@ MessageRegistry* MessageRegistry::instance() { return instance_; } +struct lsBaseMessage {}; -struct InMessage { +struct InMessage : public lsBaseMessage { const lsMethodId method_id; optional id; @@ -333,6 +213,126 @@ struct InNotificationMessage : public InMessage { : InMessage(method, id, reader) {} }; +struct OutMessage : public lsBaseMessage { + // Write out the body of the message. The writer expects object key/value + // pairs. + virtual void WriteMessageBody(Writer& writer) = 0; + + // Send the message to the language client by writing it to stdout. + void Send() { + rapidjson::StringBuffer output; + Writer writer(output); + writer.StartObject(); + writer.Key("jsonrpc"); + writer.String("2.0"); + WriteMessageBody(writer); + writer.EndObject(); + + std::cout << "Content-Length: " << output.GetSize(); + std::cout << (char)13 << char(10) << char(13) << char(10); + std::cout << output.GetString(); + std::cout.flush(); + } +}; + +struct OutRequestMessage : public OutMessage { + RequestId id; + + virtual std::string Method() = 0; + virtual void SerializeParams(Writer& visitor) = 0; + + // Message: + void WriteMessageBody(Writer& visitor) override { + auto& value = *this; + auto method = Method(); + + REFLECT_MEMBER(id); + REFLECT_MEMBER2("method", method); + + visitor.Key("params"); + SerializeParams(visitor); + } +}; + + +struct lsResponseError { + struct Data { + virtual void Write(Writer& writer) = 0; + }; + + enum class lsErrorCodes : int { + ParseError = -32700, + InvalidRequest = -32600, + MethodNotFound = -32601, + InvalidParams = -32602, + InternalError = -32603, + serverErrorStart = -32099, + serverErrorEnd = -32000, + ServerNotInitialized = -32002, + UnknownErrorCode = -32001 + }; + + lsErrorCodes code; + // Short description. + std::string message; + std::unique_ptr data; + + void Write(Writer& visitor) { + auto& value = *this; + int code = static_cast(this->code); + + visitor.StartObject(); + REFLECT_MEMBER2("code", code); + REFLECT_MEMBER(message); + if (data) { + visitor.Key("data"); + data->Write(visitor); + } + visitor.EndObject(); + } +}; + +struct OutResponseMessage : public OutMessage { + RequestId id; + + virtual optional Error() { + return nullopt; + } + virtual void WriteResult(Writer& visitor) = 0; + + // Message: + void WriteMessageBody(Writer& visitor) override { + auto& value = *this; + + REFLECT_MEMBER(id); + + optional error = Error(); + if (error) { + visitor.Key("error"); + error->Write(visitor); + } + else { + visitor.Key("result"); + WriteResult(visitor); + } + } +}; + +struct OutNotificationMessage : public OutMessage { + virtual std::string Method() = 0; + virtual void SerializeParams(Writer& writer) = 0; + + // Message: + void WriteMessageBody(Writer& visitor) override { + visitor.Key("method"); + std::string method = Method(); + ::Reflect(visitor, method); + + visitor.Key("params"); + SerializeParams(visitor); + } +}; + @@ -1358,6 +1358,11 @@ struct In_DocumentSymbolRequest : public InRequestMessage { } }; +template +void Reflect(TVisitor& visitor, In_DocumentSymbolRequest& value) { + Reflect(visitor, value.params); +} + struct Out_DocumentSymbolResponse : public OutResponseMessage { std::vector result; diff --git a/src/typed_bidi_message_queue.h b/src/typed_bidi_message_queue.h index 1b4485f4..bceedc4d 100644 --- a/src/typed_bidi_message_queue.h +++ b/src/typed_bidi_message_queue.h @@ -26,7 +26,7 @@ struct TypedBidiMessageQueue { void RegisterId(TId id, const Serializer& serializer, - const Deserializer& deseriaizer) { + const Deserializer& deserializer) { assert(serializers_.find(id) == serializers_.end() && deserializers_.find(id) == deserializers_.end() && "Duplicate registration");