#include #include #include #ifdef _WIN32 #include #include #endif #include "../provider/base/bootstrap.hpp" #include "../service/base/bootstrap.hpp" #include "../protocol/transform/facade.hpp" #include "./server.hpp" namespace lsp::core { LspServer::LspServer(size_t concurrency) : async_executor_(4) { spdlog::info("Initializing LSP server with {} worker threads", concurrency); InitializeCoreServices(); InitializeExtensionServices(); spdlog::debug("LSP server initialized with {} providers.", dispatcher_.GetAllSupportedMethods().size()); } LspServer::~LspServer() { is_shutting_down_ = true; spdlog::info("LSP server shutting down..."); } void LspServer::Run() { spdlog::info("LSP server starting main loop..."); // 设置二进制模式 #ifdef _WIN32 _setmode(_fileno(stdout), _O_BINARY); _setmode(_fileno(stdin), _O_BINARY); #endif while (!is_shutting_down_) { try { std::optional message = ReadMessage(); if (!message) { if (std::cin.eof()) { spdlog::info("End of input stream, exiting main loop"); break; // EOF } spdlog::debug("No message received, continuing..."); continue; } HandleMessage(*message); } catch (const std::exception& e) { spdlog::error("Error in main loop: {}", e.what()); } } spdlog::info("LSP server main loop ended"); } std::optional LspServer::ReadMessage() { std::string line; size_t content_length = 0; // 读取 LSP Header while (std::getline(std::cin, line)) { // 去掉尾部 \r if (!line.empty() && line.back() == '\r') { line.pop_back(); } if (line.empty()) { break; // 空行表示 header 结束 } if (line.find("Content-Length:") == 0) { std::string length_str = line.substr(15); // 跳过 "Content-Length:" size_t start = length_str.find_first_not_of(" "); if (start != std::string::npos) { length_str = length_str.substr(start); try { content_length = std::stoul(length_str); spdlog::trace("Content-Length: {}", content_length); } catch (const std::exception& e) { spdlog::error("Failed to parse Content-Length: {}", e.what()); return std::nullopt; } } } } if (content_length == 0) { spdlog::debug("No Content-Length found in header"); return std::nullopt; } // 读取内容体 std::string body(content_length, '\0'); std::cin.read(&body[0], content_length); if (std::cin.gcount() != static_cast(content_length)) { spdlog::error("Read incomplete message body, expected: {}, got: {}", content_length, std::cin.gcount()); return std::nullopt; } spdlog::trace("Received message: {}", body); return body; } void LspServer::HandleMessage(const std::string& raw_message) { if (auto notification = transform::Deserialize(raw_message)) HandleNotification(*notification); else if (auto request = transform::Deserialize(raw_message)) HandleRequest(*request); else if (auto response = transform::Deserialize(raw_message)) HandleResponse(*response); else spdlog::error("Failed to deserialize message as any LSP message type"); } void LspServer::HandleRequest(const protocol::RequestMessage& request) { std::string request_id = transform::debug::GetIdString(request.id); spdlog::debug("Processing request - id: {}, method: {}", request_id, request.method); // 检查是否可以处理请求 if (!CanProcessRequest(request.method)) { SendStateError(request); } else { // 决定同步还是异步处理 if (RequiresSyncProcessing(request.method)) { SendResponse(dispatcher_.Dispatch(request)); } else { // 异步处理 async_executor_.Submit(request_id, [this, request]() -> std::optional { if (is_shutting_down_) { spdlog::debug("Skipping request {} due to shutdown", request.method); return std::nullopt; } try { return dispatcher_.Dispatch(request); } catch (const std::exception& e) { spdlog::error("Request processing failed: {}", e.what()); return provider::BuildErrorResponseMessage(request, protocol::ErrorCodes::InternalError, e.what()); } }, [this](const std::string& response) { SendResponse(response); }); } spdlog::debug("Processing request method: {}", request.method); } } void LspServer::HandleNotification(const protocol::NotificationMessage& notification) { spdlog::debug("Processing notification - method: {}", notification.method); try { dispatcher_.Dispatch(notification); } catch (const std::exception& e) { spdlog::error("Notification processing failed for '{}': {}", notification.method, e.what()); } } void LspServer::HandleResponse(const protocol::ResponseMessage& response) { std::string id_str = transform::debug::GetIdString(response.id); spdlog::debug("Received response - id: {}", id_str); } void LspServer::OnLifecycleEvent(provider::ServerLifecycleEvent event) { switch (event) { case provider::ServerLifecycleEvent::kInitializing: spdlog::info("Server initializing..."); break; case provider::ServerLifecycleEvent::kInitialized: is_initialized_ = true; spdlog::info("Server initialized successfully"); break; case provider::ServerLifecycleEvent::kInitializeFailed: is_initialized_ = false; spdlog::error("Server initialization failed"); break; case provider::ServerLifecycleEvent::kShuttingDown: is_shutting_down_ = true; spdlog::info("Server entering shutdown state"); break; case provider::ServerLifecycleEvent::kShutdown: is_shutting_down_ = true; spdlog::info("Server shutdown complete"); break; } } bool LspServer::RequiresSyncProcessing(const std::string& method) const { static const std::unordered_set sync_methods = { "initialize", "shutdown" }; return sync_methods.count(method) > 0; } bool LspServer::CanProcessRequest(const std::string& method) const { if (!is_initialized_) return method == "initialize" || method == "exit"; if (is_shutting_down_) return method == "exit"; return true; } void LspServer::HandleCancelRequest(const protocol::NotificationMessage& notification) { spdlog::info("Handle cancel request - method: {}", notification.method); } void LspServer::SendResponse(const std::string& response) { std::lock_guard lock(output_mutex_); size_t byte_length = response.length(); std::string header = "Content-Length: " + std::to_string(byte_length) + "\r\n\r\n"; // 发送 header 和 body std::cout.write(header.c_str(), header.length()); std::cout.write(response.c_str(), response.length()); std::cout.flush(); spdlog::trace("Response sent - length: {}", byte_length); spdlog::trace("Response sent - body: {}", response); } void LspServer::InitializeCoreServices() { spdlog::debug("Initializing core services..."); dispatcher_.SetRequestScheduler(&async_executor_); dispatcher_.RegisterLifecycleCallback( [this](provider::ServerLifecycleEvent event) { OnLifecycleEvent(event); }); provider::RegisterAllProviders(dispatcher_); spdlog::debug("Core services initialized"); } void LspServer::InitializeExtensionServices() { spdlog::debug("Initializing extension services..."); service::RegisterAllServices(service_registry_, async_executor_); dispatcher_.SetSeviceRegistry(&service_registry_); spdlog::debug("Extension services initialized"); } void LspServer::SendError(const protocol::RequestMessage& request, protocol::ErrorCodes code, const std::string& message) { spdlog::warn("Sending error response - method: {}, code: {}, message: {}", request.method, static_cast(code), message); std::string error_response = provider::BuildErrorResponseMessage(request, code, message); SendResponse(error_response); } void LspServer::SendStateError(const protocol::RequestMessage& request) { if (!is_initialized_) SendError(request, protocol::ErrorCodes::ServerNotInitialized, "Server not initialized"); else if (is_shutting_down_) SendError(request, protocol::ErrorCodes::InvalidRequest, "Server is shutting down, only 'exit' is allowed"); else SendError(request, protocol::ErrorCodes::InternalError, "Request not allowed in current state"); } }