13#include "llvm/Support/JSON.h" 
   14#include "llvm/Support/LSP/Protocol.h" 
   15#include "llvm/Support/LSP/Transport.h" 
   21#define DEBUG_TYPE "circt-verilog-lsp-server" 
   24using namespace llvm::lsp;
 
   36      : server(server), transport(transport),
 
   43  void onInitialize(
const InitializeParams ¶ms,
 
   44                    Callback<json::Value> reply);
 
   45  void onInitialized(
const InitializedParams ¶ms);
 
   46  void onShutdown(
const NoParams ¶ms, Callback<std::nullptr_t> reply);
 
   52  void onDocumentDidOpen(
const DidOpenTextDocumentParams ¶ms);
 
   53  void onDocumentDidClose(
const DidCloseTextDocumentParams ¶ms);
 
   54  void onDocumentDidChange(
const DidChangeTextDocumentParams ¶ms);
 
   60  void onGoToDefinition(
const TextDocumentPositionParams ¶ms,
 
   61                        Callback<std::vector<Location>> reply);
 
   62  void onReference(
const ReferenceParams ¶ms,
 
   63                   Callback<std::vector<Location>> reply);
 
   70  JSONTransport &transport;
 
   73  void sendDiagnostics(
const PublishDiagnosticsParams &p) {
 
   74    std::scoped_lock<std::mutex> lk(diagnosticsMutex);
 
   75    publishDiagnostics(p); 
 
   79  setPublishDiagnostics(OutgoingNotification<PublishDiagnosticsParams> diag) {
 
   80    std::scoped_lock<std::mutex> lk(diagnosticsMutex);
 
   81    publishDiagnostics = std::move(diag);
 
   86  bool shutdownRequestReceived = 
false;
 
   90  std::mutex diagnosticsMutex;
 
   93  OutgoingNotification<PublishDiagnosticsParams> publishDiagnostics;
 
  104void LSPServer::onInitialize(
const InitializeParams ¶ms,
 
  105                             Callback<json::Value> reply) {
 
  107  json::Object serverCaps{
 
  112              {
"change", (int)TextDocumentSyncKind::Incremental},
 
  118      {
"definitionProvider", 
true},
 
  119      {
"referencesProvider", 
true},
 
  123      {{
"serverInfo", json::Object{{
"name", 
"circt-verilog-lsp-server"},
 
  124                                   {
"version", 
"0.0.1"}}},
 
  125       {
"capabilities", std::move(serverCaps)}}};
 
  126  reply(std::move(result));
 
  128void LSPServer::onInitialized(
const InitializedParams &) {}
 
  129void LSPServer::onShutdown(
const NoParams &, Callback<std::nullptr_t> reply) {
 
  130  shutdownRequestReceived = 
true;
 
  131  pendingChanges.abort();
 
  139void LSPServer::onDocumentDidOpen(
const DidOpenTextDocumentParams ¶ms) {
 
  140  PublishDiagnosticsParams diagParams(params.textDocument.uri,
 
  141                                      params.textDocument.version);
 
  142  server.addDocument(params.textDocument.uri, params.textDocument.text,
 
  143                     params.textDocument.version, diagParams.diagnostics);
 
  146  sendDiagnostics(diagParams);
 
  149void LSPServer::onDocumentDidClose(
const DidCloseTextDocumentParams ¶ms) {
 
  150  pendingChanges.erase(params.textDocument.uri);
 
  151  std::optional<int64_t> version =
 
  152      server.removeDocument(params.textDocument.uri);
 
  159  sendDiagnostics(PublishDiagnosticsParams(params.textDocument.uri, *version));
 
  162void LSPServer::onDocumentDidChange(
const DidChangeTextDocumentParams ¶ms) {
 
  163  pendingChanges.debounceAndUpdate(
 
  164      params, debounceOptions,
 
  165      [
this, params](std::unique_ptr<circt::lsp::PendingChanges> result) {
 
  169        PublishDiagnosticsParams diagParams(params.textDocument.uri,
 
  171        server.updateDocument(params.textDocument.uri, result->changes,
 
  172                              result->version, diagParams.diagnostics);
 
  174        sendDiagnostics(diagParams);
 
  182void LSPServer::onGoToDefinition(
const TextDocumentPositionParams ¶ms,
 
  183                                 Callback<std::vector<Location>> reply) {
 
  184  std::vector<Location> locations;
 
  185  server.getLocationsOf(params.textDocument.uri, params.position, locations);
 
  186  reply(std::move(locations));
 
  189void LSPServer::onReference(
const ReferenceParams ¶ms,
 
  190                            Callback<std::vector<Location>> reply) {
 
  191  std::vector<Location> locations;
 
  192  server.findReferencesOf(params.textDocument.uri, params.position, locations);
 
  193  reply(std::move(locations));
 
  203                                JSONTransport &transport) {
 
  204  LSPServer lspServer(options, 
server, transport);
 
  205  MessageHandler messageHandler(transport);
 
  208  lspServer.setPublishDiagnostics(
 
  209      messageHandler.outgoingNotification<PublishDiagnosticsParams>(
 
  210          "textDocument/publishDiagnostics"));
 
  213  messageHandler.method(
"initialize", &lspServer, &LSPServer::onInitialize);
 
  214  messageHandler.notification(
"initialized", &lspServer,
 
  215                              &LSPServer::onInitialized);
 
  216  messageHandler.method(
"shutdown", &lspServer, &LSPServer::onShutdown);
 
  219  messageHandler.notification(
"textDocument/didOpen", &lspServer,
 
  220                              &LSPServer::onDocumentDidOpen);
 
  221  messageHandler.notification(
"textDocument/didClose", &lspServer,
 
  222                              &LSPServer::onDocumentDidClose);
 
  224  messageHandler.notification(
"textDocument/didChange", &lspServer,
 
  225                              &LSPServer::onDocumentDidChange);
 
  227  messageHandler.method(
"textDocument/definition", &lspServer,
 
  228                        &LSPServer::onGoToDefinition);
 
  229  messageHandler.method(
"textDocument/references", &lspServer,
 
  230                        &LSPServer::onReference);
 
  233  if (Error error = transport.run(messageHandler)) {
 
  234    Logger::error(
"Transport error: {0}", error);
 
  235    consumeError(std::move(error));
 
  239  return success(lspServer.shutdownRequestReceived);
 
static std::unique_ptr< RpcServer > server
 
Thread-safe accumulator + debouncer for text document changes.
 
This class implements all of the Verilog related functionality necessary for a language server.
 
llvm::LogicalResult runVerilogLSPServer(const LSPServerOptions &lspOptions, VerilogServer &server, llvm::lsp::JSONTransport &transport)
Run the main loop of the LSP server using the given Verilog server and transport.
 
Debounce tuning for document-change bursts.
 
static DebounceOptions fromLSPOptions(const circt::lsp::LSPServerOptions &opts)
Factory: build from server options. Keep mapping 1:1 for clarity.