diff --git a/command_line.cc b/command_line.cc index ce7447f6..51ade8d5 100644 --- a/command_line.cc +++ b/command_line.cc @@ -134,38 +134,44 @@ std::unique_ptr ParseMessage() { +template +struct BaseIpcMessage : public IpcMessage { + BaseIpcMessage() : IpcMessage(T::kIpcId) {} + // IpcMessage: + void Serialize(Writer& writer) override { + T& value = *static_cast(this); + Reflect(writer, value); + } + void Deserialize(Reader& reader) override { + T& value = *static_cast(this); + Reflect(reader, value); + } +}; struct IpcMessage_Quit : public BaseIpcMessage { - static IpcMessageId kId; + static constexpr IpcId kIpcId = IpcId::Quit; }; -IpcMessageId IpcMessage_Quit::kId = "Quit"; +template +void Reflect(TVisitor& visitor, IpcMessage_Quit& value) {} struct IpcMessage_IsAlive : public BaseIpcMessage { - static IpcMessageId kId; + static constexpr IpcId kIpcId = IpcId::IsAlive; }; -IpcMessageId IpcMessage_IsAlive::kId = "IsAlive"; - - - +template +void Reflect(TVisitor& visitor, IpcMessage_IsAlive& value) {} struct IpcMessage_OpenProject : public BaseIpcMessage { - static IpcMessageId kId; - + static constexpr IpcId kIpcId = IpcId::OpenProject; std::string project_path; - - // BaseIpcMessage: - void Serialize(Writer& writer) override { - writer.String(project_path.c_str(), project_path.size()); - } - void Deserialize(Reader& reader) override { - project_path = reader.GetString(); - } }; -IpcMessageId IpcMessage_OpenProject::kId = "OpenProject"; +template +void Reflect(TVisitor& visitor, IpcMessage_OpenProject& value) { + Reflect(visitor, value.project_path); +} @@ -173,108 +179,72 @@ IpcMessageId IpcMessage_OpenProject::kId = "OpenProject"; +struct IpcMessage_LanguageServerRequest : public BaseIpcMessage { + static constexpr IpcId kIpcId = IpcId::LanguageServerRequest; + // TODO: provide a way to get the request state. + lsMethodId method_id; +}; +template +void Reflect(TVisitor& visitor, IpcMessage_LanguageServerRequest& value) { + REFLECT_MEMBER_START(); + REFLECT_MEMBER(method_id); + REFLECT_MEMBER_END(); +} + struct IpcMessage_DocumentSymbolsRequest : public BaseIpcMessage { - RequestId id; + static constexpr IpcId kIpcId = IpcId::DocumentSymbolsRequest; + RequestId request_id; std::string document; - - // BaseIpcMessage: - static IpcMessageId kId; - void Serialize(Writer& visitor) override { - // TODO: dedup - auto& value = *this; - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(document); - REFLECT_MEMBER_END(); - } - void Deserialize(Reader& visitor) override { - // TODO: dedup - auto& value = *this; - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(document); - REFLECT_MEMBER_END(); - } }; -IpcMessageId IpcMessage_DocumentSymbolsRequest::kId = "IpcMessage_DocumentSymbolsRequest"; +template +void Reflect(TVisitor& visitor, IpcMessage_DocumentSymbolsRequest& value) { + REFLECT_MEMBER_START(); + REFLECT_MEMBER(request_id); + REFLECT_MEMBER(document); + REFLECT_MEMBER_END(); +} + struct IpcMessage_DocumentSymbolsResponse : public BaseIpcMessage { - RequestId id; + static constexpr IpcId kIpcId = IpcId::DocumentSymbolsResponse; + RequestId request_id; std::vector symbols; - - // BaseIpcMessage: - static IpcMessageId kId; - void Serialize(Writer& visitor) override { - auto& value = *this; - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(symbols); - REFLECT_MEMBER_END(); - } - void Deserialize(Reader& visitor) override { - auto& value = *this; - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(symbols); - REFLECT_MEMBER_END(); - } }; -IpcMessageId IpcMessage_DocumentSymbolsResponse::kId = "IpcMessage_DocumentSymbolsResponse"; - - - - - +template +void Reflect(TVisitor& visitor, IpcMessage_DocumentSymbolsResponse& value) { + REFLECT_MEMBER_START(); + REFLECT_MEMBER(request_id); + REFLECT_MEMBER(symbols); + REFLECT_MEMBER_END(); +} struct IpcMessage_WorkspaceSymbolsRequest : public BaseIpcMessage { - RequestId id; + static constexpr IpcId kIpcId = IpcId::WorkspaceSymbolsRequest; + RequestId request_id; std::string query; - - // BaseIpcMessage: - static IpcMessageId kId; - void Serialize(Writer& visitor) override { - auto& value = *this; - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(query); - REFLECT_MEMBER_END(); - } - void Deserialize(Reader& visitor) override { - auto& value = *this; - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(query); - REFLECT_MEMBER_END(); - } }; -IpcMessageId IpcMessage_WorkspaceSymbolsRequest::kId = "IpcMessage_WorkspaceSymbolsRequest"; +template +void Reflect(TVisitor& visitor, IpcMessage_WorkspaceSymbolsRequest& value) { + REFLECT_MEMBER_START(); + REFLECT_MEMBER(request_id); + REFLECT_MEMBER(query); + REFLECT_MEMBER_END(); +} + struct IpcMessage_WorkspaceSymbolsResponse : public BaseIpcMessage { - RequestId id; + static constexpr IpcId kIpcId = IpcId::WorkspaceSymbolsResponse; + RequestId request_id; std::vector symbols; - - // BaseIpcMessage: - static IpcMessageId kId; - void Serialize(Writer& visitor) override { - auto& value = *this; - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(symbols); - REFLECT_MEMBER_END(); - } - void Deserialize(Reader& visitor) override { - auto& value = *this; - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(symbols); - REFLECT_MEMBER_END(); - } }; -IpcMessageId IpcMessage_WorkspaceSymbolsResponse::kId = "IpcMessage_WorkspaceSymbolsResponse"; - - - +template +void Reflect(TVisitor& visitor, IpcMessage_WorkspaceSymbolsResponse& value) { + REFLECT_MEMBER_START(); + REFLECT_MEMBER(request_id); + REFLECT_MEMBER(symbols); + REFLECT_MEMBER_END(); +} @@ -301,21 +271,23 @@ IpcMessageId IpcMessage_WorkspaceSymbolsResponse::kId = "IpcMessage_WorkspaceSym void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) { - std::vector> messages = ipc->TakeMessages(); + std::vector> messages = ipc->TakeMessages(); for (auto& message : messages) { - std::cerr << "Processing message " << message->runtime_id() << " (hash " << message->hashed_runtime_id() << ")" << std::endl; + std::cerr << "Processing message " << static_cast(message->ipc_id) << std::endl; - if (IpcMessage_Quit::kId == message->runtime_id()) { + switch (message->ipc_id) { + case IpcId::Quit: { break; } - else if (IpcMessage_IsAlive::kId == message->runtime_id()) { + case IpcId::IsAlive: { IpcMessage_IsAlive response; ipc->SendToClient(0, &response); // todo: make non-blocking + break; } - else if (IpcMessage_OpenProject::kId == message->runtime_id()) { + case IpcId::OpenProject: { IpcMessage_OpenProject* msg = static_cast(message.get()); std::string path = msg->project_path; @@ -330,14 +302,14 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) { db->ApplyIndexUpdate(&update); } std::cerr << "Done" << std::endl; + break; } - - else if (IpcMessage_DocumentSymbolsRequest::kId == message->runtime_id()) { + case IpcId::DocumentSymbolsRequest: { auto msg = static_cast(message.get()); IpcMessage_DocumentSymbolsResponse response; - response.id = msg->id; + response.request_id = msg->request_id; std::cerr << "Wanted file " << msg->document << std::endl; for (auto& file : db->files) { @@ -355,7 +327,7 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) { lsSymbolInformation info; info.location.range.start.line = ref.loc.line - 1; // TODO: cleanup indexer to negate by 1. info.location.range.start.character = ref.loc.column - 1; // TODO: cleanup indexer to negate by 1. - // TODO: store range information. + // TODO: store range information. info.location.range.end.line = info.location.range.start.line; info.location.range.end.character = info.location.range.start.character; @@ -405,13 +377,15 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) { ipc->SendToClient(0, &response); + + break; } - else if (IpcMessage_WorkspaceSymbolsRequest::kId == message->runtime_id()) { + case IpcId::WorkspaceSymbolsRequest: { auto msg = static_cast(message.get()); IpcMessage_WorkspaceSymbolsResponse response; - response.id = msg->id; + response.request_id = msg->request_id; std::cerr << "- Considering " << db->qualified_names.size() << " candidates " << std::endl; @@ -493,12 +467,14 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) { ipc->SendToClient(0, &response); + break; } - else { - std::cerr << "Unhandled IPC message with kind " << message->runtime_id() << " (hash " << message->hashed_runtime_id() << ")" << std::endl; + default: { + std::cerr << "Unhandled IPC message with kind " << static_cast(message->ipc_id) << std::endl; exit(1); } + } } } @@ -575,7 +551,7 @@ void LanguageServerStdinLoop(IpcClient* ipc) { auto request = static_cast(message.get()); IpcMessage_DocumentSymbolsRequest ipc_request; - ipc_request.id = request->id.value(); + ipc_request.request_id = request->id.value(); ipc_request.document = request->params.textDocument.uri.GetPath(); std::cerr << "Request textDocument=" << ipc_request.document << std::endl; ipc->SendToServer(&ipc_request); @@ -586,7 +562,7 @@ void LanguageServerStdinLoop(IpcClient* ipc) { { auto request = static_cast(message.get()); IpcMessage_WorkspaceSymbolsRequest ipc_request; - ipc_request.id = request->id.value(); + ipc_request.request_id = request->id.value(); ipc_request.query = request->params.query; std::cerr << "Request query=" << ipc_request.query << std::endl; ipc->SendToServer(&ipc_request); @@ -597,37 +573,41 @@ void LanguageServerStdinLoop(IpcClient* ipc) { } void LanguageServerMainLoop(IpcClient* ipc) { - std::vector> messages = ipc->TakeMessages(); + std::vector> messages = ipc->TakeMessages(); for (auto& message : messages) { - if (IpcMessage_Quit::kId == message->runtime_id()) { + switch (message->ipc_id) { + case IpcId::Quit: { exit(0); + break; } - - else if (IpcMessage_DocumentSymbolsResponse::kId == message->runtime_id()) { + case IpcId::DocumentSymbolsResponse: { auto msg = static_cast(message.get()); auto response = Out_DocumentSymbolResponse(); - response.id = msg->id; + response.id = msg->request_id; response.result = msg->symbols; response.Send(); std::cerr << "Send symbol response to client (" << response.result.size() << " symbols)" << std::endl; + break; } - else if (IpcMessage_WorkspaceSymbolsResponse::kId == message->runtime_id()) { + case IpcId::WorkspaceSymbolsResponse: { auto msg = static_cast(message.get()); auto response = Out_WorkspaceSymbolResponse(); - response.id = msg->id; + response.id = msg->request_id; response.result = msg->symbols; response.Send(); std::cerr << "Send symbol response to client (" << response.result.size() << " symbols)" << std::endl; + break; } - else { - std::cerr << "Unhandled IPC message with kind " << message->runtime_id() << " (hash " << message->hashed_runtime_id() << ")" << std::endl; + default: { + std::cerr << "Unhandled IPC message with kind " << static_cast(message->ipc_id) << std::endl; exit(1); } + } } } @@ -645,10 +625,10 @@ void LanguageServerMain(std::string process_name) { std::this_thread::sleep_for(std::chrono::milliseconds(20)); // Check if we got an IsAlive message back. - std::vector> messages = client_ipc.TakeMessages(); + std::vector> messages = client_ipc.TakeMessages(); bool has_server = false; for (auto& message : messages) { - if (message->runtime_id() == IpcMessage_IsAlive::kId) { + if (IpcId::IsAlive == message->ipc_id) { has_server = true; break; } @@ -668,13 +648,13 @@ void LanguageServerMain(std::string process_name) { /*stderr*/[](const char* bytes, size_t n) { for (int i = 0; i < n; ++i) std::cerr << bytes[i]; - }, + }, /*open_stdin*/false); std::this_thread::sleep_for(std::chrono::seconds(1)); // Pass empty process name so we only try to start the querydb once. LanguageServerMain(""); return; -} + } #endif // for debugging attach @@ -767,16 +747,14 @@ int main(int argc, char** argv) { _setmode(_fileno(stdin), O_BINARY); #endif - IpcRegistry::instance()->Register(); + IpcRegistry::instance()->Register(IpcId::Quit); + IpcRegistry::instance()->Register(IpcId::IsAlive); + IpcRegistry::instance()->Register(IpcId::OpenProject); - IpcRegistry::instance()->Register(); - IpcRegistry::instance()->Register(); - - IpcRegistry::instance()->Register(); - IpcRegistry::instance()->Register(); - - IpcRegistry::instance()->Register(); - IpcRegistry::instance()->Register(); + IpcRegistry::instance()->Register(IpcId::DocumentSymbolsRequest); + IpcRegistry::instance()->Register(IpcId::DocumentSymbolsResponse); + IpcRegistry::instance()->Register(IpcId::WorkspaceSymbolsRequest); + IpcRegistry::instance()->Register(IpcId::WorkspaceSymbolsResponse); MessageRegistry::instance()->Register(); MessageRegistry::instance()->Register(); diff --git a/ipc.cc b/ipc.cc index 22326a80..ac9c0e65 100644 --- a/ipc.cc +++ b/ipc.cc @@ -1,15 +1,19 @@ #include "ipc.h" - - - +#include "serializer.h" namespace { struct JsonMessage { - int message_id; + IpcId ipc_id; size_t payload_size; - const char* payload(); - void SetPayload(size_t payload_size, const char* payload); + const char* payload() { + return reinterpret_cast(this) + sizeof(JsonMessage); + } + void SetPayload(size_t payload_size, const char* payload) { + char* payload_dest = reinterpret_cast(this) + sizeof(JsonMessage); + this->payload_size = payload_size; + memcpy(payload_dest, payload, payload_size); + } }; JsonMessage* get_free_message(IpcDirectionalChannel* channel) { @@ -34,24 +38,10 @@ namespace { } } -const char* JsonMessage::payload() { - return reinterpret_cast(this) + sizeof(JsonMessage); -} - -void JsonMessage::SetPayload(size_t payload_size, const char* payload) { - char* payload_dest = reinterpret_cast(this) + sizeof(JsonMessage); - this->payload_size = payload_size; - memcpy(payload_dest, payload, payload_size); -} - -void BaseIpcMessageElided::Serialize(Writer& writer) {} - -void BaseIpcMessageElided::Deserialize(Reader& reader) {} - IpcRegistry* IpcRegistry::instance_ = nullptr; -std::unique_ptr IpcRegistry::Allocate(int id) { - return std::unique_ptr((*allocators)[id]()); +std::unique_ptr IpcRegistry::Allocate(IpcId id) { + return std::unique_ptr((*allocators)[id]()); } IpcDirectionalChannel::IpcDirectionalChannel(const std::string& name) { @@ -64,7 +54,9 @@ IpcDirectionalChannel::~IpcDirectionalChannel() { delete[] local_block; } -void IpcDirectionalChannel::PushMessage(BaseIpcMessageElided* message) { +void IpcDirectionalChannel::PushMessage(IpcMessage* message) { + assert(message->ipc_id != IpcId::Invalid); + rapidjson::StringBuffer output; rapidjson::PrettyWriter writer(output); writer.SetFormatOptions( @@ -95,18 +87,18 @@ void IpcDirectionalChannel::PushMessage(BaseIpcMessageElided* message) { if ((*shared->shared_bytes_used + sizeof(JsonMessage) + payload_size) >= shmem_size) continue; - get_free_message(this)->message_id = message->hashed_runtime_id(); + get_free_message(this)->ipc_id = message->ipc_id; get_free_message(this)->SetPayload(payload_size, output.GetString()); *shared->shared_bytes_used += sizeof(JsonMessage) + get_free_message(this)->payload_size; assert(*shared->shared_bytes_used < shmem_size); - get_free_message(this)->message_id = -1; + get_free_message(this)->ipc_id = IpcId::Invalid; break; } } -std::vector> IpcDirectionalChannel::TakeMessages() { +std::vector> IpcDirectionalChannel::TakeMessages() { size_t remaining_bytes = 0; // Move data from shared memory into a local buffer. Do this // before parsing the blocks so that other processes can begin @@ -117,14 +109,14 @@ std::vector> IpcDirectionalChannel::TakeMe memcpy(local_block, shared->shared_start, *shared->shared_bytes_used); *shared->shared_bytes_used = 0; - get_free_message(this)->message_id = -1; + get_free_message(this)->ipc_id = IpcId::Invalid; } - std::vector> result; + std::vector> result; char* message = local_block; while (remaining_bytes > 0) { - std::unique_ptr base_message = IpcRegistry::instance()->Allocate(as_message(message)->message_id); + std::unique_ptr base_message = IpcRegistry::instance()->Allocate(as_message(message)->ipc_id); rapidjson::Document document; document.Parse(as_message(message)->payload(), as_message(message)->payload_size); @@ -147,7 +139,7 @@ std::vector> IpcDirectionalChannel::TakeMe IpcServer::IpcServer(const std::string& name) : name_(name), server_(NameToServerName(name)) {} -void IpcServer::SendToClient(int client_id, BaseIpcMessageElided* message) { +void IpcServer::SendToClient(int client_id, IpcMessage* message) { // Find or create the client. auto it = clients_.find(client_id); if (it == clients_.end()) @@ -156,17 +148,17 @@ void IpcServer::SendToClient(int client_id, BaseIpcMessageElided* message) { clients_[client_id]->PushMessage(message); } -std::vector> IpcServer::TakeMessages() { +std::vector> IpcServer::TakeMessages() { return server_.TakeMessages(); } IpcClient::IpcClient(const std::string& name, int client_id) : server_(NameToServerName(name)), client_(NameToClientName(name, client_id)) {} -void IpcClient::SendToServer(BaseIpcMessageElided* message) { +void IpcClient::SendToServer(IpcMessage* message) { server_.PushMessage(message); } -std::vector> IpcClient::TakeMessages() { +std::vector> IpcClient::TakeMessages() { return client_.TakeMessages(); } diff --git a/ipc.h b/ipc.h index bbf1d862..9647e900 100644 --- a/ipc.h +++ b/ipc.h @@ -15,63 +15,46 @@ // TODO: We need to add support for payloads larger than the maximum shared memory buffer size. -using IpcMessageId = std::string; +enum class IpcId : int { + // Invalid request id. + Invalid = 0, -struct BaseIpcMessageElided { - virtual IpcMessageId runtime_id() const = 0; - virtual int hashed_runtime_id() const = 0; + Quit = 1, + IsAlive, + OpenProject, - virtual void Serialize(Writer& writer); - virtual void Deserialize(Reader& reader); + // This is a language server request. The actual request method + // id is embedded within the request state. + LanguageServerRequest, + // TODO: remove + DocumentSymbolsRequest, + DocumentSymbolsResponse, + WorkspaceSymbolsRequest, + WorkspaceSymbolsResponse }; -// Usage: -// -// class IpcMessage_Foo : public BaseIpcMessage { -// static IpcMessageId kId; -// -// // BaseIpcMessage: -// ... -// } -// IpcMessageId IpcMessage_Foo::kId = "Foo"; -// -// -// main() { -// IpcRegistry::instance()->Register(); -// } -// -// Note: This is a template so that the statics are stored separately -// per type. -template -struct BaseIpcMessage : BaseIpcMessageElided { - BaseIpcMessage(); - virtual ~BaseIpcMessage(); - // Populated by IpcRegistry::RegisterAllocator. - static IpcMessageId runtime_id_; - static int hashed_runtime_id_; +struct IpcMessage { + IpcMessage(IpcId ipc_id) : ipc_id(ipc_id) {} + virtual ~IpcMessage() {} - // BaseIpcMessageElided: - IpcMessageId runtime_id() const override { - return runtime_id_; - } - int hashed_runtime_id() const override { - return hashed_runtime_id_; - } + const IpcId ipc_id; + + virtual void Serialize(Writer& writer) = 0; + virtual void Deserialize(Reader& reader) = 0; }; struct IpcRegistry { - using Allocator = std::function; + using Allocator = std::function; // Use unique_ptrs so we can initialize on first use // (static init order might not be right). - std::unique_ptr> allocators; - std::unique_ptr> hash_to_id; + std::unique_ptr> allocators; template - void Register(); + void Register(IpcId id); - std::unique_ptr Allocate(int id); + std::unique_ptr Allocate(IpcId id); static IpcRegistry* instance() { if (!instance_) @@ -82,25 +65,16 @@ struct IpcRegistry { }; template -void IpcRegistry::Register() { - if (!allocators) { - allocators = MakeUnique>(); - hash_to_id = MakeUnique>(); - } +void IpcRegistry::Register(IpcId id) { + if (!allocators) + allocators = MakeUnique>(); - IpcMessageId id = T::kId; + assert(allocators->find(id) == allocators->end() && + "There is already an IPC message with the given id"); - int hash = std::hash()(id); - auto it = allocators->find(hash); - assert(allocators->find(hash) == allocators->end() && "There is already an IPC message with the given id"); - - (*hash_to_id)[hash] = id; - (*allocators)[hash] = []() { + (*allocators)[id] = [id]() { return new T(); }; - - T::runtime_id_ = id; - T::hashed_runtime_id_ = hash; } @@ -115,8 +89,8 @@ struct IpcDirectionalChannel { explicit IpcDirectionalChannel(const std::string& name); ~IpcDirectionalChannel(); - void PushMessage(BaseIpcMessageElided* message); - std::vector> TakeMessages(); + void PushMessage(IpcMessage* message); + std::vector> TakeMessages(); // Pointer to process shared memory and process shared mutex. std::unique_ptr shared; @@ -129,8 +103,8 @@ struct IpcDirectionalChannel { struct IpcServer { IpcServer(const std::string& name); - void SendToClient(int client_id, BaseIpcMessageElided* message); - std::vector> TakeMessages(); + void SendToClient(int client_id, IpcMessage* message); + std::vector> TakeMessages(); private: std::string name_; @@ -141,36 +115,12 @@ private: struct IpcClient { IpcClient(const std::string& name, int client_id); - void SendToServer(BaseIpcMessageElided* message); - std::vector> TakeMessages(); + void SendToServer(IpcMessage* message); + std::vector> TakeMessages(); IpcDirectionalChannel* client() { return &client_; } private: IpcDirectionalChannel server_; IpcDirectionalChannel client_; -}; - - - - - - - - - - - -template -BaseIpcMessage::BaseIpcMessage() { - assert(!runtime_id_.empty() && "Message is not registered using IpcRegistry::RegisterAllocator"); -} - -template -BaseIpcMessage::~BaseIpcMessage() {} - -template -IpcMessageId BaseIpcMessage::runtime_id_; - -template -int BaseIpcMessage::hashed_runtime_id_ = -1; +}; \ No newline at end of file diff --git a/language_server_api.h b/language_server_api.h index 03ffaed2..e2459114 100644 --- a/language_server_api.h +++ b/language_server_api.h @@ -18,6 +18,21 @@ using std::experimental::nullopt; ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// +enum class lsMethodId : int { + // Language server specific requests. + CancelRequest = 0, + Initialize, + Initialized, + TextDocumentDocumentSymbol, + WorkspaceSymbol, +}; + +template +void Reflect(TVisitor& visitor, lsMethodId& value) { + int value0 = static_cast(value); + Reflect(visitor, value0); + value = static_cast(value0); +} struct RequestId { optional id0; @@ -25,11 +40,12 @@ struct RequestId { }; void Reflect(Writer& visitor, RequestId& value) { + assert(value.id0.has_value() || value.id1.has_value()); + if (value.id0) { Reflect(visitor, value.id0.value()); } else { - assert(value.id1.has_value()); Reflect(visitor, value.id1.value()); } } @@ -214,14 +230,6 @@ struct OutNotificationMessage : public OutMessage { ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -enum class lsMethodId { - CancelRequest, - Initialize, - Initialized, - TextDocumentDocumentSymbol, - WorkspaceSymbol, -}; - const char* MethodIdToString(lsMethodId id) { switch (id) { case lsMethodId::CancelRequest: @@ -303,18 +311,18 @@ struct InMessage { const lsMethodId method_id; optional id; - InMessage(lsMethodId method_id, optional id, Reader& reader) + InMessage(lsMethodId method_id, optional id, Reader& reader) // We verify there are no duplicate hashes inside of MessageRegistry. : method_id(method_id), id(id) {} }; struct InRequestMessage : public InMessage { - InRequestMessage(lsMethodId method, optional id, Reader& reader) + InRequestMessage(lsMethodId method, optional id, Reader& reader) : InMessage(method, id, reader) {} }; struct InNotificationMessage : public InMessage { - InNotificationMessage(lsMethodId method, optional id, Reader& reader) + InNotificationMessage(lsMethodId method, optional id, Reader& reader) : InMessage(method, id, reader) {} };