语言服务协议

语言服务器协议定义了一组 JSON-RPC 请求、响应和通知消息,这些消息使用 基本协议 进行交换。本节开始介绍协议中使用的基本 JSON 结构。本文档使用 TypeScript 在严格模式下的 interface 来描述这些内容。这意味着,例如,必须显式列出 null 值,并且必须列出必需属性,即使可能存在窜改值。基于基本的 JSON 结构,描述了实际请求及其响应和通知。

例如,从客户端向服务器发送请求,以请求文本文档中特定位置的符号的悬停提示。请求的方法将是 textDocument/hover,其参数如下:

interface HoverParams {
	textDocument: string; /** The text document's URI in string form */
	position: { line: uinteger; character: uinteger; };
}

请求的结果是将要呈现的悬浮提示。在其简单形式中,它可以是一个字符串。所以结果如下所示:

interface HoverResult {
	value: string;
}

另请注意,响应返回值为 null 表示没有结果。它不会告诉客户端重新发送请求。

通常,语言服务协议支持 JSON-RPC 消息,但是,我们约定传递给 请求通知消息的参数为对象类型(如果传递的话)。但是,这并不禁止在自定义消息中使用数组参数类型。

该协议目前假定一个服务器服务于一个工具。该协议目前不支持在不同工具之间共享一个服务器。这种共享将需要额外的协议,例如锁定文档以支持并发编辑。

能力 (Capabilities)

并非每个语言服务器都可以支持协议定义的所有功能。LSP 因此提供了 capabilities。一个能力组对应一套语言功能。开发工具和语言服务器使用 capabilities 宣布其支持的功能。例如,例如,服务器宣布它可以处理 textDocument/hover 请求,但可能无法处理 workspace/symbol 请求。同样,开发工具宣布其能够在保存文档之前提供关于保存的通知,以便服务器可以在保存之前计算文本以格式化编辑的文档。

在初始化 initialize 请求期间,客户端和服务器之间交换 capabilities 的集合。

请求、响应和通知的顺序

对请求的响应的发送顺序应与请求在服务器端或客户端上出现的顺序大致相同。因此,例如,如果服务器收到 textDocument/completion 请求,然后收到 textDocument/signatureHelp 请求,它通常会首先返回 textDocument/completion 的响应,然后返回 textDocument/signatureHelp 的响应。

但是,服务器可能决定使用并行执行策略,并且可能希望以与收到请求不同的顺序返回响应。只要此重新排序不影响响应的正确性,服务器就可以这样做。例如,允许对 textDocument/completiontextDocument/signatureHelp 的结果重新排序,因为这些请求中的每一个通常不会影响另一个请求的输出。另一方面,服务器很可能不应该对 textDocument/definitiontextDocument/rename 请求重新排序,因为执行后者可能会影响前者的结果。

消息文档

和前面一样,LSP 定义了一组请求、响应和通知。在后面对这些消息的描述中,每一项都使用以下格式进行描述:

  • 描述请求的标头

  • 一个可选的 客户端能力(Client capability) 部分,描述了请求的客户端能力。这包括客户端能力属性路径和 json 结构。

  • 一个可选的 服务端能力(Server Capability) 部分,描述了请求的服务端能力,这包括服务端能力属性路径和 json 结构。客户端应该忽略他们不理解的服务端功能(例如,在这种情况下,初始化请求不应该失败)。

  • 一个可选的 注册选项(Registration Options) 部分,描述请求或通知支持动态功能注册时的注册选项。请参阅 注册注销 请求,详细了解其工作原理。

  • 一个 请求(Request) 部分描述发送请求的格式。该方法是标识请求的字符串,参数使用 TypeScript 接口进行记录。它还记录了请求是否支持已完成的工作进度和部分结果进度。

  • 一个 响应(Response) 部分描述了响应的格式。结果项描述成功时返回的数据。可选的部分结果项描述部分结果通知的返回数据。error.data 描述发生错误时返回的数据。请记住,如果失败,响应已包含 error.codeerror.message 字段。仅当协议强制使用某些错误代码或消息时,才指定这些字段。如果服务器可以自由决定这些值,则此处未列出这些值。