#include #include #include #include #include #include "json.hpp" #include "log.hpp" #include "server.hpp" static void request(std::vector & buf); static void reply(const json::obj & ); json::obj noop( const json::obj & ) { return {}; } std::unordered_map actions { { "initialize", server::init }, { "initialized", noop } }; int main(int argc, char * argv[]) { g_argc = argc; g_argv = argv; log() << "Language Server called with args:" << std::endl; for(int i = 0; i < argc; i++) { log() << "\t- " << argv[i] << std::endl; } // std::cout.setf(std::ios::unitbuf); // char buff[1000]; // int r = 0; // while(0 != (r = read(STDIN_FILENO, buff, 1000))) { // for(int i = 0; i < r; i++) { // log() << buff[i]; // } // } // log() << std::endl; // return 0; std::vector buffer; while(true) { request(buffer); if(buffer.size() == 0) break; auto top = json::parse(buffer); auto action = actions.find( top["method"] ); if(action != actions.end()) { log() << "Executing request '" << action->first << "'" << std::endl; json::obj response = { {"id", top["id"] } }; try{ response["result"] = action->second( top["params"] ); } catch( const json::obj & error ) { response["result"] = ""; response["error"] = error; } reply(response); } else { log() << "WARNING no action for method '" << top["method"].dump(4) << "'" << std::endl; } } log() << "Language Server closing after end of file" << std::endl; return 0; } static void request(std::vector & buffer) { std::string lenstr; std::getline( std::cin, lenstr ); if(std::cin.eof()) { buffer.clear(); return; }; if (lenstr.rfind("Content-Length: ", 0) != 0) { log() << "Expected content length bug got '" << lenstr << "' instead " << std::endl; std::exit(EXIT_FAILURE); } size_t idx = sizeof("Content-Length:"); size_t end; size_t len = std::stoul(lenstr.substr(idx), &end); if(lenstr.length() != (idx + end + 1)) { log() << "Inconsistent size of integer in content length: " << lenstr.length() << " vs " << (idx + end) << std::endl; } log() << "New request of " << len << " bytes" << std::endl; buffer.resize( len + 2 ); std::cin.read(buffer.data(), buffer.size()); for(char c : buffer) { log() << c; } log() << std::endl; return; } static void reply( const json::obj & response) { if(response["result"].is_null()) { log() << "No response needed" << std::endl; return; } log() << "Responding with : " << response.dump(4) << std::endl; const std::string & r = response.dump(); std::cout << "Content-Length: " << r.length() << "\r\n\r\n"; std::cout.flush(); std::cout << r << "\r\n"; std::cout.flush(); }