lsp 3.17协议规范文档 - 1 - 基础协议
文档翻译自:Language Server Protocol Specification - 3.17 https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/
本文档描述了 3.17.x 版本的语言服务器协议。 可以在此处找到协议 3.17.x 版本的node实现:https://github.com/Microsoft/vscode-languageserver-node。
注意:可以通过针对此文档https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/lsp/3.17/specification.md提交pull request来编辑本文档。
What’s new in 3.17
所有新的 3.17 功能都使用相应的“自版本 3.17”或在 JSDoc 中使用 @since 3.17.0 注释进行标记。 主要的新功能是:类型层次结构、内联值、嵌入提示、笔记本文档支持和描述 3.17 LSP 版本的元模型。
可以在change log中找到更改的详细列表
版本号是用于将新特性归类到新的版本中,比如可以标记某个特性是从哪个版本开始出现的。 规范中的功能使用“capability”标志保持兼容,这些兼容性标志会在客户端和服务器初始化期间进行数据交换。
基础协议
基本协议由标头和内容部分组成(类似于 HTTP)。 标题和内容部分由“\r\n”分隔。
标头部分
标头部分由标头字段组成。 每个标头字段由一个名称和一个值组成,由“: ”(一个冒号和一个空格)分隔。 标头字段的结构符合 HTTP 语义。 每个字段都以‘\r\n’结束。 考虑到最后一个标头字段和整个标头本身都以 '\r\n' 结尾,这意味着在整个标头和消息内容部分由两个/r/n分割。
目前支持以下字段:
| 字段名称 | Value Type | 说明 |
|---|---|---|
| Content-Length | 数字 | 内容部分的长度(以字节为单位)。 此标头必填。 |
| Content-Type | 字符 | 内容部分的 MIME 类型。 默认为 application/vscode-jsonrpc; charset=utf-8 |
标头部分和分隔标题和内容部分的“\r\n”都使用“ascii”编码进行编码。
内容部分
包含消息的实际内容。 消息的内容部分使用 JSON-RPC(http://www.jsonrpc.org/) 来描述请求、响应和通知。 内容部分使用标头字段Content-Type中指定的字符集进行编码。 它默认为 utf-8,这是目前唯一支持的编码。 如果服务器或客户端收到一个编码不同于 utf-8 的标头,会返回一个错误。
(Prior versions of the protocol used the string constant utf8 which is not a correct encoding constant according to specification.) For backwards compatibility it is highly recommended that a client and a server treats the string utf8 as utf-8.
(协议的早期版本使用字符串常量 utf8,根据规范(http://www.iana.org/assignments/character-sets/character-sets.xhtml),它不是正确的编码常量,少了“-”横线,应该是utf-8。)为了向后兼容,强烈建议客户端和服务器将字符串 utf8 视为 utf-8。
示例:
Content-Length: ...\r\n
\r\n
{
"jsonrpc": "2.0",
"id": 1,
"method": "textDocument/didOpen",
"params": {
...
}
}
基本协议 JSON 结构
以下 TypeScript 定义描述了基本的 JSON-RPC 协议(http://www.jsonrpc.org/specification)
基础数据类型
该协议对整数、无符号整数、十进制数、对象和数组使用以下定义::
/**
* Defines an integer number in the range of -2^31 to 2^31 - 1.
*/
export type integer = number;
/**
* Defines an unsigned integer number in the range of 0 to 2^31 - 1.
*/
export type uinteger = number;
/**
* Defines a decimal number. Since decimal numbers are very
* rare in the language server specification we denote the
* exact range with every decimal using the mathematics
* interval notation (e.g. [0, 1] denotes all decimals d with
* 0 <= d <= 1.
*/
export type decimal = number;
/**
* The LSP any type
*
* @since 3.17.0
*/
export type LSPAny = LSPObject | LSPArray | string | integer | uinteger |
decimal | boolean | null;
/**
* LSP object definition.
*
* @since 3.17.0
*/
export type LSPObject = { [key: string]: LSPAny };
/**
* LSP arrays.
*
* @since 3.17.0
*/
export type LSPArray = LSPAny[];
抽象消息
JSON-RPC 定义的普通消息结构如下。 lsp使用“2.0”作为 jsonrpc 版本。
interface Message {
jsonrpc: string;
}
请求消息
请求消息描述客户端和服务器之间的请求。 每个请求处理完成后都必须回复响应消息给请求发起方。
interface RequestMessage extends Message {
/**
* The request id.
*/
id: integer | string;
/**
* The method to be invoked.
*/
method: string;
/**
* The method's params.
*/
params?: array | object;
}
响应消息
响应消息表示请求处理的结果。 如果响应没有result值,请求消息的处理方仍然需要返回响应消息以符合 JSON-RPC 规范。 在这种情况下,应将 ResponseMessage 的结果属性设置为 null 以表示请求成功。
interface ResponseMessage extends Message {
/**
* The request id.
*/
id: integer | string | null;
/**
* The result of a request. This member is REQUIRED on success.
* This member MUST NOT exist if there was an error invoking the method.
*/
result?: string | number | boolean | object | null;
/**
* The error object in case a request fails.
*/
error?: ResponseError;
}
interface ResponseError {
/**
* A number indicating the error type that occurred.
*/
code: integer;
/**
* A string providing a short description of the error.
*/
message: string;
/**
* A primitive or structured value that contains additional
* information about the error. Can be omitted.
*/
data?: string | number | boolean | array | object | null;
}
export namespace ErrorCodes {
// Defined by JSON-RPC
export const ParseError: integer = -32700;
export const InvalidRequest: integer = -32600;
export const MethodNotFound: integer = -32601;
export const InvalidParams: integer = -32602;
export const InternalError: integer = -32603;
/**
* This is the start range of JSON-RPC reserved error codes.
* It doesn't denote a real error code. No LSP error codes should
* be defined between the start and end range. For backwards
* compatibility the `ServerNotInitialized` and the `UnknownErrorCode`
* are left in the range.
*
* @since 3.16.0
*/
export const jsonrpcReservedErrorRangeStart: integer = -32099;
/** @deprecated use jsonrpcReservedErrorRangeStart */
export const serverErrorStart: integer = jsonrpcReservedErrorRangeStart;
/**
* Error code indicating that a server received a notification or
* request before the server has received the `initialize` request.
*/
export const ServerNotInitialized: integer = -32002;
export const UnknownErrorCode: integer = -32001;
/**
* This is the end range of JSON-RPC reserved error codes.
* It doesn't denote a real error code.
*
* @since 3.16.0
*/
export const jsonrpcReservedErrorRangeEnd = -32000;
/** @deprecated use jsonrpcReservedErrorRangeEnd */
export const serverErrorEnd: integer = jsonrpcReservedErrorRangeEnd;
/**
* This is the start range of LSP reserved error codes.
* It doesn't denote a real error code.
*
* @since 3.16.0
*/
export const lspReservedErrorRangeStart: integer = -32899;
/**
* A request failed but it was syntactically correct, e.g the
* method name was known and the parameters were valid. The error
* message should contain human readable information about why
* the request failed.
*
* @since 3.17.0
*/
export const RequestFailed: integer = -32803;
/**
* The server cancelled the request. This error code should
* only be used for requests that explicitly support being
* server cancellable.
*
* @since 3.17.0
*/
export const ServerCancelled: integer = -32802;
/**
* The server detected that the content of a document got
* modified outside normal conditions. A server should
* NOT send this error code if it detects a content change
* in it unprocessed messages. The result even computed
* on an older state might still be useful for the client.
*
* If a client decides that a result is not of any use anymore
* the client should cancel the request.
*/
export const ContentModified: integer = -32801;
/**
* The client has canceled a request and a server as detected
* the cancel.
*/
export const RequestCancelled: integer = -32800;
/**
* This is the end range of LSP reserved error codes.
* It doesn't denote a real error code.
*
* @since 3.16.0
*/
export const lspReservedErrorRangeEnd: integer = -32800;
}
通知消息
通知消息处理完成后不用回复响应,类似于一个事件通知的机制
interface NotificationMessage extends Message {
/**
* The method to be invoked.
*/
method: string;
/**
* The notification's params.
*/
params?: array | object;
}
$通知与请求
“$/”开头的通知和请求是依赖于协议实现的,可能无法在所有客户端或服务器中实现。 例如,如果服务器实现使用单线程同步编程语言,那么服务器几乎无法对 $/cancelRequest 通知做出反应。 如果服务器或客户端收到以“$/”开头的通知,则可以忽略该通知。 如果服务器或客户端收到以“$/”开头的请求,则它必须使用错误代码 MethodNotFound(例如 -32601)对请求进行错误处理。
取消请求
基本协议支持取消请求。 要取消请求,将发送具有以下属性的通知消息:
Notification:
- method: ‘$/cancelRequest’
- params:
CancelParams定义如下
interface CancelParams {
/**
* 要取消的请求id.
*/
id: integer | string;
}
被取消的请求仍然需要从服务器返回并发回响应。 它不能被挂起。 这符合每个请求都要发回响应的 JSON-RPC 协议规范。 此外,它允许在取消时返回部分结果。 如果要在该请求被取消时返回错误响应,建议将错误代码设置为 ErrorCodes.RequestCancelled。
进度支持(自3.15.0之后)
基本协议还支持以通用方式报告进度。 此机制可用于报告任何类型的进度,包括工作完成进度(通常用于使用进度条在用户界面中报告进度)和结果流形式的部分结果进度。
进度通知包含以下属性
Notification:
- method: ‘$/progress’
- params:
ProgressParams定义如下:
type ProgressToken = integer | string;
interface ProgressParams<T> {
/**
* The progress token provided by the client or server.
*/
token: ProgressToken;
/**
* The progress data.
*/
value: T;
}
根据token报告进度。 token不同于request ID,token允许报告非请求类的进度,如通知等 。

浙公网安备 33010602011771号