internal/lsp: the core lsp protocol
This is not intended to be a user friendly package, just the rawest correct
implemenation of the protocol as a building block
Change-Id: Ib672b7f1e2fd8284be422dc7964f1876e94c9578
Reviewed-on: https://go-review.googlesource.com/136676
Reviewed-by: Alan Donovan <adonovan@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/lsp/protocol/basic.go b/internal/lsp/protocol/basic.go
new file mode 100644
index 0000000..05174d9
--- /dev/null
+++ b/internal/lsp/protocol/basic.go
@@ -0,0 +1,362 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the corresponding structures to the
+// "Basic JSON Structures" part of the LSP specification.
+
+package protocol
+
+const (
+ // CodeRequestCancelled is the error code that is returned when a request is
+ // cancelled early.
+ CodeRequestCancelled = -32800
+)
+
+// DocumentURI represents the URI of a document.
+// Many of the interfaces contain fields that correspond to the URI of a document.
+// For clarity, the type of such a field is declared as a DocumentURI.
+// Over the wire, it will still be transferred as a string, but this guarantees
+// that the contents of that string can be parsed as a valid URI.
+type DocumentURI string
+
+// Position in a text document expressed as zero-based line and zero-based character offset.
+// A position is between two characters like an ‘insert’ cursor in a editor.
+type Position struct {
+ /**
+ * Line position in a document (zero-based).
+ */
+ Line float64 `json:"line"`
+
+ /**
+ * Character offset on a line in a document (zero-based). Assuming that the line is
+ * represented as a string, the `character` value represents the gap between the
+ * `character` and `character + 1`.
+ *
+ * If the character value is greater than the line length it defaults back to the
+ * line length.
+ */
+ Character float64 `json:"character"`
+}
+
+// Range in a text document expressed as (zero-based) start and end positions.
+// A range is comparable to a selection in an editor.
+// Therefore the end position is exclusive.
+// If you want to specify a range that contains a line including the line
+// ending character(s) then use an end position denoting the start of the next
+// line.
+type Range struct {
+ /**
+ * The range's start position.
+ */
+ Start Position `json:"start"`
+
+ /**
+ * The range's end position.
+ */
+ End Position `json:"end"`
+}
+
+// Location represents a location inside a resource, such as a line inside a text file.
+type Location struct {
+ URI DocumentURI `json:"uri"`
+ Range Range `json:"range"`
+}
+
+// Diagnostic represents a diagnostic, such as a compiler error or warning.
+// Diagnostic objects are only valid in the scope of a resource.
+type Diagnostic struct {
+ /**
+ * The range at which the message applies.
+ */
+ Range Range `json:"range"`
+
+ /**
+ * The diagnostic's severity. Can be omitted. If omitted it is up to the
+ * client to interpret diagnostics as error, warning, info or hint.
+ */
+ Severity DiagnosticSeverity `json:"severity,omitempty"`
+
+ /**
+ * The diagnostic's code, which might appear in the user interface.
+ */
+ Code string `json:"code,omitempty"` // number | string
+
+ /**
+ * A human-readable string describing the source of this
+ * diagnostic, e.g. 'typescript' or 'super lint'.
+ */
+ Source string `json:"source,omitempty"`
+
+ /**
+ * The diagnostic's message.
+ */
+ Message string `json:"message"`
+
+ /**
+ * An array of related diagnostic information, e.g. when symbol-names within
+ * a scope collide all definitions can be marked via this property.
+ */
+ Related []DiagnosticRelatedInformation `json:"relatedInformation,omitempty"`
+}
+
+// DiagnosticSeverity indicates the severity of a Diagnostic message.
+type DiagnosticSeverity float64
+
+const (
+ /**
+ * Reports an error.
+ */
+ SeverityError DiagnosticSeverity = 1
+ /**
+ * Reports a warning.
+ */
+ SeverityWarning DiagnosticSeverity = 2
+ /**
+ * Reports an information.
+ */
+ SeverityInformation DiagnosticSeverity = 3
+ /**
+ * Reports a hint.
+ */
+ SeverityHint DiagnosticSeverity = 4
+)
+
+// DiagnosticRelatedInformation represents a related message and source code
+// location for a diagnostic.
+// This should be used to point to code locations that cause or related to a
+// diagnostics, e.g when duplicating a symbol in a scope.
+type DiagnosticRelatedInformation struct {
+ /**
+ * The location of this related diagnostic information.
+ */
+ Location Location `json:"location"`
+
+ /**
+ * The message of this related diagnostic information.
+ */
+ Message string `json:"message"`
+}
+
+// Command represents a reference to a command.
+// Provides a title which will be used to represent a command in the UI.
+// Commands are identified by a string identifier.
+// The protocol currently doesn’t specify a set of well-known commands.
+// So executing a command requires some tool extension code.
+type Command struct {
+ /**
+ * Title of the command, like `save`.
+ */
+ Title string `json:"title"`
+
+ /**
+ * The identifier of the actual command handler.
+ */
+ Command string `json:"command"`
+
+ /**
+ * Arguments that the command handler should be
+ * invoked with.
+ */
+ Arguments []interface{} `json:"arguments,omitempty"`
+}
+
+// TextEdit is a textual edit applicable to a text document.
+type TextEdit struct {
+ /**
+ * The range of the text document to be manipulated. To insert
+ * text into a document create a range where start === end.
+ */
+ Range Range `json:"range"`
+
+ /**
+ * The string to be inserted. For delete operations use an
+ * empty string.
+ */
+ NewText string `json:"newText"`
+}
+
+// TextDocumentEdit describes textual changes on a single text document.
+// The text document is referred to as a VersionedTextDocumentIdentifier to
+// allow clients to check the text document version before an edit is applied.
+// A TextDocumentEdit describes all changes on a version Si and after they are
+// applied move the document to version Si+1.
+// So the creator of a TextDocumentEdit doesn’t need to sort the array or do
+// any kind of ordering.
+// However the edits must be non overlapping.
+type TextDocumentEdit struct {
+ /**
+ * The text document to change.
+ */
+ TextDocument VersionedTextDocumentIdentifier `json:"textDocument"`
+
+ /**
+ * The edits to be applied.
+ */
+ Edits []TextEdit `json:"edits"`
+}
+
+// WorkspaceEdit represents changes to many resources managed in the workspace.
+// The edit should either provide Changes or DocumentChanges.
+// If the client can handle versioned document edits and if DocumentChanges are
+// present, the latter are preferred over Changes.
+type WorkspaceEdit struct {
+ /**
+ * Holds changes to existing resources.
+ */
+ Changes map[DocumentURI][]TextEdit `json:"changes,omitempty"`
+
+ /**
+ * An array of `TextDocumentEdit`s to express changes to n different text documents
+ * where each text document edit addresses a specific version of a text document.
+ * Whether a client supports versioned document edits is expressed via
+ * `WorkspaceClientCapabilities.workspaceEdit.documentChanges`.
+ */
+ DocumentChanges []TextDocumentEdit `json:"documentChanges,omitempty"`
+}
+
+// TextDocumentIdentifier identifies a document using a URI.
+// On the protocol level, URIs are passed as strings.
+// The corresponding JSON structure looks like this.
+type TextDocumentIdentifier struct {
+ /**
+ * The text document's URI.
+ */
+ URI DocumentURI `json:"uri"`
+}
+
+// TextDocumentItem is an item to transfer a text document from the client to
+// the server.
+type TextDocumentItem struct {
+ /**
+ * The text document's URI.
+ */
+ URI DocumentURI `json:"uri"`
+
+ /**
+ * The text document's language identifier.
+ */
+ LanguageID string `json:"languageId"`
+
+ /**
+ * The version number of this document (it will increase after each
+ * change, including undo/redo).
+ */
+ Version float64 `json:"version"`
+
+ /**
+ * The content of the opened text document.
+ */
+ Text string `json:"text"`
+}
+
+// VersionedTextDocumentIdentifier is an identifier to denote a specific version of a text document.
+type VersionedTextDocumentIdentifier struct {
+ TextDocumentIdentifier
+
+ /**
+ * The version number of this document. If a versioned text document identifier
+ * is sent from the server to the client and the file is not open in the editor
+ * (the server has not received an open notification before) the server can send
+ * `null` to indicate that the version is known and the content on disk is the
+ * truth (as speced with document content ownership)
+ */
+ Version *uint64 `json:"version"`
+}
+
+// TextDocumentPositionParams is a parameter literal used in requests to pass
+// a text document and a position inside that document.
+type TextDocumentPositionParams struct {
+ /**
+ * The text document.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+
+ /**
+ * The position inside the text document.
+ */
+ Position Position `json:"position"`
+}
+
+// DocumentFilter is a document filter denotes a document through properties
+// like language, scheme or pattern.
+// An example is a filter that applies to TypeScript files on disk.
+// Another example is a filter the applies to JSON files with name package.json:
+// { language: 'typescript', scheme: 'file' }
+// { language: 'json', pattern: '**/package.json' }
+type DocumentFilter struct {
+ /**
+ * A language id, like `typescript`.
+ */
+ Language string `json:"language,omitempty"`
+
+ /**
+ * A URI [scheme](#URI.scheme), like `file` or `untitled`.
+ */
+ Scheme string `json:"scheme,omitempty"`
+
+ /**
+ * A glob pattern, like `*.{ts,js}`.
+ */
+ Pattern string `json:"pattern,omitempty"`
+}
+
+// A document selector is the combination of one or more document filters.
+type DocumentSelector []DocumentFilter
+
+/**
+ * Describes the content type that a client supports in various
+ * result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
+ *
+ * Please note that `MarkupKinds` must not start with a `$`. This kinds
+ * are reserved for internal usage.
+ */
+type MarkupKind string
+
+const (
+ /**
+ * Plain text is supported as a content format
+ */
+ PlainText MarkupKind = "plaintext"
+
+ /**
+ * Markdown is supported as a content format
+ */
+ Markdown MarkupKind = "markdown"
+)
+
+/**
+ * A `MarkupContent` literal represents a string value which content is interpreted base on its
+ * kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds.
+ *
+ * If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues.
+ * See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+ *
+ * Here is an example how such a string can be constructed using JavaScript / TypeScript:
+ * ```ts
+ * let markdown: MarkdownContent = {
+ * kind: MarkupKind.Markdown,
+ * value: [
+ * '# Header',
+ * 'Some text',
+ * '```typescript',
+ * 'someCode();',
+ * '```'
+ * ].join('\n')
+ * };
+ * ```
+ *
+ * *Please Note* that clients might sanitize the return markdown. A client could decide to
+ * remove HTML from the markdown to avoid script execution.
+ */
+type MarkupContent struct {
+ /**
+ * The type of the Markup
+ */
+ Kind MarkupKind `json:"kind"`
+
+ /**
+ * The content itself
+ */
+ Value string `json:"value"`
+}
diff --git a/internal/lsp/protocol/client.go b/internal/lsp/protocol/client.go
new file mode 100644
index 0000000..1e71328
--- /dev/null
+++ b/internal/lsp/protocol/client.go
@@ -0,0 +1,205 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package protocol
+
+import (
+ "context"
+ "encoding/json"
+
+ "golang.org/x/tools/internal/jsonrpc2"
+)
+
+type Client interface {
+ ShowMessage(context.Context, *ShowMessageParams) error
+ ShowMessageRequest(context.Context, *ShowMessageRequestParams) (*MessageActionItem, error)
+ LogMessage(context.Context, *LogMessageParams) error
+ Telemetry(context.Context, interface{}) error
+ RegisterCapability(context.Context, *RegistrationParams) error
+ UnregisterCapability(context.Context, *UnregistrationParams) error
+ WorkspaceFolders(context.Context) ([]WorkspaceFolder, error)
+ Configuration(context.Context, *ConfigurationParams) ([]interface{}, error)
+ ApplyEdit(context.Context, *ApplyWorkspaceEditParams) (bool, error)
+ PublishDiagnostics(context.Context, *PublishDiagnosticsParams) error
+}
+
+func clientHandler(client Client) jsonrpc2.Handler {
+ return func(ctx context.Context, conn *jsonrpc2.Conn, r *jsonrpc2.Request) (interface{}, *jsonrpc2.Error) {
+ switch r.Method {
+ case "$/cancelRequest":
+ var params CancelParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ conn.Cancel(params.ID)
+ return nil, nil
+
+ case "window/showMessage":
+ var params ShowMessageParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := client.ShowMessage(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "window/showMessageRequest":
+ var params ShowMessageRequestParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := client.ShowMessageRequest(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "window/logMessage":
+ var params LogMessageParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := client.LogMessage(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "telemetry/event":
+ var params interface{}
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := client.Telemetry(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "client/registerCapability":
+ var params RegistrationParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := client.RegisterCapability(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "client/unregisterCapability":
+ var params UnregistrationParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := client.UnregisterCapability(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "workspace/workspaceFolders":
+ if r.Params != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params")
+ }
+ resp, err := client.WorkspaceFolders(ctx)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "workspace/configuration":
+ var params ConfigurationParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := client.Configuration(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "workspace/applyEdit":
+ var params ApplyWorkspaceEditParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := client.ApplyEdit(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/publishDiagnostics":
+ var params PublishDiagnosticsParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := client.PublishDiagnostics(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ default:
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeMethodNotFound, "method %q not found", r.Method)
+ }
+ }
+}
+
+type clientDispatcher struct {
+ *jsonrpc2.Conn
+}
+
+func (c *clientDispatcher) ShowMessage(ctx context.Context, params *ShowMessageParams) error {
+ return c.Conn.Notify(ctx, "window/showMessage", params)
+}
+
+func (c *clientDispatcher) ShowMessageRequest(ctx context.Context, params *ShowMessageRequestParams) (*MessageActionItem, error) {
+ var result MessageActionItem
+ if err := c.Conn.Call(ctx, "window/showMessageRequest", params, &result); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func (c *clientDispatcher) LogMessage(ctx context.Context, params *LogMessageParams) error {
+ return c.Conn.Notify(ctx, "window/logMessage", params)
+}
+
+func (c *clientDispatcher) Telemetry(ctx context.Context, params interface{}) error {
+ return c.Conn.Notify(ctx, "telemetry/event", params)
+}
+
+func (c *clientDispatcher) RegisterCapability(ctx context.Context, params *RegistrationParams) error {
+ return c.Conn.Notify(ctx, "client/registerCapability", params)
+}
+
+func (c *clientDispatcher) UnregisterCapability(ctx context.Context, params *UnregistrationParams) error {
+ return c.Conn.Notify(ctx, "client/unregisterCapability", params)
+}
+
+func (c *clientDispatcher) WorkspaceFolders(ctx context.Context) ([]WorkspaceFolder, error) {
+ var result []WorkspaceFolder
+ if err := c.Conn.Call(ctx, "workspace/workspaceFolders", nil, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (c *clientDispatcher) Configuration(ctx context.Context, params *ConfigurationParams) ([]interface{}, error) {
+ var result []interface{}
+ if err := c.Conn.Call(ctx, "workspace/configuration", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (c *clientDispatcher) ApplyEdit(ctx context.Context, params *ApplyWorkspaceEditParams) (bool, error) {
+ var result bool
+ if err := c.Conn.Call(ctx, "workspace/applyEdit", params, &result); err != nil {
+ return false, err
+ }
+ return result, nil
+}
+
+func (c *clientDispatcher) PublishDiagnostics(ctx context.Context, params *PublishDiagnosticsParams) error {
+ return c.Conn.Notify(ctx, "textDocument/publishDiagnostics", params)
+}
diff --git a/internal/lsp/protocol/diagnostics.go b/internal/lsp/protocol/diagnostics.go
new file mode 100644
index 0000000..2fe45ce
--- /dev/null
+++ b/internal/lsp/protocol/diagnostics.go
@@ -0,0 +1,20 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the corresponding structures to the
+// "Diagnostics" part of the LSP specification.
+
+package protocol
+
+type PublishDiagnosticsParams struct {
+ /**
+ * The URI for which diagnostic information is reported.
+ */
+ URI DocumentURI `json:"uri"`
+
+ /**
+ * An array of diagnostic information items.
+ */
+ Diagnostics []Diagnostic `json:"diagnostics"`
+}
diff --git a/internal/lsp/protocol/doc.go b/internal/lsp/protocol/doc.go
new file mode 100644
index 0000000..2ffdf51
--- /dev/null
+++ b/internal/lsp/protocol/doc.go
@@ -0,0 +1,16 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package protocol contains the structs that map directly to the wire format
+// of the "Language Server Protocol".
+//
+// It is a literal transcription, with unmodified comments, and only the changes
+// required to make it go code.
+// Names are uppercased to export them.
+// All fields have JSON tags added to correct the names.
+// Fields marked with a ? are also marked as "omitempty"
+// Fields that are "|| null" are made pointers
+// Fields that are string or number are left as string
+// Fields that are type "number" are made float64
+package protocol
diff --git a/internal/lsp/protocol/general.go b/internal/lsp/protocol/general.go
new file mode 100644
index 0000000..be8fa68
--- /dev/null
+++ b/internal/lsp/protocol/general.go
@@ -0,0 +1,849 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the corresponding structures to the
+// "General" messages part of the LSP specification.
+
+package protocol
+
+import "golang.org/x/tools/internal/jsonrpc2"
+
+type CancelParams struct {
+ /**
+ * The request id to cancel.
+ */
+ ID jsonrpc2.ID `json:"id"`
+}
+
+type InitializeParams struct {
+ /**
+ * The process Id of the parent process that started
+ * the server. Is null if the process has not been started by another process.
+ * If the parent process is not alive then the server should exit (see exit notification) its process.
+ */
+ ProcessID *float64 `json:"processId"`
+
+ /**
+ * The rootPath of the workspace. Is null
+ * if no folder is open.
+ *
+ * @deprecated in favour of rootURI.
+ */
+ RootPath *string `json:"rootPath"`
+
+ /**
+ * The rootURI of the workspace. Is null if no
+ * folder is open. If both `rootPath` and `rootURI` are set
+ * `rootURI` wins.
+ */
+ RootURI *DocumentURI `json:"rootURI"`
+
+ /**
+ * User provided initialization options.
+ */
+ InitializationOptions interface{} `json:"initializationOptions"`
+
+ /**
+ * The capabilities provided by the client (editor or tool)
+ */
+ Capabilities ClientCapabilities `json:"capabilities"`
+
+ /**
+ * The initial trace setting. If omitted trace is disabled ('off').
+ */
+ Trace string `json:"trace"` // 'off' | 'messages' | 'verbose'
+
+ /**
+ * The workspace folders configured in the client when the server starts.
+ * This property is only available if the client supports workspace folders.
+ * It can be `null` if the client supports workspace folders but none are
+ * configured.
+ *
+ * Since 3.6.0
+ */
+ WorkspaceFolders []WorkspaceFolder `json:"workspaceFolders,omitempty"`
+}
+
+/**
+ * Workspace specific client capabilities.
+ */
+type WorkspaceClientCapabilities struct {
+ /**
+ * The client supports applying batch edits to the workspace by supporting
+ * the request 'workspace/applyEdit'
+ */
+ ApplyEdit bool `json:"applyEdit,omitempty"`
+
+ /**
+ * Capabilities specific to `WorkspaceEdit`s
+ */
+ WorkspaceEdit struct {
+ /**
+ * The client supports versioned document changes in `WorkspaceEdit`s
+ */
+ DocumentChanges bool `json:"documentChanges,omitempty"`
+ } `json:"workspaceEdit,omitempty"`
+
+ /**
+ * Capabilities specific to the `workspace/didChangeConfiguration` notification.
+ */
+ DidChangeConfiguration struct {
+ /**
+ * Did change configuration notification supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"didChangeConfiguration,omitempty"`
+
+ /**
+ * Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
+ */
+ DidChangeWatchedFiles struct {
+ /**
+ * Did change watched files notification supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"didChangeWatchedFiles,omitempty"`
+
+ /**
+ * Capabilities specific to the `workspace/symbol` request.
+ */
+ Symbol struct {
+ /**
+ * Symbol request supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+
+ /**
+ * Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.
+ */
+ SymbolKind struct {
+ /**
+ * The symbol kind values the client supports. When this
+ * property exists the client also guarantees that it will
+ * handle values outside its set gracefully and falls back
+ * to a default value when unknown.
+ *
+ * If this property is not present the client only supports
+ * the symbol kinds from `File` to `Array` as defined in
+ * the initial version of the protocol.
+ */
+ ValueSet []SymbolKind `json:"valueSet,omitempty"`
+ } `json:"symbolKind,omitempty"`
+ } `json:"symbol,omitempty"`
+
+ /**
+ * Capabilities specific to the `workspace/executeCommand` request.
+ */
+ ExecuteCommand struct {
+ /**
+ * Execute command supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"executeCommand,omitempty"`
+
+ /**
+ * The client has support for workspace folders.
+ *
+ * Since 3.6.0
+ */
+ WorkspaceFolders bool `json:"workspaceFolders,omitempty"`
+
+ /**
+ * The client supports `workspace/configuration` requests.
+ *
+ * Since 3.6.0
+ */
+ Configuration bool `json:"configuration,omitempty"`
+}
+
+/**
+ * Text document specific client capabilities.
+ */
+type TextDocumentClientCapabilities struct {
+ Synchronization struct {
+ /**
+ * Whether text document synchronization supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+
+ /**
+ * The client supports sending will save notifications.
+ */
+ WillSave bool `json:"willSave,omitempty"`
+
+ /**
+ * The client supports sending a will save request and
+ * waits for a response providing text edits which will
+ * be applied to the document before it is saved.
+ */
+ WillSaveWaitUntil bool `json:"willSaveWaitUntil,omitempty"`
+
+ /**
+ * The client supports did save notifications.
+ */
+ DidSave bool `json:"didSave,omitempty"`
+ } `json:"synchronization,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/completion`
+ */
+ Completion struct {
+ /**
+ * Whether completion supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+
+ /**
+ * The client supports the following `CompletionItem` specific
+ * capabilities.
+ */
+ CompletionItem struct {
+ /**
+ * Client supports snippets as insert text.
+ *
+ * A snippet can define tab stops and placeholders with `$1`, `$2`
+ * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+ * the end of the snippet. Placeholders with equal identifiers are linked,
+ * that is typing in one will update others too.
+ */
+ SnippetSupport bool `json:"snippetSupport,omitempty"`
+
+ /**
+ * Client supports commit characters on a completion item.
+ */
+ CommitCharactersSupport bool `json:"commitCharactersSupport,omitempty"`
+
+ /**
+ * Client supports the follow content formats for the documentation
+ * property. The order describes the preferred format of the client.
+ */
+ DocumentationFormat []MarkupKind `json:"documentationFormat,omitempty"`
+
+ /**
+ * Client supports the deprecated property on a completion item.
+ */
+ DeprecatedSupport bool `json:"deprecatedSupport,omitempty"`
+
+ /**
+ * Client supports the preselect property on a completion item.
+ */
+ PreselectSupport bool `json:"preselectSupport,omitempty"`
+ } `json:"completionItem,omitempty"`
+
+ CompletionItemKind struct {
+ /**
+ * The completion item kind values the client supports. When this
+ * property exists the client also guarantees that it will
+ * handle values outside its set gracefully and falls back
+ * to a default value when unknown.
+ *
+ * If this property is not present the client only supports
+ * the completion items kinds from `Text` to `Reference` as defined in
+ * the initial version of the protocol.
+ */
+ ValueSet []CompletionItemKind `json:"valueSet,omitempty"`
+ } `json:"completionItemKind,omitempty"`
+
+ /**
+ * The client supports to send additional context information for a
+ * `textDocument/completion` request.
+ */
+ ContextSupport bool `json:"contextSupport,omitempty"`
+ } `json:"completion"`
+
+ /**
+ * Capabilities specific to the `textDocument/hover`
+ */
+ Hover struct {
+ /**
+ * Whether hover supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+
+ /**
+ * Client supports the follow content formats for the content
+ * property. The order describes the preferred format of the client.
+ */
+ ContentFormat []MarkupKind `json:"contentFormat,omitempty"`
+ } `json:"hover,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/signatureHelp`
+ */
+ SignatureHelp struct {
+ /**
+ * Whether signature help supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+
+ /**
+ * The client supports the following `SignatureInformation`
+ * specific properties.
+ */
+ SignatureInformation struct {
+ /**
+ * Client supports the follow content formats for the documentation
+ * property. The order describes the preferred format of the client.
+ */
+ DocumentationFormat []MarkupKind `json:"documentationFormat,omitempty"`
+ } `json:"signatureInformation,omitempty"`
+ } `json:"signatureHelp,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/references`
+ */
+ References struct {
+ /**
+ * Whether references supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"references,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/documentHighlight`
+ */
+ DocumentHighlight struct {
+ /**
+ * Whether document highlight supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"documentHighlight,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/documentSymbol`
+ */
+ DocumentSymbol struct {
+ /**
+ * Whether document symbol supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+
+ /**
+ * Specific capabilities for the `SymbolKind`.
+ */
+ SymbolKind struct {
+ /**
+ * The symbol kind values the client supports. When this
+ * property exists the client also guarantees that it will
+ * handle values outside its set gracefully and falls back
+ * to a default value when unknown.
+ *
+ * If this property is not present the client only supports
+ * the symbol kinds from `File` to `Array` as defined in
+ * the initial version of the protocol.
+ */
+ ValueSet []SymbolKind `json:"valueSet,omitempty"`
+ } `json:"symbolKind,omitempty"`
+
+ /**
+ * The client support hierarchical document symbols.
+ */
+ HierarchicalDocumentSymbolSupport bool `json:"hierarchicalDocumentSymbolSupport,omitempty"`
+ } `json:"documentSymbol,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/formatting`
+ */
+ Formatting struct {
+ /**
+ * Whether formatting supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"formatting,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/rangeFormatting`
+ */
+ RangeFormatting struct {
+ /**
+ * Whether range formatting supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"rangeFormatting,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/onTypeFormatting`
+ */
+ OnTypeFormatting struct {
+ /**
+ * Whether on type formatting supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"onTypeFormatting,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/definition`
+ */
+ Definition struct {
+ /**
+ * Whether definition supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"definition,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/typeDefinition`
+ *
+ * Since 3.6.0
+ */
+ TypeDefinition struct {
+ /**
+ * Whether typeDefinition supports dynamic registration. If this is set to `true`
+ * the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
+ * return value for the corresponding server capability as well.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"typeDefinition,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/implementation`.
+ *
+ * Since 3.6.0
+ */
+ Implementation struct {
+ /**
+ * Whether implementation supports dynamic registration. If this is set to `true`
+ * the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
+ * return value for the corresponding server capability as well.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"implementation,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/codeAction`
+ */
+ CodeAction struct {
+ /**
+ * Whether code action supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ /**
+ * The client support code action literals as a valid
+ * response of the `textDocument/codeAction` request.
+ *
+ * Since 3.8.0
+ */
+ CodeActionLiteralSupport struct {
+ /**
+ * The code action kind is support with the following value
+ * set.
+ */
+ CodeActionKind struct {
+
+ /**
+ * The code action kind values the client supports. When this
+ * property exists the client also guarantees that it will
+ * handle values outside its set gracefully and falls back
+ * to a default value when unknown.
+ */
+ ValueSet []CodeActionKind `json:"valueSet"`
+ } `json:"codeActionKind"`
+ } `json:"codeActionLiteralSupport,omitempty"`
+ } `json:"codeAction,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/codeLens`
+ */
+ CodeLens struct {
+ /**
+ * Whether code lens supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"codeLens,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/documentLink`
+ */
+ DocumentLink struct {
+ /**
+ * Whether document link supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"documentLink,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/documentColor` and the
+ * `textDocument/colorPresentation` request.
+ *
+ * Since 3.6.0
+ */
+ ColorProvider struct {
+ /**
+ * Whether colorProvider supports dynamic registration. If this is set to `true`
+ * the client supports the new `(ColorProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)`
+ * return value for the corresponding server capability as well.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"colorProvider,omitempty"`
+
+ /**
+ * Capabilities specific to the `textDocument/rename`
+ */
+ Rename struct {
+ /**
+ * Whether rename supports dynamic registration.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ } `json:"rename,omitempty"`
+
+ /**
+ * Capabilities specific to `textDocument/publishDiagnostics`.
+ */
+ PublishDiagnostics struct {
+ /**
+ * Whether the clients accepts diagnostics with related information.
+ */
+ RelatedInformation bool `json:"relatedInformation,omitempty"`
+ } `json:"publishDiagnostics,omitempty"`
+
+ /**
+ * Capabilities specific to `textDocument/foldingRange` requests.
+ *
+ * Since 3.10.0
+ */
+ FoldingRange struct {
+ /**
+ * Whether implementation supports dynamic registration for folding range providers. If this is set to `true`
+ * the client supports the new `(FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)`
+ * return value for the corresponding server capability as well.
+ */
+ DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
+ /**
+ * The maximum number of folding ranges that the client prefers to receive per document. The value serves as a
+ * hint, servers are free to follow the limit.
+ */
+ RangeLimit float64 `json:"rangeLimit,omitempty"`
+ /**
+ * If set, the client signals that it only supports folding complete lines. If set, client will
+ * ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange.
+ */
+ LineFoldingOnly bool `json:"lineFoldingOnly,omitempty"`
+ }
+}
+
+// ClientCapabilities now define capabilities for dynamic registration, workspace
+// and text document features the client supports. The experimental can be used to
+// pass experimental capabilities under development. For future compatibility a
+// ClientCapabilities object literal can have more properties set than currently
+// defined. Servers receiving a ClientCapabilities object literal with unknown
+// properties should ignore these properties. A missing property should be
+// interpreted as an absence of the capability. If a property is missing that
+// defines sub properties all sub properties should be interpreted as an absence
+// of the capability.
+//
+// Client capabilities got introduced with version 3.0 of the protocol. They
+// therefore only describe capabilities that got introduced in 3.x or later.
+// Capabilities that existed in the 2.x version of the protocol are still
+// mandatory for clients. Clients cannot opt out of providing them. So even if a
+// client omits the ClientCapabilities.textDocument.synchronization it is still
+// required that the client provides text document synchronization (e.g. open,
+// changed and close notifications).
+type ClientCapabilities struct {
+ /**
+ * Workspace specific client capabilities.
+ */
+ Workspace WorkspaceClientCapabilities `json:"workspace,omitempty"`
+
+ /**
+ * Text document specific client capabilities.
+ */
+ TextDocument TextDocumentClientCapabilities `json:"textDocument,omitempty"`
+
+ /**
+ * Experimental client capabilities.
+ */
+ Experimental interface{} `json:"experimental,omitempty"`
+}
+
+type InitializeResult struct {
+ /**
+ * The capabilities the language server provides.
+ */
+ Capabilities ServerCapabilities `json:"capabilities"`
+}
+
+/**
+ * Defines how the host (editor) should sync document changes to the language server.
+ */
+type TextDocumentSyncKind float64
+
+const (
+ /**
+ * Documents should not be synced at all.
+ */
+ None TextDocumentSyncKind = 0
+
+ /**
+ * Documents are synced by always sending the full content
+ * of the document.
+ */
+ Full TextDocumentSyncKind = 1
+
+ /**
+ * Documents are synced by sending the full content on open.
+ * After that only incremental updates to the document are
+ * send.
+ */
+ Incremental TextDocumentSyncKind = 2
+)
+
+/**
+ * Completion options.
+ */
+type CompletionOptions struct {
+ /**
+ * The server provides support to resolve additional
+ * information for a completion item.
+ */
+ ResolveProvider bool `json:"resolveProvider,omitempty"`
+
+ /**
+ * The characters that trigger completion automatically.
+ */
+ TriggerCharacters []string `json:"triggerCharacters,omitempty"`
+}
+
+/**
+ * Signature help options.
+ */
+type SignatureHelpOptions struct {
+ /**
+ * The characters that trigger signature help
+ * automatically.
+ */
+ TriggerCharacters []string `json:"triggerCharacters,omitempty"`
+}
+
+/**
+ * Code Lens options.
+ */
+type CodeLensOptions struct {
+ /**
+ * Code lens has a resolve provider as well.
+ */
+ ResolveProvider bool `json:"resolveProvider,omitempty"`
+}
+
+/**
+ * Format document on type options.
+ */
+type DocumentOnTypeFormattingOptions struct {
+ /**
+ * A character on which formatting should be triggered, like `}`.
+ */
+ FirstTriggerCharacter string `json:"firstTriggerCharacter"`
+
+ /**
+ * More trigger characters.
+ */
+ MoreTriggerCharacter []string `json:"moreTriggerCharacter,omitempty"`
+}
+
+/**
+ * Document link options.
+ */
+type DocumentLinkOptions struct {
+ /**
+ * Document links have a resolve provider as well.
+ */
+ ResolveProvider bool `json:"resolveProvider,omitempty"`
+}
+
+/**
+ * Execute command options.
+ */
+type ExecuteCommandOptions struct {
+ /**
+ * The commands to be executed on the server
+ */
+ Commands []string `json:"commands"`
+}
+
+/**
+ * Save options.
+ */
+type SaveOptions struct {
+ /**
+ * The client is supposed to include the content on save.
+ */
+ IncludeText bool `json:"includeText,omitempty"`
+}
+
+/**
+ * Color provider options.
+ */
+type ColorProviderOptions struct {
+}
+
+/**
+ * Folding range provider options.
+ */
+type FoldingRangeProviderOptions struct {
+}
+
+type TextDocumentSyncOptions struct {
+ /**
+ * Open and close notifications are sent to the server.
+ */
+ OpenClose bool `json:"openClose,omitempty"`
+ /**
+ * Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
+ * and TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None.
+ */
+ Change float64 `json:"change,omitempty"`
+ /**
+ * Will save notifications are sent to the server.
+ */
+ WillSave bool `json:"willSave,omitempty"`
+ /**
+ * Will save wait until requests are sent to the server.
+ */
+ WillSaveWaitUntil bool `json:"willSaveWaitUntil,omitempty"`
+ /**
+ * Save notifications are sent to the server.
+ */
+ Save SaveOptions `json:"save,omitempty"`
+}
+
+/**
+ * Static registration options to be returned in the initialize request.
+ */
+type StaticRegistrationOptions struct {
+ /**
+ * The id used to register the request. The id can be used to deregister
+ * the request again. See also Registration#id.
+ */
+ ID string `json:"id,omitempty"`
+}
+
+type ServerCapabilities struct {
+ /**
+ * Defines how text documents are synced. Is either a detailed structure defining each notification or
+ * for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to `TextDocumentSyncKind.None`.
+ */
+ TextDocumentSync interface{} `json:"textDocumentSync,omitempty"` // TextDocumentSyncOptions | number
+ /**
+ * The server provides hover support.
+ */
+ HoverProvider bool `json:"hoverProvider,omitempty"`
+ /**
+ * The server provides completion support.
+ */
+ CompletionProvider CompletionOptions `json:"completionProvider,omitempty"`
+ /**
+ * The server provides signature help support.
+ */
+ SignatureHelpProvider SignatureHelpOptions `json:"signatureHelpProvider,omitempty"`
+ /**
+ * The server provides goto definition support.
+ */
+ DefinitionProvider bool `json:"definitionProvider,omitempty"`
+ /**
+ * The server provides Goto Type Definition support.
+ *
+ * Since 3.6.0
+ */
+ TypeDefinitionProvider interface{} `json:"typeDefinitionProvider,omitempty"` // boolean | (TextDocumentRegistrationOptions & StaticRegistrationOptions)
+ /**
+ * The server provides Goto Implementation support.
+ *
+ * Since 3.6.0
+ */
+ ImplementationProvider interface{} `json:"implementationProvider,omitempty"` // boolean | (TextDocumentRegistrationOptions & StaticRegistrationOptions)
+ /**
+ * The server provides find references support.
+ */
+ ReferencesProvider bool `json:"referencesProvider,omitempty"`
+ /**
+ * The server provides document highlight support.
+ */
+ DocumentHighlightProvider bool `json:"documentHighlightProvider,omitempty"`
+ /**
+ * The server provides document symbol support.
+ */
+ DocumentSymbolProvider bool `json:"documentSymbolProvider,omitempty"`
+ /**
+ * The server provides workspace symbol support.
+ */
+ WorkspaceSymbolProvider bool `json:"workspaceSymbolProvider,omitempty"`
+ /**
+ * The server provides code actions.
+ */
+ CodeActionProvider bool `json:"codeActionProvider,omitempty"`
+ /**
+ * The server provides code lens.
+ */
+ CodeLensProvider CodeLensOptions `json:"codeLensProvider,omitempty"`
+ /**
+ * The server provides document formatting.
+ */
+ DocumentFormattingProvider bool `json:"documentFormattingProvider,omitempty"`
+ /**
+ * The server provides document range formatting.
+ */
+ DocumentRangeFormattingProvider bool `json:"documentRangeFormattingProvider,omitempty"`
+ /**
+ * The server provides document formatting on typing.
+ */
+ DocumentOnTypeFormattingProvider DocumentOnTypeFormattingOptions `json:"documentOnTypeFormattingProvider,omitempty"`
+ /**
+ * The server provides rename support.
+ */
+ RenameProvider bool `json:"renameProvider,omitempty"`
+ /**
+ * The server provides document link support.
+ */
+ DocumentLinkProvider DocumentLinkOptions `json:"documentLinkProvider,omitempty"`
+ /**
+ * The server provides color provider support.
+ *
+ * Since 3.6.0
+ */
+ //TODO: complex union type to decode here
+ ColorProvider interface{} `json:"colorProvider,omitempty"` // boolean | ColorProviderOptions | (ColorProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)
+ /**
+ * The server provides folding provider support.
+ *
+ * Since 3.10.0
+ */
+ //TODO: complex union type to decode here
+ FoldingRangeProvider interface{} `json:"foldingRangeProvider,omitempty"` // boolean | FoldingRangeProviderOptions | (FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)
+ /**
+ * The server provides execute command support.
+ */
+ ExecuteCommandProvider ExecuteCommandOptions `json:"executeCommandProvider,omitempty"`
+ /**
+ * Workspace specific server capabilities
+ */
+ Workspace struct {
+ /**
+ * The server supports workspace folder.
+ *
+ * Since 3.6.0
+ */
+ WorkspaceFolders struct {
+ /**
+ * The server has support for workspace folders
+ */
+ Supported bool `json:"supported,omitempty"`
+ /**
+ * Whether the server wants to receive workspace folder
+ * change notifications.
+ *
+ * If a strings is provided the string is treated as a ID
+ * under which the notification is registered on the client
+ * side. The ID can be used to unregister for these events
+ * using the `client/unregisterCapability` request.
+ */
+ ChangeNotifications interface{} `json:"changeNotifications,omitempty"` // string | boolean
+ } `json:"workspaceFolders,omitempty"`
+ } `json:"workspace,omitempty"`
+ /**
+ * Experimental server capabilities.
+ */
+ Experimental interface{} `json:"experimental,omitempty"`
+}
+
+type InitializedParams struct {
+}
diff --git a/internal/lsp/protocol/language.go b/internal/lsp/protocol/language.go
new file mode 100644
index 0000000..78732b1
--- /dev/null
+++ b/internal/lsp/protocol/language.go
@@ -0,0 +1,1020 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the corresponding structures to the
+// "Language Features" part of the LSP specification.
+
+package protocol
+
+type CompletionParams struct {
+ TextDocumentPositionParams
+
+ /**
+ * The completion context. This is only available if the client specifies
+ * to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
+ */
+ Context CompletionContext `json:"context,omitempty"`
+}
+
+/**
+ * How a completion was triggered
+ */
+type CompletionTriggerKind float64
+
+const (
+ /**
+ * Completion was triggered by typing an identifier (24x7 code
+ * complete), manual invocation (e.g Ctrl+Space) or via API.
+ */
+ Invoked CompletionTriggerKind = 1
+
+ /**
+ * Completion was triggered by a trigger character specified by
+ * the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
+ */
+ TriggerCharacter CompletionTriggerKind = 2
+
+ /**
+ * Completion was re-triggered as the current completion list is incomplete.
+ */
+ TriggerForIncompleteCompletions CompletionTriggerKind = 3
+)
+
+/**
+ * Contains additional information about the context in which a completion request is triggered.
+ */
+type CompletionContext struct {
+ /**
+ * How the completion was triggered.
+ */
+ TriggerKind CompletionTriggerKind `json:"triggerKind"`
+
+ /**
+ * The trigger character (a single character) that has trigger code complete.
+ * Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
+ */
+ TriggerCharacter string `json:"triggerCharacter,omitempty"`
+}
+
+/**
+ * Represents a collection of [completion items](#CompletionItem) to be presented
+ * in the editor.
+ */
+type CompletionList struct {
+ /**
+ * This list it not complete. Further typing should result in recomputing
+ * this list.
+ */
+ IsIncomplete bool `json:"isIncomplete"`
+
+ /**
+ * The completion items.
+ */
+ Items []CompletionItem `json:"items"`
+}
+
+/**
+ * Defines whether the insert text in a completion item should be interpreted as
+ * plain text or a snippet.
+ */
+type InsertTextFormat float64
+
+const (
+ /**
+ * The primary text to be inserted is treated as a plain string.
+ */
+ PlainTextFormat InsertTextFormat = 1
+
+ /**
+ * The primary text to be inserted is treated as a snippet.
+ *
+ * A snippet can define tab stops and placeholders with `$1`, `$2`
+ * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+ * the end of the snippet. Placeholders with equal identifiers are linked,
+ * that is typing in one will update others too.
+ */
+ SnippetTextFormat InsertTextFormat = 2
+)
+
+type CompletionItem struct {
+ /**
+ * The label of this completion item. By default
+ * also the text that is inserted when selecting
+ * this completion.
+ */
+ Label string `json:"label"`
+
+ /**
+ * The kind of this completion item. Based of the kind
+ * an icon is chosen by the editor.
+ */
+ Kind float64 `json:"kind,omitempty"`
+
+ /**
+ * A human-readable string with additional information
+ * about this item, like type or symbol information.
+ */
+ Detail string `json:"detail,omitempty"`
+
+ /**
+ * A human-readable string that represents a doc-comment.
+ */
+ Documentation interface{} `json:"documentation,omitempty"` // string | MarkupContent
+
+ /**
+ * Indicates if this item is deprecated.
+ */
+ Deprecated bool `json:"deprecated,omitempty"`
+
+ /**
+ * Select this item when showing.
+ *
+ * *Note* that only one completion item can be selected and that the
+ * tool / client decides which item that is. The rule is that the *first*
+ * item of those that match best is selected.
+ */
+ Preselect bool `json:"preselect,omitempty"`
+
+ /**
+ * A string that should be used when comparing this item
+ * with other items. When `falsy` the label is used.
+ */
+ SortText string `json:"sortText,omitempty"`
+
+ /**
+ * A string that should be used when filtering a set of
+ * completion items. When `falsy` the label is used.
+ */
+ FilterText string `json:"filterText,omitempty"`
+
+ /**
+ * A string that should be inserted into a document when selecting
+ * this completion. When `falsy` the label is used.
+ *
+ * The `insertText` is subject to interpretation by the client side.
+ * Some tools might not take the string literally. For example
+ * VS Code when code complete is requested in this example `con<cursor position>`
+ * and a completion item with an `insertText` of `console` is provided it
+ * will only insert `sole`. Therefore it is recommended to use `textEdit` instead
+ * since it avoids additional client side interpretation.
+ *
+ * @deprecated Use textEdit instead.
+ */
+ InsertText string `json:"insertText,omitempty"`
+
+ /**
+ * The format of the insert text. The format applies to both the `insertText` property
+ * and the `newText` property of a provided `textEdit`.
+ */
+ InsertTextFormat InsertTextFormat `json:"insertTextFormat,omitempty"`
+
+ /**
+ * An edit which is applied to a document when selecting this completion. When an edit is provided the value of
+ * `insertText` is ignored.
+ *
+ * *Note:* The range of the edit must be a single line range and it must contain the position at which completion
+ * has been requested.
+ */
+ TextEdit TextEdit `json:"textEdit,omitempty"`
+
+ /**
+ * An optional array of additional text edits that are applied when
+ * selecting this completion. Edits must not overlap (including the same insert position)
+ * with the main edit nor with themselves.
+ *
+ * Additional text edits should be used to change text unrelated to the current cursor position
+ * (for example adding an import statement at the top of the file if the completion item will
+ * insert an unqualified type).
+ */
+ AdditionalTextEdits []TextEdit `json:"additionalTextEdits,omitempty"`
+
+ /**
+ * An optional set of characters that when pressed while this completion is active will accept it first and
+ * then type that character. *Note* that all commit characters should have `length=1` and that superfluous
+ * characters will be ignored.
+ */
+ CommitCharacters []string `json:"commitCharacters,omitempty"`
+
+ /**
+ * An optional command that is executed *after* inserting this completion. *Note* that
+ * additional modifications to the current document should be described with the
+ * additionalTextEdits-property.
+ */
+ Command Command `json:"command,omitempty"`
+
+ /**
+ * An data entry field that is preserved on a completion item between
+ * a completion and a completion resolve request.
+ */
+ Data interface{} `json:"data"`
+}
+
+/**
+ * The kind of a completion entry.
+ */
+type CompletionItemKind float64
+
+const (
+ TextCompletion CompletionItemKind = 1
+ MethodCompletion CompletionItemKind = 2
+ FunctionCompletion CompletionItemKind = 3
+ ConstructorCompletion CompletionItemKind = 4
+ FieldCompletion CompletionItemKind = 5
+ VariableCompletion CompletionItemKind = 6
+ ClassCompletion CompletionItemKind = 7
+ InterfaceCompletion CompletionItemKind = 8
+ ModuleCompletion CompletionItemKind = 9
+ PropertyCompletion CompletionItemKind = 10
+ UnitCompletion CompletionItemKind = 11
+ ValueCompletion CompletionItemKind = 12
+ EnumCompletion CompletionItemKind = 13
+ KeywordCompletion CompletionItemKind = 14
+ SnippetCompletion CompletionItemKind = 15
+ ColorCompletion CompletionItemKind = 16
+ FileCompletion CompletionItemKind = 17
+ ReferenceCompletion CompletionItemKind = 18
+ FolderCompletion CompletionItemKind = 19
+ EnumMemberCompletion CompletionItemKind = 20
+ ConstantCompletion CompletionItemKind = 21
+ StructCompletion CompletionItemKind = 22
+ EventCompletion CompletionItemKind = 23
+ OperatorCompletion CompletionItemKind = 24
+ TypeParameterCompletion CompletionItemKind = 25
+)
+
+type CompletionRegistrationOptions struct {
+ TextDocumentRegistrationOptions
+ /**
+ * Most tools trigger completion request automatically without explicitly requesting
+ * it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user
+ * starts to type an identifier. For example if the user types `c` in a JavaScript file
+ * code complete will automatically pop up present `console` besides others as a
+ * completion item. Characters that make up identifiers don't need to be listed here.
+ *
+ * If code complete should automatically be trigger on characters not being valid inside
+ * an identifier (for example `.` in JavaScript) list them in `triggerCharacters`.
+ */
+ TriggerCharacters []string `json:"triggerCharacters,omitempty"`
+
+ /**
+ * The server provides support to resolve additional
+ * information for a completion item.
+ */
+ ResolveProvider bool `json:"resolveProvider,omitempty"`
+}
+
+/**
+ * The result of a hover request.
+ */
+type Hover struct {
+ /**
+ * The hover's content
+ */
+ Contents MarkupContent `json:"contents"`
+
+ /**
+ * An optional range is a range inside a text document
+ * that is used to visualize a hover, e.g. by changing the background color.
+ */
+ Range Range `json:"range,omitempty"`
+}
+
+/**
+ * Signature help represents the signature of something
+ * callable. There can be multiple signature but only one
+ * active and only one active parameter.
+ */
+type SignatureHelp struct {
+ /**
+ * One or more signatures.
+ */
+ Signatures []SignatureInformation `json:"signatures"`
+
+ /**
+ * The active signature. If omitted or the value lies outside the
+ * range of `signatures` the value defaults to zero or is ignored if
+ * `signatures.length === 0`. Whenever possible implementors should
+ * make an active decision about the active signature and shouldn't
+ * rely on a default value.
+ * In future version of the protocol this property might become
+ * mandatory to better express this.
+ */
+ ActiveSignature float64 `json:"activeSignature,omitempty"`
+
+ /**
+ * The active parameter of the active signature. If omitted or the value
+ * lies outside the range of `signatures[activeSignature].parameters`
+ * defaults to 0 if the active signature has parameters. If
+ * the active signature has no parameters it is ignored.
+ * In future version of the protocol this property might become
+ * mandatory to better express the active parameter if the
+ * active signature does have any.
+ */
+ ActiveParameter float64 `json:"activeParameter,omitempty"`
+}
+
+/**
+ * Represents the signature of something callable. A signature
+ * can have a label, like a function-name, a doc-comment, and
+ * a set of parameters.
+ */
+type SignatureInformation struct {
+ /**
+ * The label of this signature. Will be shown in
+ * the UI.
+ */
+ Label string `json:"label"`
+
+ /**
+ * The human-readable doc-comment of this signature. Will be shown
+ * in the UI but can be omitted.
+ */
+ Documentation interface{} `json:"documentation,omitempty"` // string | MarkupContent
+
+ /**
+ * The parameters of this signature.
+ */
+ Parameters []ParameterInformation `json:"parameters,omitempty"`
+}
+
+/**
+ * Represents a parameter of a callable-signature. A parameter can
+ * have a label and a doc-comment.
+ */
+type ParameterInformation struct {
+ /**
+ * The label of this parameter. Will be shown in
+ * the UI.
+ */
+ Label string `json:"label"`
+
+ /**
+ * The human-readable doc-comment of this parameter. Will be shown
+ * in the UI but can be omitted.
+ */
+ Documentation interface{} `json:"documentation,omitempty"` // string | MarkupContent
+}
+
+type SignatureHelpRegistrationOptions struct {
+ TextDocumentRegistrationOptions
+ /**
+ * The characters that trigger signature help
+ * automatically.
+ */
+ TriggerCharacters []string `json:"triggerCharacters,omitempty"`
+}
+
+type ReferenceParams struct {
+ TextDocumentPositionParams
+ Context ReferenceContext
+}
+
+type ReferenceContext struct {
+ /**
+ * Include the declaration of the current symbol.
+ */
+ IncludeDeclaration bool `json:"includeDeclaration"`
+}
+
+/**
+ * A document highlight is a range inside a text document which deserves
+ * special attention. Usually a document highlight is visualized by changing
+ * the background color of its range.
+ *
+ */
+type DocumentHighlight struct {
+ /**
+ * The range this highlight applies to.
+ */
+ Range Range `json:"range"`
+
+ /**
+ * The highlight kind, default is DocumentHighlightKind.Text.
+ */
+ Kind float64 `json:"kind,omitempty"`
+}
+
+/**
+ * A document highlight kind.
+ */
+type DocumentHighlightKind float64
+
+const (
+ /**
+ * A textual occurrence.
+ */
+ TextHighlight DocumentHighlightKind = 1
+
+ /**
+ * Read-access of a symbol, like reading a variable.
+ */
+ ReadHighlight DocumentHighlightKind = 2
+
+ /**
+ * Write-access of a symbol, like writing to a variable.
+ */
+ WriteHighlight DocumentHighlightKind = 3
+)
+
+type DocumentSymbolParams struct {
+ /**
+ * The text document.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+}
+
+/**
+ * A symbol kind.
+ */
+type SymbolKind float64
+
+const (
+ FileSymbol SymbolKind = 1
+ ModuleSymbol SymbolKind = 2
+ NamespaceSymbol SymbolKind = 3
+ PackageSymbol SymbolKind = 4
+ ClassSymbol SymbolKind = 5
+ MethodSymbol SymbolKind = 6
+ PropertySymbol SymbolKind = 7
+ FieldSymbol SymbolKind = 8
+ ConstructorSymbol SymbolKind = 9
+ EnumSymbol SymbolKind = 10
+ InterfaceSymbol SymbolKind = 11
+ FunctionSymbol SymbolKind = 12
+ VariableSymbol SymbolKind = 13
+ ConstantSymbol SymbolKind = 14
+ StringSymbol SymbolKind = 15
+ NumberSymbol SymbolKind = 16
+ BooleanSymbol SymbolKind = 17
+ ArraySymbol SymbolKind = 18
+ ObjectSymbol SymbolKind = 19
+ KeySymbol SymbolKind = 20
+ NullSymbol SymbolKind = 21
+ EnumMemberSymbol SymbolKind = 22
+ StructSymbol SymbolKind = 23
+ EventSymbol SymbolKind = 24
+ OperatorSymbol SymbolKind = 25
+ TypeParameterSymbol SymbolKind = 26
+)
+
+/**
+ * Represents programming constructs like variables, classes, interfaces etc. that appear in a document. Document symbols can be
+ * hierarchical and they have two ranges: one that encloses its definition and one that points to its most interesting range,
+ * e.g. the range of an identifier.
+ */
+type DocumentSymbol struct {
+
+ /**
+ * The name of this symbol.
+ */
+ Name string `json:"name"`
+
+ /**
+ * More detail for this symbol, e.g the signature of a function. If not provided the
+ * name is used.
+ */
+ Detail string `json:"detail,omitempty"`
+
+ /**
+ * The kind of this symbol.
+ */
+ Kind SymbolKind `json:"kind"`
+
+ /**
+ * Indicates if this symbol is deprecated.
+ */
+ Deprecated bool `json:"deprecated,omitempty"`
+
+ /**
+ * The range enclosing this symbol not including leading/trailing whitespace but everything else
+ * like comments. This information is typically used to determine if the clients cursor is
+ * inside the symbol to reveal in the symbol in the UI.
+ */
+ Range Range `json:"range"`
+
+ /**
+ * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+ * Must be contained by the `range`.
+ */
+ SelectionRange Range `json:"selectionRange"`
+
+ /**
+ * Children of this symbol, e.g. properties of a class.
+ */
+ Children []DocumentSymbol `json:"children,omitempty"`
+}
+
+/**
+ * Represents information about programming constructs like variables, classes,
+ * interfaces etc.
+ */
+type SymbolInformation struct {
+ /**
+ * The name of this symbol.
+ */
+ Name string `json:"name"`
+
+ /**
+ * The kind of this symbol.
+ */
+ Kind float64 `json:"kind"`
+
+ /**
+ * Indicates if this symbol is deprecated.
+ */
+ Deprecated bool `json:"deprecated,omitempty"`
+
+ /**
+ * The location of this symbol. The location's range is used by a tool
+ * to reveal the location in the editor. If the symbol is selected in the
+ * tool the range's start information is used to position the cursor. So
+ * the range usually spans more then the actual symbol's name and does
+ * normally include things like visibility modifiers.
+ *
+ * The range doesn't have to denote a node range in the sense of a abstract
+ * syntax tree. It can therefore not be used to re-construct a hierarchy of
+ * the symbols.
+ */
+ Location Location `json:"location"`
+
+ /**
+ * The name of the symbol containing this symbol. This information is for
+ * user interface purposes (e.g. to render a qualifier in the user interface
+ * if necessary). It can't be used to re-infer a hierarchy for the document
+ * symbols.
+ */
+ ContainerName string `json:"containerName,omitempty"`
+}
+
+/**
+ * Params for the CodeActionRequest
+ */
+type CodeActionParams struct {
+ /**
+ * The document in which the command was invoked.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+
+ /**
+ * The range for which the command was invoked.
+ */
+ Range Range `json:"range"`
+
+ /**
+ * Context carrying additional information.
+ */
+ Context CodeActionContext `json:"context"`
+}
+
+/**
+ * The kind of a code action.
+ *
+ * Kinds are a hierarchical list of identifiers separated by `.`, e.g. `"refactor.extract.function"`.
+ *
+ * The set of kinds is open and client needs to announce the kinds it supports to the server during
+ * initialization.
+ */
+type CodeActionKind string
+
+/**
+ * A set of predefined code action kinds
+ */
+const (
+ /**
+ * Base kind for quickfix actions: 'quickfix'
+ */
+ QuickFix CodeActionKind = "quickfix"
+
+ /**
+ * Base kind for refactoring actions: 'refactor'
+ */
+ Refactor CodeActionKind = "refactor"
+
+ /**
+ * Base kind for refactoring extraction actions: 'refactor.extract'
+ *
+ * Example extract actions:
+ *
+ * - Extract method
+ * - Extract function
+ * - Extract variable
+ * - Extract interface from class
+ * - ...
+ */
+ RefactorExtract CodeActionKind = "refactor.extract"
+
+ /**
+ * Base kind for refactoring inline actions: 'refactor.inline'
+ *
+ * Example inline actions:
+ *
+ * - Inline function
+ * - Inline variable
+ * - Inline constant
+ * - ...
+ */
+ RefactorInline CodeActionKind = "refactor.inline"
+
+ /**
+ * Base kind for refactoring rewrite actions: 'refactor.rewrite'
+ *
+ * Example rewrite actions:
+ *
+ * - Convert JavaScript function to class
+ * - Add or remove parameter
+ * - Encapsulate field
+ * - Make method static
+ * - Move method to base class
+ * - ...
+ */
+ RefactorRewrite CodeActionKind = "refactor.rewrite"
+
+ /**
+ * Base kind for source actions: `source`
+ *
+ * Source code actions apply to the entire file.
+ */
+ Source CodeActionKind = "source"
+
+ /**
+ * Base kind for an organize imports source action: `source.organizeImports`
+ */
+ SourceOrganizeImports CodeActionKind = "source.organizeImports"
+)
+
+/**
+ * Contains additional diagnostic information about the context in which
+ * a code action is run.
+ */
+type CodeActionContext struct {
+ /**
+ * An array of diagnostics.
+ */
+ Diagnostics []Diagnostic `json:"diagnostics"`
+
+ /**
+ * Requested kind of actions to return.
+ *
+ * Actions not of this kind are filtered out by the client before being shown. So servers
+ * can omit computing them.
+ */
+ Only []CodeActionKind `json:"only,omitempty"`
+}
+
+/**
+ * A code action represents a change that can be performed in code, e.g. to fix a problem or
+ * to refactor code.
+ *
+ * A CodeAction must set either `edit` and/or a `command`. If both are supplied, the `edit` is applied first, then the `command` is executed.
+ */
+type CodeAction struct {
+
+ /**
+ * A short, human-readable, title for this code action.
+ */
+ Title string `json:"title"`
+
+ /**
+ * The kind of the code action.
+ *
+ * Used to filter code actions.
+ */
+ Kind CodeActionKind `json:"kind,omitempty"`
+
+ /**
+ * The diagnostics that this code action resolves.
+ */
+ Diagnostics []Diagnostic `json:"diagnostics,omitempty"`
+
+ /**
+ * The workspace edit this code action performs.
+ */
+ Edit WorkspaceEdit `json:"edit,omitempty"`
+
+ /**
+ * A command this code action executes. If a code action
+ * provides an edit and a command, first the edit is
+ * executed and then the command.
+ */
+ Command Command `json:"command,omitempty"`
+}
+
+type CodeLensParams struct {
+ /**
+ * The document to request code lens for.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+}
+
+/**
+ * A code lens represents a command that should be shown along with
+ * source text, like the number of references, a way to run tests, etc.
+ *
+ * A code lens is _unresolved_ when no command is associated to it. For performance
+ * reasons the creation of a code lens and resolving should be done in two stages.
+ */
+type CodeLens struct {
+ /**
+ * The range in which this code lens is valid. Should only span a single line.
+ */
+ Range Range `json:"range"`
+
+ /**
+ * The command this code lens represents.
+ */
+ Command Command `json:"command,omitempty"`
+
+ /**
+ * A data entry field that is preserved on a code lens item between
+ * a code lens and a code lens resolve request.
+ */
+ Data interface{} `json:"data"`
+}
+
+type CodeLensRegistrationOptions struct {
+ TextDocumentRegistrationOptions
+ /**
+ * Code lens has a resolve provider as well.
+ */
+ ResolveProvider bool `json:"resolveProvider,omitempty"`
+}
+
+type DocumentLinkParams struct {
+ /**
+ * The document to provide document links for.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+}
+
+/**
+ * A document link is a range in a text document that links to an internal or external resource, like another
+ * text document or a web site.
+ */
+type DocumentLink struct {
+ /**
+ * The range this link applies to.
+ */
+ Range Range `json:"range"`
+ /**
+ * The uri this link points to. If missing a resolve request is sent later.
+ */
+ Target DocumentURI `json:"target,omitempty"`
+ /**
+ * A data entry field that is preserved on a document link between a
+ * DocumentLinkRequest and a DocumentLinkResolveRequest.
+ */
+ Data interface{} `json:"data,omitempty"`
+}
+
+type DocumentLinkRegistrationOptions struct {
+ TextDocumentRegistrationOptions
+ /**
+ * Document links have a resolve provider as well.
+ */
+ ResolveProvider bool `json:"resolveProvider,omitempty"`
+}
+
+type DocumentColorParams struct {
+ /**
+ * The text document.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+}
+
+type ColorInformation struct {
+ /**
+ * The range in the document where this color appears.
+ */
+ Range Range `json:"range"`
+
+ /**
+ * The actual color value for this color range.
+ */
+ Color Color `json:"color"`
+}
+
+/**
+ * Represents a color in RGBA space.
+ */
+type Color struct {
+
+ /**
+ * The red component of this color in the range [0-1].
+ */
+ Red float64 `json:"red"`
+
+ /**
+ * The green component of this color in the range [0-1].
+ */
+ Green float64 `json:"green"`
+
+ /**
+ * The blue component of this color in the range [0-1].
+ */
+ Blue float64 `json:"blue"`
+
+ /**
+ * The alpha component of this color in the range [0-1].
+ */
+ Alpha float64 `json:"alpha"`
+}
+
+type ColorPresentationParams struct {
+ /**
+ * The text document.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+
+ /**
+ * The color information to request presentations for.
+ */
+ Color Color `json:"color"`
+
+ /**
+ * The range where the color would be inserted. Serves as a context.
+ */
+ Range Range `json:"range"`
+}
+
+type ColorPresentation struct {
+ /**
+ * The label of this color presentation. It will be shown on the color
+ * picker header. By default this is also the text that is inserted when selecting
+ * this color presentation.
+ */
+ Label string `json:"label"`
+ /**
+ * An [edit](#TextEdit) which is applied to a document when selecting
+ * this presentation for the color. When `falsy` the [label](#ColorPresentation.label)
+ * is used.
+ */
+ TextEdit TextEdit `json:"textEdit,omitempty"`
+ /**
+ * An optional array of additional [text edits](#TextEdit) that are applied when
+ * selecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves.
+ */
+ AdditionalTextEdits []TextEdit `json:"additionalTextEdits,omitempty"`
+}
+
+type DocumentFormattingParams struct {
+ /**
+ * The document to format.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+
+ /**
+ * The format options.
+ */
+ Options FormattingOptions `json:"options"`
+}
+
+/**
+ * Value-object describing what options formatting should use.
+ */
+type FormattingOptions struct {
+ /**
+ * Size of a tab in spaces.
+ */
+ TabSize float64 `json:"tabSize"`
+
+ /**
+ * Prefer spaces over tabs.
+ */
+ InsertSpaces bool `json:"insertSpaces"`
+
+ /**
+ * Signature for further properties.
+ */
+ // TODO: [key: string]: boolean | number | string;
+}
+
+type DocumentRangeFormattingParams struct {
+ /**
+ * The document to format.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+
+ /**
+ * The range to format
+ */
+ Range Range `json:"range"`
+
+ /**
+ * The format options
+ */
+ Options FormattingOptions `json:"options"`
+}
+
+type DocumentOnTypeFormattingParams struct {
+ /**
+ * The document to format.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+
+ /**
+ * The position at which this request was sent.
+ */
+ Position Position `json:"position"`
+
+ /**
+ * The character that has been typed.
+ */
+ Ch string `json:"ch"`
+
+ /**
+ * The format options.
+ */
+ Options FormattingOptions `json:"options"`
+}
+
+type DocumentOnTypeFormattingRegistrationOptions struct {
+ TextDocumentRegistrationOptions
+ /**
+ * A character on which formatting should be triggered, like `}`.
+ */
+ FirstTriggerCharacter string `json:"firstTriggerCharacter"`
+ /**
+ * More trigger characters.
+ */
+ MoreTriggerCharacter []string `json:"moreTriggerCharacter"`
+}
+
+type RenameParams struct {
+ /**
+ * The document to rename.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+
+ /**
+ * The position at which this request was sent.
+ */
+ Position Position `json:"position"`
+
+ /**
+ * The new name of the symbol. If the given name is not valid the
+ * request must return a [ResponseError](#ResponseError) with an
+ * appropriate message set.
+ */
+ NewName string `json:"newName"`
+}
+
+type FoldingRangeRequestParam struct {
+ /**
+ * The text document.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+}
+
+/**
+ * Enum of known range kinds
+ */
+type FoldingRangeKind string
+
+const (
+ /**
+ * Folding range for a comment
+ */
+ Comment FoldingRangeKind = "comment"
+ /**
+ * Folding range for a imports or includes
+ */
+ Imports FoldingRangeKind = "imports"
+ /**
+ * Folding range for a region (e.g. `#region`)
+ */
+ Region FoldingRangeKind = "region"
+)
+
+/**
+ * Represents a folding range.
+ */
+type FoldingRange struct {
+
+ /**
+ * The zero-based line number from where the folded range starts.
+ */
+ StartLine float64 `json:"startLine"`
+
+ /**
+ * The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line.
+ */
+ StartCharacter float64 `json:"startCharacter,omitempty"`
+
+ /**
+ * The zero-based line number where the folded range ends.
+ */
+ EndLine float64 `json:"endLine"`
+
+ /**
+ * The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line.
+ */
+ EndCharacter float64 `json:"endCharacter,omitempty"`
+
+ /**
+ * Describes the kind of the folding range such as `comment' or 'region'. The kind
+ * is used to categorize folding ranges and used by commands like 'Fold all comments'. See
+ * [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds.
+ */
+ Kind string `json:"kind,omitempty"`
+}
diff --git a/internal/lsp/protocol/protocol.go b/internal/lsp/protocol/protocol.go
new file mode 100644
index 0000000..2768250
--- /dev/null
+++ b/internal/lsp/protocol/protocol.go
@@ -0,0 +1,34 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package protocol
+
+import (
+ "context"
+
+ "golang.org/x/tools/internal/jsonrpc2"
+)
+
+func canceller(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) {
+ conn.Notify(context.Background(), "$/cancelRequest", &CancelParams{ID: *req.ID})
+}
+
+func RunClient(ctx context.Context, stream jsonrpc2.Stream, client Client, opts ...interface{}) (*jsonrpc2.Conn, Server) {
+ opts = append([]interface{}{clientHandler(client), canceller}, opts...)
+ conn := jsonrpc2.NewConn(ctx, stream, opts...)
+ return conn, &serverDispatcher{Conn: conn}
+}
+
+func RunServer(ctx context.Context, stream jsonrpc2.Stream, server Server, opts ...interface{}) (*jsonrpc2.Conn, Client) {
+ opts = append([]interface{}{serverHandler(server), canceller}, opts...)
+ conn := jsonrpc2.NewConn(ctx, stream, opts...)
+ return conn, &clientDispatcher{Conn: conn}
+}
+
+func toJSONError(err error) *jsonrpc2.Error {
+ if jsonError, ok := err.(*jsonrpc2.Error); ok {
+ return jsonError
+ }
+ return jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+}
diff --git a/internal/lsp/protocol/registration.go b/internal/lsp/protocol/registration.go
new file mode 100644
index 0000000..31e1eb5
--- /dev/null
+++ b/internal/lsp/protocol/registration.go
@@ -0,0 +1,61 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the corresponding structures to the
+// "Client" part of the LSP specification.
+
+package protocol
+
+/**
+ * General parameters to register for a capability.
+ */
+type Registration struct {
+ /**
+ * The id used to register the request. The id can be used to deregister
+ * the request again.
+ */
+ ID string `json:"id"`
+
+ /**
+ * The method / capability to register for.
+ */
+ Method string `json:"method"`
+
+ /**
+ * Options necessary for the registration.
+ */
+ RegisterOptions interface{} `json:"registerOptions,omitempty"`
+}
+
+type RegistrationParams struct {
+ Registrations []Registration `json:"registrations"`
+}
+
+type TextDocumentRegistrationOptions struct {
+ /**
+ * A document selector to identify the scope of the registration. If set to null
+ * the document selector provided on the client side will be used.
+ */
+ DocumentSelector *DocumentSelector `json:"documentSelector"`
+}
+
+/**
+ * General parameters to unregister a capability.
+ */
+type Unregistration struct {
+ /**
+ * The id used to unregister the request or notification. Usually an id
+ * provided during the register request.
+ */
+ ID string `json:"id"`
+
+ /**
+ * The method / capability to unregister for.
+ */
+ Method string `json:"method"`
+}
+
+type UnregistrationParams struct {
+ Unregisterations []Unregistration `json:"unregisterations"`
+}
diff --git a/internal/lsp/protocol/server.go b/internal/lsp/protocol/server.go
new file mode 100644
index 0000000..22694f1
--- /dev/null
+++ b/internal/lsp/protocol/server.go
@@ -0,0 +1,718 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package protocol
+
+import (
+ "context"
+ "encoding/json"
+
+ "golang.org/x/tools/internal/jsonrpc2"
+)
+
+type Server interface {
+ Initialize(context.Context, *InitializeParams) (*InitializeResult, error)
+ Initialized(context.Context, *InitializedParams) error
+ Shutdown(context.Context) error
+ Exit(context.Context) error
+ DidChangeWorkspaceFolders(context.Context, *DidChangeWorkspaceFoldersParams) error
+ DidChangeConfiguration(context.Context, *DidChangeConfigurationParams) error
+ DidChangeWatchedFiles(context.Context, *DidChangeWatchedFilesParams) error
+ Symbols(context.Context, *WorkspaceSymbolParams) ([]SymbolInformation, error)
+ ExecuteCommand(context.Context, *ExecuteCommandParams) (interface{}, error)
+ DidOpen(context.Context, *DidOpenTextDocumentParams) error
+ DidChange(context.Context, *DidChangeTextDocumentParams) error
+ WillSave(context.Context, *WillSaveTextDocumentParams) error
+ WillSaveWaitUntil(context.Context, *WillSaveTextDocumentParams) ([]TextEdit, error)
+ DidSave(context.Context, *DidSaveTextDocumentParams) error
+ DidClose(context.Context, *DidCloseTextDocumentParams) error
+ Completion(context.Context, *CompletionParams) (*CompletionList, error)
+ CompletionResolve(context.Context, *CompletionItem) (*CompletionItem, error)
+ Hover(context.Context, *TextDocumentPositionParams) (*Hover, error)
+ SignatureHelp(context.Context, *TextDocumentPositionParams) (*SignatureHelp, error)
+ Definition(context.Context, *TextDocumentPositionParams) ([]Location, error)
+ TypeDefinition(context.Context, *TextDocumentPositionParams) ([]Location, error)
+ Implementation(context.Context, *TextDocumentPositionParams) ([]Location, error)
+ References(context.Context, *ReferenceParams) ([]Location, error)
+ DocumentHighlight(context.Context, *TextDocumentPositionParams) ([]DocumentHighlight, error)
+ DocumentSymbol(context.Context, *DocumentSymbolParams) ([]DocumentSymbol, error)
+ CodeAction(context.Context, *CodeActionParams) ([]CodeAction, error)
+ CodeLens(context.Context, *CodeLensParams) ([]CodeLens, error)
+ CodeLensResolve(context.Context, *CodeLens) (*CodeLens, error)
+ DocumentLink(context.Context, *DocumentLinkParams) ([]DocumentLink, error)
+ DocumentLinkResolve(context.Context, *DocumentLink) (*DocumentLink, error)
+ DocumentColor(context.Context, *DocumentColorParams) ([]ColorInformation, error)
+ ColorPresentation(context.Context, *ColorPresentationParams) ([]ColorPresentation, error)
+ Formatting(context.Context, *DocumentFormattingParams) ([]TextEdit, error)
+ RangeFormatting(context.Context, *DocumentRangeFormattingParams) ([]TextEdit, error)
+ OnTypeFormatting(context.Context, *DocumentOnTypeFormattingParams) ([]TextEdit, error)
+ Rename(context.Context, *RenameParams) ([]WorkspaceEdit, error)
+ FoldingRanges(context.Context, *FoldingRangeRequestParam) ([]FoldingRange, error)
+}
+
+func serverHandler(server Server) jsonrpc2.Handler {
+ return func(ctx context.Context, conn *jsonrpc2.Conn, r *jsonrpc2.Request) (interface{}, *jsonrpc2.Error) {
+ switch r.Method {
+ case "initialize":
+ var params InitializeParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.Initialize(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "initialized":
+ var params InitializedParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := server.Initialized(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "shutdown":
+ if r.Params != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params")
+ }
+ if err := server.Shutdown(ctx); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "exit":
+ if r.Params != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params")
+ }
+ if err := server.Exit(ctx); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "$/cancelRequest":
+ var params CancelParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ conn.Cancel(params.ID)
+ return nil, nil
+
+ case "workspace/didChangeWorkspaceFolders":
+ var params DidChangeWorkspaceFoldersParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := server.DidChangeWorkspaceFolders(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "workspace/didChangeConfiguration":
+ var params DidChangeConfigurationParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := server.DidChangeConfiguration(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "workspace/didChangeWatchedFiles":
+ var params DidChangeWatchedFilesParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := server.DidChangeWatchedFiles(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "workspace/symbol":
+ var params WorkspaceSymbolParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.Symbols(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "workspace/executeCommand":
+ var params ExecuteCommandParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.ExecuteCommand(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/didOpen":
+ var params DidOpenTextDocumentParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := server.DidOpen(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "textDocument/didChange":
+ var params DidChangeTextDocumentParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := server.DidChange(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "textDocument/willSave":
+ var params WillSaveTextDocumentParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := server.WillSave(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "textDocument/willSaveWaitUntil":
+ var params WillSaveTextDocumentParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.WillSaveWaitUntil(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/didSave":
+ var params DidSaveTextDocumentParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := server.DidSave(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "textDocument/didClose":
+ var params DidCloseTextDocumentParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ if err := server.DidClose(ctx, ¶ms); err != nil {
+ return nil, toJSONError(err)
+ }
+ return nil, nil
+
+ case "textDocument/completion":
+ var params CompletionParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.Completion(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "completionItem/resolve":
+ var params CompletionItem
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.CompletionResolve(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/hover":
+ var params TextDocumentPositionParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.Hover(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/signatureHelp":
+ var params TextDocumentPositionParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.SignatureHelp(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/definition":
+ var params TextDocumentPositionParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.Definition(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/typeDefinition":
+ var params TextDocumentPositionParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.TypeDefinition(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/implementation":
+ var params TextDocumentPositionParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.Implementation(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/references":
+ var params ReferenceParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.References(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/documentHighlight":
+ var params TextDocumentPositionParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.DocumentHighlight(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/documentSymbol":
+ var params DocumentSymbolParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.DocumentSymbol(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/codeAction":
+ var params CodeActionParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.CodeAction(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/codeLens":
+ var params CodeLensParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.CodeLens(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "codeLens/resolve":
+ var params CodeLens
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.CodeLensResolve(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/documentLink":
+ var params DocumentLinkParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.DocumentLink(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "documentLink/resolve":
+ var params DocumentLink
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.DocumentLinkResolve(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/documentColor":
+ var params DocumentColorParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.DocumentColor(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/colorPresentation":
+ var params ColorPresentationParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.ColorPresentation(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/formatting":
+ var params DocumentFormattingParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.Formatting(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/rangeFormatting":
+ var params DocumentRangeFormattingParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.RangeFormatting(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/onTypeFormatting":
+ var params DocumentOnTypeFormattingParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.OnTypeFormatting(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/rename":
+ var params RenameParams
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.Rename(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+
+ case "textDocument/foldingRanges":
+ var params FoldingRangeRequestParam
+ if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
+ }
+ resp, err := server.FoldingRanges(ctx, ¶ms)
+ if err != nil {
+ return nil, toJSONError(err)
+ }
+ return resp, nil
+ default:
+ return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeMethodNotFound, "method %q not found", r.Method)
+ }
+ }
+}
+
+type serverDispatcher struct {
+ *jsonrpc2.Conn
+}
+
+func (s *serverDispatcher) Initialize(ctx context.Context, params *InitializeParams) (*InitializeResult, error) {
+ var result InitializeResult
+ if err := s.Conn.Call(ctx, "initialize", params, &result); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func (s *serverDispatcher) Initialized(ctx context.Context, params *InitializedParams) error {
+ return s.Conn.Notify(ctx, "initialized", params)
+}
+
+func (s *serverDispatcher) Shutdown(ctx context.Context) error {
+ return s.Conn.Call(ctx, "shutdown", nil, nil)
+}
+
+func (s *serverDispatcher) Exit(ctx context.Context) error {
+ return s.Conn.Notify(ctx, "exit", nil)
+}
+
+func (s *serverDispatcher) DidChangeWorkspaceFolders(ctx context.Context, params *DidChangeWorkspaceFoldersParams) error {
+ return s.Conn.Notify(ctx, "workspace/didChangeWorkspaceFolders", params)
+}
+
+func (s *serverDispatcher) DidChangeConfiguration(ctx context.Context, params *DidChangeConfigurationParams) error {
+ return s.Conn.Notify(ctx, "workspace/didChangeConfiguration", params)
+}
+
+func (s *serverDispatcher) DidChangeWatchedFiles(ctx context.Context, params *DidChangeWatchedFilesParams) error {
+ return s.Conn.Notify(ctx, "workspace/didChangeWatchedFiles", params)
+}
+
+func (s *serverDispatcher) Symbols(ctx context.Context, params *WorkspaceSymbolParams) ([]SymbolInformation, error) {
+ var result []SymbolInformation
+ if err := s.Conn.Call(ctx, "workspace/symbol", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) ExecuteCommand(ctx context.Context, params *ExecuteCommandParams) (interface{}, error) {
+ var result interface{}
+ if err := s.Conn.Call(ctx, "workspace/executeCommand", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) DidOpen(ctx context.Context, params *DidOpenTextDocumentParams) error {
+ return s.Conn.Notify(ctx, "textDocument/didOpen", params)
+}
+
+func (s *serverDispatcher) DidChange(ctx context.Context, params *DidChangeTextDocumentParams) error {
+ return s.Conn.Notify(ctx, "textDocument/didChange", params)
+}
+
+func (s *serverDispatcher) WillSave(ctx context.Context, params *WillSaveTextDocumentParams) error {
+ return s.Conn.Notify(ctx, "textDocument/willSave", params)
+}
+
+func (s *serverDispatcher) WillSaveWaitUntil(ctx context.Context, params *WillSaveTextDocumentParams) ([]TextEdit, error) {
+ var result []TextEdit
+ if err := s.Conn.Call(ctx, "textDocument/willSaveWaitUntil", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) DidSave(ctx context.Context, params *DidSaveTextDocumentParams) error {
+ return s.Conn.Notify(ctx, "textDocument/didSave", params)
+}
+
+func (s *serverDispatcher) DidClose(ctx context.Context, params *DidCloseTextDocumentParams) error {
+ return s.Conn.Notify(ctx, "textDocument/didClose", params)
+}
+
+func (s *serverDispatcher) Completion(ctx context.Context, params *CompletionParams) (*CompletionList, error) {
+ var result CompletionList
+ if err := s.Conn.Call(ctx, "textDocument/completion", params, &result); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func (s *serverDispatcher) CompletionResolve(ctx context.Context, params *CompletionItem) (*CompletionItem, error) {
+ var result CompletionItem
+ if err := s.Conn.Call(ctx, "completionItem/resolve", params, &result); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func (s *serverDispatcher) Hover(ctx context.Context, params *TextDocumentPositionParams) (*Hover, error) {
+ var result Hover
+ if err := s.Conn.Call(ctx, "textDocument/hover", params, &result); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func (s *serverDispatcher) SignatureHelp(ctx context.Context, params *TextDocumentPositionParams) (*SignatureHelp, error) {
+ var result SignatureHelp
+ if err := s.Conn.Call(ctx, "textDocument/signatureHelp", params, &result); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func (s *serverDispatcher) Definition(ctx context.Context, params *TextDocumentPositionParams) ([]Location, error) {
+ var result []Location
+ if err := s.Conn.Call(ctx, "textDocument/definition", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) TypeDefinition(ctx context.Context, params *TextDocumentPositionParams) ([]Location, error) {
+ var result []Location
+ if err := s.Conn.Call(ctx, "textDocument/typeDefinition", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) Implementation(ctx context.Context, params *TextDocumentPositionParams) ([]Location, error) {
+ var result []Location
+ if err := s.Conn.Call(ctx, "textDocument/implementation", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) References(ctx context.Context, params *ReferenceParams) ([]Location, error) {
+ var result []Location
+ if err := s.Conn.Call(ctx, "textDocument/references", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) DocumentHighlight(ctx context.Context, params *TextDocumentPositionParams) ([]DocumentHighlight, error) {
+ var result []DocumentHighlight
+ if err := s.Conn.Call(ctx, "textDocument/documentHighlight", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) DocumentSymbol(ctx context.Context, params *DocumentSymbolParams) ([]DocumentSymbol, error) {
+ var result []DocumentSymbol
+ if err := s.Conn.Call(ctx, "textDocument/documentSymbol", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) CodeAction(ctx context.Context, params *CodeActionParams) ([]CodeAction, error) {
+ var result []CodeAction
+ if err := s.Conn.Call(ctx, "textDocument/codeAction", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) CodeLens(ctx context.Context, params *CodeLensParams) ([]CodeLens, error) {
+ var result []CodeLens
+ if err := s.Conn.Call(ctx, "textDocument/codeLens", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) CodeLensResolve(ctx context.Context, params *CodeLens) (*CodeLens, error) {
+ var result CodeLens
+ if err := s.Conn.Call(ctx, "codeLens/resolve", params, &result); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func (s *serverDispatcher) DocumentLink(ctx context.Context, params *DocumentLinkParams) ([]DocumentLink, error) {
+ var result []DocumentLink
+ if err := s.Conn.Call(ctx, "textDocument/documentLink", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) DocumentLinkResolve(ctx context.Context, params *DocumentLink) (*DocumentLink, error) {
+ var result DocumentLink
+ if err := s.Conn.Call(ctx, "documentLink/resolve", params, &result); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func (s *serverDispatcher) DocumentColor(ctx context.Context, params *DocumentColorParams) ([]ColorInformation, error) {
+ var result []ColorInformation
+ if err := s.Conn.Call(ctx, "textDocument/documentColor", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) ColorPresentation(ctx context.Context, params *ColorPresentationParams) ([]ColorPresentation, error) {
+ var result []ColorPresentation
+ if err := s.Conn.Call(ctx, "textDocument/colorPresentation", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) Formatting(ctx context.Context, params *DocumentFormattingParams) ([]TextEdit, error) {
+ var result []TextEdit
+ if err := s.Conn.Call(ctx, "textDocument/formatting", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) RangeFormatting(ctx context.Context, params *DocumentRangeFormattingParams) ([]TextEdit, error) {
+ var result []TextEdit
+ if err := s.Conn.Call(ctx, "textDocument/rangeFormatting", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) OnTypeFormatting(ctx context.Context, params *DocumentOnTypeFormattingParams) ([]TextEdit, error) {
+ var result []TextEdit
+ if err := s.Conn.Call(ctx, "textDocument/onTypeFormatting", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) Rename(ctx context.Context, params *RenameParams) ([]WorkspaceEdit, error) {
+ var result []WorkspaceEdit
+ if err := s.Conn.Call(ctx, "textDocument/rename", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func (s *serverDispatcher) FoldingRanges(ctx context.Context, params *FoldingRangeRequestParam) ([]FoldingRange, error) {
+ var result []FoldingRange
+ if err := s.Conn.Call(ctx, "textDocument/foldingRanges", params, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
diff --git a/internal/lsp/protocol/text.go b/internal/lsp/protocol/text.go
new file mode 100644
index 0000000..83456a4
--- /dev/null
+++ b/internal/lsp/protocol/text.go
@@ -0,0 +1,130 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the corresponding structures to the
+// "Text Synchronization" part of the LSP specification.
+
+package protocol
+
+type DidOpenTextDocumentParams struct {
+ /**
+ * The document that was opened.
+ */
+ TextDocument TextDocumentItem `json:"textDocument"`
+}
+
+type DidChangeTextDocumentParams struct {
+ /**
+ * The document that did change. The version number points
+ * to the version after all provided content changes have
+ * been applied.
+ */
+ TextDocument VersionedTextDocumentIdentifier `json:"textDocument"`
+
+ /**
+ * The actual content changes. The content changes describe single state changes
+ * to the document. So if there are two content changes c1 and c2 for a document
+ * in state S10 then c1 move the document to S11 and c2 to S12.
+ */
+ ContentChanges []TextDocumentContentChangeEvent `json:"contentChanges"`
+}
+
+/**
+ * An event describing a change to a text document. If range and rangeLength are omitted
+ * the new text is considered to be the full content of the document.
+ */
+type TextDocumentContentChangeEvent struct {
+ /**
+ * The range of the document that changed.
+ */
+ Range Range `json:"range,omitempty"`
+
+ /**
+ * The length of the range that got replaced.
+ */
+ RangeLength float64 `json:"rangeLength,omitempty"`
+
+ /**
+ * The new text of the range/document.
+ */
+ Text string `json:"text"`
+}
+
+/**
+ * Describe options to be used when registering for text document change events.
+ */
+type TextDocumentChangeRegistrationOptions struct {
+ TextDocumentRegistrationOptions
+ /**
+ * How documents are synced to the server. See TextDocumentSyncKind.Full
+ * and TextDocumentSyncKind.Incremental.
+ */
+ SyncKind float64 `json:"syncKind"`
+}
+
+/**
+ * The parameters send in a will save text document notification.
+ */
+type WillSaveTextDocumentParams struct {
+ /**
+ * The document that will be saved.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+
+ /**
+ * The 'TextDocumentSaveReason'.
+ */
+ Reason TextDocumentSaveReason `json:"reason"`
+}
+
+/**
+ * Represents reasons why a text document is saved.
+ */
+type TextDocumentSaveReason float64
+
+const (
+ /**
+ * Manually triggered, e.g. by the user pressing save, by starting debugging,
+ * or by an API call.
+ */
+ Manual TextDocumentSaveReason = 1
+
+ /**
+ * Automatic after a delay.
+ */
+ AfterDelay TextDocumentSaveReason = 2
+
+ /**
+ * When the editor lost focus.
+ */
+ FocusOut TextDocumentSaveReason = 3
+)
+
+type DidSaveTextDocumentParams struct {
+ /**
+ * The document that was saved.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+
+ /**
+ * Optional the content when saved. Depends on the includeText value
+ * when the save notification was requested.
+ */
+ Text string `json:"text,omitempty"`
+}
+
+type TextDocumentSaveRegistrationOptions struct {
+ TextDocumentRegistrationOptions
+ /**
+ * The client is supposed to include the content on save.
+ */
+ IncludeText bool `json:"includeText,omitempty"`
+}
+
+type DidCloseTextDocumentParams struct {
+ /**
+ * The document that was closed.
+ */
+ TextDocument TextDocumentIdentifier `json:"textDocument"`
+}
diff --git a/internal/lsp/protocol/window.go b/internal/lsp/protocol/window.go
new file mode 100644
index 0000000..1105568
--- /dev/null
+++ b/internal/lsp/protocol/window.go
@@ -0,0 +1,77 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the corresponding structures to the
+// "Window" messages part of the LSP specification.
+
+package protocol
+
+type ShowMessageParams struct {
+ /**
+ * The message type. See {@link MessageType}.
+ */
+ Type MessageType `json:"type"`
+
+ /**
+ * The actual message.
+ */
+ Message string `json:"message"`
+}
+
+type MessageType float64
+
+const (
+ /**
+ * An error message.
+ */
+ Error MessageType = 1
+ /**
+ * A warning message.
+ */
+ Warning MessageType = 2
+ /**
+ * An information message.
+ */
+ Info MessageType = 3
+ /**
+ * A log message.
+ */
+ Log MessageType = 4
+)
+
+type ShowMessageRequestParams struct {
+ /**
+ * The message type. See {@link MessageType}.
+ */
+ Type MessageType `json:"type"`
+
+ /**
+ * The actual message.
+ */
+ Message string `json:"message"`
+
+ /**
+ * The message action items to present.
+ */
+ Actions []MessageActionItem `json:"actions,omitempty"`
+}
+
+type MessageActionItem struct {
+ /**
+ * A short title like 'Retry', 'Open Log' etc.
+ */
+ Title string
+}
+
+type LogMessageParams struct {
+ /**
+ * The message type. See {@link MessageType}.
+ */
+ Type MessageType `json:"type"`
+
+ /**
+ * The actual message.
+ */
+ Message string `json:"message"`
+}
diff --git a/internal/lsp/protocol/workspace.go b/internal/lsp/protocol/workspace.go
new file mode 100644
index 0000000..c465849
--- /dev/null
+++ b/internal/lsp/protocol/workspace.go
@@ -0,0 +1,203 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the corresponding structures to the
+// "Workspace" part of the LSP specification.
+
+package protocol
+
+type WorkspaceFolder struct {
+ /**
+ * The associated URI for this workspace folder.
+ */
+ URI string `json:"uri"`
+
+ /**
+ * The name of the workspace folder. Defaults to the
+ * uri's basename.
+ */
+ Name string `json:"name"`
+}
+
+type DidChangeWorkspaceFoldersParams struct {
+ /**
+ * The actual workspace folder change event.
+ */
+ Event WorkspaceFoldersChangeEvent `json:"event"`
+}
+
+/**
+ * The workspace folder change event.
+ */
+type WorkspaceFoldersChangeEvent struct {
+ /**
+ * The array of added workspace folders
+ */
+ Added []WorkspaceFolder `json:"added"`
+
+ /**
+ * The array of the removed workspace folders
+ */
+ Removed []WorkspaceFolder `json:"removed"`
+}
+
+type DidChangeConfigurationParams struct {
+ /**
+ * The actual changed settings
+ */
+ Settings interface{} `json:"settings"`
+}
+
+type ConfigurationParams struct {
+ Items []ConfigurationItem `json:"items"`
+}
+
+type ConfigurationItem struct {
+ /**
+ * The scope to get the configuration section for.
+ */
+ ScopeURI string `json:"scopeURI,omitempty"`
+
+ /**
+ * The configuration section asked for.
+ */
+ Section string `json:"section,omitempty"`
+}
+
+type DidChangeWatchedFilesParams struct {
+ /**
+ * The actual file events.
+ */
+ Changes []FileEvent `json:"changes"`
+}
+
+/**
+ * An event describing a file change.
+ */
+type FileEvent struct {
+ /**
+ * The file's URI.
+ */
+ URI DocumentURI `json:"uri"`
+ /**
+ * The change type.
+ */
+ Type float64 `json:"type"`
+}
+
+/**
+ * The file event type.
+ */
+type FileChangeType float64
+
+const (
+ /**
+ * The file got created.
+ */
+ Created FileChangeType = 1
+ /**
+ * The file got changed.
+ */
+ Changed FileChangeType = 2
+ /**
+ * The file got deleted.
+ */
+ Deleted FileChangeType = 3
+)
+
+/**
+ * Describe options to be used when registering for text document change events.
+ */
+type DidChangeWatchedFilesRegistrationOptions struct {
+ /**
+ * The watchers to register.
+ */
+ Watchers []FileSystemWatcher `json:"watchers"`
+}
+
+type FileSystemWatcher struct {
+ /**
+ * The glob pattern to watch
+ */
+ GlobPattern string `json:"globPattern"`
+
+ /**
+ * The kind of events of interest. If omitted it defaults
+ * to WatchKind.Create | WatchKind.Change | WatchKind.Delete
+ * which is 7.
+ */
+ Kind float64 `json:"kind,omitempty"`
+}
+
+type WatchKind float64
+
+const (
+ /**
+ * Interested in create events.
+ */
+ Create WatchKind = 1
+
+ /**
+ * Interested in change events
+ */
+ Change WatchKind = 2
+
+ /**
+ * Interested in delete events
+ */
+ Delete WatchKind = 4
+)
+
+/**
+ * The parameters of a Workspace Symbol Request.
+ */
+type WorkspaceSymbolParams struct {
+ /**
+ * A non-empty query string
+ */
+ Query string `json:"query"`
+}
+
+type ExecuteCommandParams struct {
+
+ /**
+ * The identifier of the actual command handler.
+ */
+ Command string `json:"command"`
+ /**
+ * Arguments that the command should be invoked with.
+ */
+ Arguments []interface{} `json:"arguments,omitempty"`
+}
+
+/**
+ * Execute command registration options.
+ */
+type ExecuteCommandRegistrationOptions struct {
+ /**
+ * The commands to be executed on the server
+ */
+ Commands []string `json:"commands"`
+}
+
+type ApplyWorkspaceEditParams struct {
+ /**
+ * An optional label of the workspace edit. This label is
+ * presented in the user interface for example on an undo
+ * stack to undo the workspace edit.
+ */
+ Label string `json:"label,omitempty"`
+
+ /**
+ * The edits to apply.
+ */
+ Edit WorkspaceEdit `json:"edit"`
+}
+
+type ApplyWorkspaceEditResponse struct {
+ /**
+ * Indicates whether the edit was applied or not.
+ */
+ Applied bool `json:"applied"`
+}