#pragma once
#include "LibLsp/lsp/ProtocolJsonHandler.h"
#include "LibLsp/lsp/AbsolutePath.h"
#include "LibLsp/JsonRpc/Endpoint.h"
#include "LibLsp/JsonRpc/TcpServer.h"
#include "LibLsp/JsonRpc/Condition.h"
// header for requests
#include "LibLsp/lsp/textDocument/hover.h"
#include "LibLsp/lsp/general/initialize.h"
#include "LibLsp/lsp/general/shutdown.h"
#include "LibLsp/lsp/textDocument/declaration_definition.h"
#include "LibLsp/lsp/textDocument/colorPresentation.h"
//header for notifs
#include "LibLsp/lsp/general/exit.h"
#include "LibLsp/lsp/general/initialized.h"
#include "LibLsp/lsp/textDocument/did_open.h"
#include "LibLsp/lsp/textDocument/did_change.h"
#include "LibLsp/lsp/textDocument/did_save.h"
#include "LibLsp/lsp/textDocument/did_close.h"
#include "LibLsp/JsonRpc/stream.h"
#include "common.h"
#include "symbolmaps.h"
//everything else
#include <functional>
#include <cctype>
#include <unordered_map>
namespace absyntax
{
class block;
}
namespace AsymptoteLsp
{
class istream : public lsp::base_istream<std::istream>
{
public:
istream(std::istream& ist) : lsp::base_istream<std::istream>(ist)
{
}
std::string what() override
{
return "AsymptoteLSP_istream";
}
};
class ostream : public lsp::base_ostream<std::ostream>
{
public:
ostream(std::ostream& ost) : lsp::base_ostream<std::ostream>(ost)
{
}
std::string what() override
{
return "AsymptoteLSP_ostream";
}
};
template<typename TLeft, typename TRight>
inline optional<std::pair<optional<TLeft>, optional<TRight>>> opt_left(TLeft const& opt)
{
return make_optional(std::make_pair(optional<TLeft>(opt), optional<TRight>()));
}
template<typename TLeft, typename TRight>
inline optional<std::pair<optional<TLeft>, optional<TRight>>> opt_right(TRight const& opt)
{
return make_optional(std::make_pair(optional<TLeft>(), optional<TRight>(opt)));
}
TextDocumentHover::Either fromString(std::string const &str);
TextDocumentHover::Either fromMarkedStr(lsMarkedString const& markedString);
TextDocumentHover::Either fromMarkedStr(std::string const& str, std::string const& language="asymptote");
TextDocumentHover::Either fromMarkedStr(std::vector<std::string> const& stringList,
std::string const& language="asymptote");
#if defined(LINUX_SYSTEM)
// these functions have no use for apple or windows builds
std::string wslDos2Unix(std::string const& dosPath);
std::string wslUnix2Dos(std::string const& unixPath);
#endif
std::string getDocIdentifierRawPath(lsTextDocumentIdentifier const&);
typedef std::unordered_map<std::string, std::unique_ptr<SymbolContext>> SymContextFilemap;
class LspLog: public lsp::Log
{
public:
void log(Level level, std::string&& msg) override;
void log(Level level, const std::string& msg) override;
void log(Level level, std::wstring&& msg) override;
void log(Level level, const std::wstring& msg) override;
};
class AsymptoteLspServer
{
public:
AsymptoteLspServer(shared_ptr<lsp::ProtocolJsonHandler> const& jsonHandler,
shared_ptr<GenericEndpoint> const& endpoint, LspLog& log);
AsymptoteLspServer(RemoteEndPoint* remoteEndPt,
shared_ptr<lsp::ProtocolJsonHandler> const& jsonHandler,
shared_ptr<GenericEndpoint> const& endpoint, LspLog& log);
virtual ~AsymptoteLspServer();
// copy constructors + copy assignment op
AsymptoteLspServer(AsymptoteLspServer& sv) = delete;
AsymptoteLspServer& operator=(AsymptoteLspServer const& sv) = delete;
// move constructors and move assignment op
AsymptoteLspServer(AsymptoteLspServer&& sv) = delete;
AsymptoteLspServer& operator=(AsymptoteLspServer&& sv) = delete;
virtual void start();
void startIO(std::istream& in=cin, std::ostream& out=cout);
protected:
td_hover::response handleHoverRequest(td_hover::request const&);
virtual td_initialize::response handleInitailizeRequest(td_initialize::request const&);
virtual td_shutdown::response handleShutdownRequest(td_shutdown::request const&);
td_definition::response handleDefnRequest(td_definition::request const&);
td_documentColor::response handleDocColorRequest(td_documentColor::request const&);
td_colorPresentation::response handleColorPresRequest(td_colorPresentation::request const&);
virtual void onInitialized(Notify_InitializedNotification::notify& notify);
virtual void onExit(Notify_Exit::notify& notify);
void onChange(Notify_TextDocumentDidChange::notify& notify);
void onOpen(Notify_TextDocumentDidOpen::notify& notify);
void onSave(Notify_TextDocumentDidSave::notify& notify);
void onClose(Notify_TextDocumentDidClose::notify& notify);
void generateMissingTrees(std::string const& inputFile);
void initializeRequestFn();
void initializeNotifyFn();
void reloadFile(std::string const&);
void updateFileContentsTable(std::string const& filename);
void updateFileContentsTable(std::string const& filename, std::istream& in);
// logging functions
void log(lsp::Log::Level const& level, std::string const& message);
void logInfo(std::string const& message);
void logWarning(std::string const& message);
void logError(std::string const& message);
SymbolContext* reloadFileRaw(std::string const&, bool const& fillTree=true);
SymbolContext* fromRawPath(lsTextDocumentIdentifier const& identifier);
SymbolContext* reloadFileRaw(absyntax::block* blk, std::string const& rawPath, bool const& fillTree=true);
virtual void clearVariables();
Condition<bool> serverClosed;
private:
unique_ptr<RemoteEndPoint> internalREP;
protected:
// [owned, ptr]
RemoteEndPoint* const remoteEndPoint;
private:
shared_ptr<lsp::ProtocolJsonHandler> pjh;
shared_ptr<GenericEndpoint> ep;
SymbolContext* plainCtx=NULL;
LspLog& _log;
unique_ptr<SymContextFilemap> symmapContextsPtr;
unique_ptr<unordered_map<std::string, std::vector<std::string>>> fileContentsPtr;
std::string plainFile;
};
class TCPAsymptoteLSPServer : public lsp::TcpServer, public AsymptoteLspServer
{
public:
TCPAsymptoteLSPServer(
std::string const& addr, std::string const& port,
shared_ptr<lsp::ProtocolJsonHandler> const& jsonHandler,
shared_ptr<GenericEndpoint> const& endpoint, LspLog& log);
~TCPAsymptoteLSPServer() override;
protected:
void start() override;
Condition<bool> serverInitialized;
};
}