#pragma once
#include <libsolidity/lsp/Transport.h>
#include <libsolidity/lsp/FileRepository.h>
#include <libsolidity/interface/CompilerStack.h>
#include <libsolidity/interface/FileReader.h>
#include <json/value.h>
#include <functional>
#include <map>
#include <optional>
#include <string>
#include <vector>
namespace solidity::lsp
{
enum class ErrorCode;
class LanguageServer
{
public:
explicit LanguageServer(Transport& _transport);
void compileAndUpdateDiagnostics();
bool run();
FileRepository& fileRepository() noexcept { return m_fileRepository; }
Transport& client() noexcept { return m_client; }
frontend::ASTNode const* astNodeAtSourceLocation(std::string const& _sourceUnitName, langutil::LineColumn const& _filePos);
langutil::CharStreamProvider const& charStreamProvider() const noexcept { return m_compilerStack; }
private:
void requireServerInitialized();
void handleInitialize(MessageID _id, Json::Value const& _args);
void handleWorkspaceDidChangeConfiguration(Json::Value const& _args);
void setTrace(Json::Value const& _args);
void handleTextDocumentDidOpen(Json::Value const& _args);
void handleTextDocumentDidChange(Json::Value const& _args);
void handleTextDocumentDidClose(Json::Value const& _args);
void handleGotoDefinition(MessageID _id, Json::Value const& _args);
void changeConfiguration(Json::Value const&);
void compile();
using MessageHandler = std::function<void(MessageID, Json::Value const&)>;
Json::Value toRange(langutil::SourceLocation const& _location);
Json::Value toJson(langutil::SourceLocation const& _location);
enum class State { Started, Initialized, ShutdownRequested, ExitRequested, ExitWithoutShutdown };
State m_state = State::Started;
Transport& m_client;
std::map<std::string, MessageHandler> m_handlers;
std::set<std::string> m_openFiles;
std::set<std::string> m_nonemptyDiagnostics;
FileRepository m_fileRepository;
frontend::CompilerStack m_compilerStack;
Json::Value m_settingsObject;
};
}