Protocole de serveur de langageLanguage Server Protocol

Qu’est le protocole de serveur de langage ?What is the Language Server Protocol?

Prise en charge de riches fonctionnalités d’édition comme source code saisie automatique ou atteindre la définition pour un langage de programmation dans un éditeur ou l’IDE est généralement très difficile et fastidieuse.Supporting rich editing features like source code auto-completions or Go to Definition for a programming language in an editor or IDE is traditionally very challenging and time consuming. Généralement il nécessite l’écriture d’un modèle de domaine (un scanneur, un analyseur, un outil de vérification de type, un générateur et bien plus encore) dans le langage de programmation de l’éditeur ou IDE.Usually it requires writing a domain model (a scanner, a parser, a type checker, a builder and more) in the programming language of the editor or IDE. Par exemple, le plug-in Eclipse CDT, qui fournit la prise en charge pour C/C++ dans l’IDE Eclipse est écrit en Java, car l’IDE Eclipse lui-même est écrit en Java.For example, the Eclipse CDT plugin, which provides support for C/C++ in the Eclipse IDE is written in Java since the Eclipse IDE itself is written in Java. Selon cette approche, il signifie implémenter un modèle de domaine dans TypeScript pour Visual Studio Code C/C++ et un modèle de domaine distincts en c# pour Visual Studio.Following this approach, it would mean implementing a C/C++ domain model in TypeScript for Visual Studio Code, and a separate domain model in C# for Visual Studio.

Création de modèles de domaine spécifique à la langue est également beaucoup plus faciles si un outil de développement peut réutiliser les bibliothèques spécifiques au langage existantes.Creating language-specific domain models are also a lot easier if a development tool can reuse existing language-specific libraries. Toutefois, ces bibliothèques sont généralement implémentées dans le langage de programmation lui-même (par exemple, une bonne C/C++ domaine modèles sont implémentées en C/C++).However, these libraries are usually implemented in the programming language itself (for example, good C/C++ domain models are implemented in C/C++). L’intégration d’une bibliothèque C/C++ dans un éditeur écrit en TypeScript est techniquement possible mais difficile à gérer.Integrating a C/C++ library into an editor written in TypeScript is technically possible but hard to do.

Serveurs de langueLanguage servers

Une autre approche consiste à exécuter la bibliothèque dans son propre processus et de communication entre processus permet de communiquer avec elle.Another approach is to run the library in its own process and use inter-process communication to talk to it. Les messages envoyés dans les deux sens forment un protocole.The messages sent back and forth form a protocol. Le protocole de serveur de langage (LSP) est le produit suivant : standardiser les messages échangés entre un outil de développement et un processus de serveur de langage.The language server protocol (LSP) is the product of standardizing the messages exchanged between a development tool and a language server process. À l’aide de serveurs de langage ou fées n’est pas une idée de nouveau ou nouvelle.Using language servers or demons is not a new or novel idea. Éditeurs, tels que Vim et Emacs ont été cela pendant un certain temps prendre en charge les sémantiques la saisie semi-automatique.Editors like Vim and Emacs have been doing this for some time to provide semantic auto-completion support. L’objectif des LSP était de simplifier ces sortes d’intégrations et fournissent un cadre utile pour exposer des fonctionnalités de langage à un large éventail d’outils.The goal of the LSP was to simplify these sorts of integrations and provide a useful framework for exposing language features to a variety of tools.

Un protocole commun permet l’intégration de fonctionnalités de langage de programmation dans un outil de développement avec un minimum d’efforts en réutilisant une implémentation existante de la langue modèle de domaine.Having a common protocol allows the integration of programming language features into a development tool with minimal fuss by reusing an existing implementation of the language's domain model. Un serveur de langage back-end peut être écrit en PHP, Python ou Java et le partenaire LSP lui permet d’être facilement intégrés à un large éventail d’outils.A language server back-end could be written in PHP, Python, or Java and the LSP lets it be easily integrated into a variety of tools. Le protocole fonctionne à un niveau d’abstraction commun afin qu’un outil peut offrir des services de langage enrichi sans avoir à apprécier pleinement les nuances spécifiques au modèle de domaine sous-jacent.The protocol works at a common level of abstraction so that a tool can offer rich language services without needing to fully understand the nuances specific to the underlying domain model.

Fonctionnement des LSP démarréHow work on the LSP started

Le LSP a évolué au fil du temps et il est aujourd'hui à la Version 3.0.The LSP has evolved over time and today it is at Version 3.0. Il démarré lorsque le concept d’un serveur de langage a été récupéré par OmniSharp pour fournir des fonctionnalités d’édition riches pour c#.It started when the concept of a language server was picked up by OmniSharp to provide rich editing features for C#. Initialement, OmniSharp utilisé le protocole HTTP avec une charge utile JSON et ont été intégrée dans plusieurs éditeurs notamment Visual Studio Code.Initially, OmniSharp used the HTTP protocol with a JSON payload and has been integrated into several editors including Visual Studio Code.

En même temps, Microsoft commencer à travailler sur un serveur de langage TypeScript, avec l’idée de prendre en charge de TypeScript dans les éditeurs comme Emacs et Sublime Text.Around the same time, Microsoft started to work on a TypeScript language server, with the idea of supporting TypeScript in editors like Emacs and Sublime Text. Dans cette implémentation, un éditeur communique via stdin/stdout avec le processus de serveur de TypeScript et utilise une inspiré par le protocole de débogueur V8 de charge utile JSON pour les demandes et réponses.In this implementation, an editor communicates through stdin/stdout with the TypeScript server process and uses a JSON payload inspired by the V8 debugger protocol for requests and responses. Le serveur de TypeScript a été intégré dans le plug-in Sublime TypeScript et le Code de Visual Studio pour la modification de TypeScript riche.The TypeScript server has been integrated into the TypeScript Sublime plugin and VS Code for rich TypeScript editing.

Après avoir intégré à deux serveurs de langue différente, l’équipe Visual Studio Code démarré l’exploration d’un protocole de serveur de langage commun pour les éditeurs et différents IDE.After having integrated two different language servers, the VS Code team started to explore a common language server protocol for editors and IDEs. Un protocole commun permet à un fournisseur de langage créer un serveur de langue unique qui peut être consommé par différents IDE.A common protocol enables a language provider to create a single language server that can be consumed by different IDEs. Un consommateur de serveur de langage a uniquement implémenter le côté client du protocole qu’une seule fois.A language server consumer only has to implement the client side of the protocol once. Cela entraîne une situation gagnant-gagnant pour le fournisseur de langages et le consommateur de langage.This results in a win-win situation for both the language provider and the language consumer.

Le protocole de serveur de langage démarrer avec le protocole utilisé par le serveur de TypeScript, développée avec plusieurs fonctionnalités de langage inspirées par l’API de langage de Visual Studio Code.The language server protocol started with the protocol used by the TypeScript server, expanding it with more language features inspired by the VS Code language API. Le protocole est sauvegardé avec JSON-RPC pour l’appel distant en raison de sa simplicité et les bibliothèques existantes.The protocol is backed with JSON-RPC for remote invocation due to its simplicity and existing libraries.

Les VS Code équipe prototypée le protocole en implémentant plusieurs serveurs de langage linter qui répondent à des demandes à lint (analyse) un fichier et renvoyer un ensemble d’erreurs et avertissements détectés.The VS Code team prototyped the protocol by implementing several linter language servers which respond to requests to lint (scan) a file and return a set of detected warnings and errors. L’objectif était de lint un fichier en tant que les modifications d’utilisateurs dans un document, ce qui signifie qu’il y aura de demandes de linting pendant une session de l’éditeur.The goal was to lint a file as the user edits in a document, which means that there will be many linting requests during an editor session. Il paraissait logique pour maintenir un serveur de configuration et en cours d’exécution afin qu’un nouveau processus de validation lint n’était pas nécessaire au démarrage de chaque modification de l’utilisateur.It made sense to keep a server up and running so that a new linting process did not need to be started for each user edit. Plusieurs serveurs linter ont été implémentées, y compris du Code Visual Studio extensions ESLint et TSLint.Several linter servers were implemented, including VS Code's ESLint and TSLint extensions. Ces deux serveurs linter sont implémentées dans TypeScript/JavaScript et exécuter sur Node.js.These two linter servers are both implemented in TypeScript/JavaScript and run on Node.js. Ils partagent une bibliothèque qui implémente la partie client et le serveur du protocole.They share a library that implements the client and server part of the protocol.

Fonctionne des LSPHow the LSP works

Un serveur de langage s’exécute dans son propre processus et outils tels que Visual Studio ou VS Code communiquent avec le serveur à l’aide du protocole de langage sur JSON-RPC.A language server runs in its own process, and tools like Visual Studio or VS Code communicate with the server using the language protocol over JSON-RPC. Un autre avantage de la langue de fonctionnement du serveur dans un processus dédié est que les problèmes de performances liés à un modèle de processus unique sont évités.Another advantage of the language server operating in a dedicated process is that performance issues related to a single process model are avoided. Le canal de transport réel peut être stdio, sockets, canaux nommés ou nœud ipc si le client et le serveur sont écrits en Node.js.The actual transport channel can either be stdio, sockets, named pipes, or node ipc if both the client and server are written in Node.js.

Ci-dessous est un exemple de la façon dont un outil et un serveur de langage communiquent durant une routine de session d’édition :Below is an example for how a tool and a language server communicate during a routine editing session:

diagramme de flux LSP

  • L’utilisateur ouvre un fichier (appelé un document) dans l’outil: l’outil avertit le serveur de langage qu’un document est ouvert (' textDocument/didOpen »).The user opens a file (referred to as a document) in the tool: The tool notifies the language server that a document is open ('textDocument/didOpen'). Dès lors, la vérité sur le contenu du document n’est plus sur le système de fichiers mais conservée par l’outil dans la mémoire.From now on, the truth about the contents of the document is no longer on the file system but kept by the tool in memory.

  • L’utilisateur apporte des modifications: l’outil informe le serveur sur la modification de document (« textDocument/didChange ») et les informations de sémantique du programme sont mis à jour par le serveur de langage.The user makes edits: The tool notifies the server about the document change ('textDocument/didChange') and the semantic information of the program is updated by the language server. Dans ce cas, le serveur de langage analyse ces informations et avertit l’outil avec les erreurs détectées et les avertissements (« textDocument/publishDiagnostics »).As this happens, the language server analyzes this information and notifies the tool with the detected errors and warnings ('textDocument/publishDiagnostics').

  • L’utilisateur exécute « Atteindre la définition » sur un symbole dans l’éditeur: l’outil envoie une demande de « textDocument/définition » avec deux paramètres : (1) l’URI de document et (2) la position du texte à partir d’où la demande de définition d’atteindre a été lancée sur le serveur.The user executes "Go to Definition" on a symbol in the editor: The tool sends a 'textDocument/definition' request with two parameters: (1) the document URI and (2) the text position from where the Go to Definition request was initiated to the server. Le serveur répond avec l’URI de document et de la position de la définition du symbole à l’intérieur du document.The server responds with the document URI and the position of the symbol's definition inside the document.

  • L’utilisateur ferme le document (fichier): envoi d’une notification de ' textDocument/didClose' à partir de l’outil, qui informe le serveur de langage qui le document est maintenant n’est plus en mémoire et que le contenu actuel est maintenant à jour sur le système de fichiers.The user closes the document (file): A 'textDocument/didClose' notification is sent from the tool, informing the language server that the document is now no longer in memory and that the current contents is now up to date on the file system.

Cet exemple illustre la façon dont le protocole communique avec le serveur de langage au niveau des fonctionnalités de l’éditeur « Atteindre la définition », « Rechercher toutes les références ».This example illustrates how the protocol communicates with the language server at the level of editor features like "Go to Definition", "Find all References". Les types de données utilisés par le protocole sont éditeur ou IDE, types de données tels que le document actuellement ouvert et la position du curseur.The data types used by the protocol are editor or IDE 'data types' like the currently open text document and the position of the cursor. Les types de données ne sont pas au niveau d’un modèle de domaine langage programmation, ce qui vous donne généralement des arborescences de syntaxe abstraite et des symboles de compilation (par exemple, types résolues, espaces de noms,...). Cela simplifie considérablement le protocole.The data types are not at the level of a programming language domain model which would usually provide abstract syntax trees and compiler symbols (for example, resolved types, namespaces, ...). This simplifies the protocol significantly.

Maintenant nous allons examiner la demande « textDocument/définition » plus en détail.Now let's look at the 'textDocument/definition' request in more detail. Voici les charges utiles qui vont entre l’outil client et le serveur de langage pour la demande « Atteindre la définition » dans un document de C++.Below are the payloads that go between the client tool and the language server for the "Go to Definition" request in a C++ document.

Il s’agit de la demande :This is the request:

{
    "jsonrpc": "2.0",
    "id" : 1,
    "method": "textDocument/definition",
    "params": {
        "textDocument": {
            "uri": "file:///p%3A/mseng/VSCode/Playgrounds/cpp/use.cpp"
        },
        "position": {
            "line": 3,
            "character": 12
        }
    }
}

Il s’agit de la réponse :This is the response:

{
    "jsonrpc": "2.0",
    "id": "1",
    "result": {
        "uri": "file:///p%3A/mseng/VSCode/Playgrounds/cpp/provide.cpp",
        "range": {
            "start": {
                "line": 0,
                "character": 4
            },
            "end": {
                "line": 0,
                "character": 11
            }
        }
    }
}

Rétrospectivement, décrivant les types de données au niveau de l’éditeur, plutôt qu’au niveau du modèle de langage de programmation est une des raisons de la réussite du protocole du serveur de langage.In retrospect, describing the data types at the level of the editor rather than at the level of the programming language model is one of the reasons for the success of the language server protocol. Il est beaucoup plus simple normaliser les URI de document texte ou une position de curseur par rapport à standardiser une symboles de compilateur et d’arborescence de syntaxe abstraite entre les différents langages de programmation.It is much simpler to standardize a text document URI or a cursor position compared with standardizing an abstract syntax tree and compiler symbols across different programming languages.

Lorsqu’un utilisateur travaille avec différentes langues, VS Code démarre généralement un serveur de langage pour chaque langage de programmation.When a user is working with different languages, VS Code typically starts a language server for each programming language. L’exemple ci-dessous montre une session où l’utilisateur travaille sur les fichiers Java et SASS.The example below shows a session where the user works on Java and SASS files.

Java et sass

FonctionnalitésCapabilities

Pas de chaque serveur de langage peut prendre en charge toutes les fonctionnalités définies par le protocole.Not every language server can support all features defined by the protocol. Par conséquent, le client et le serveur annonce leur jeu de fonctionnalités prises en charge par le biais « fonctionnalités ».Therefore, the client and server announces their supported feature set through 'capabilities'. Par exemple, un serveur annonce qu’il puisse traiter la demande de « textDocument/définition », mais il peut ne pas gérer la demande 'espace de travail/symbol'.As an example, a server announces that it can handle the 'textDocument/definition' request, but it might not handle the 'workspace/symbol' request. De même, les clients peuvent annoncer qu’ils sont en mesure de fournir « sur le point d’enregistrer' notifications avant l’enregistrée d’un document, afin qu’un serveur peut calculer des modifications textuelles pour mettre en forme automatiquement le document modifié.Similarly, clients can announce that they are able to provide 'about to save' notifications before a document is saved, so that a server can compute textual edits to automatically format the edited document.

Intégration d’un serveur de langageIntegrating a language server

L’intégration réelle d’un serveur de langage à un outil particulier n’est pas définie par le protocole de serveur de langage et le reste pour les implémenteurs de l’outil.The actual integration of a language server into a particular tool is not defined by the language server protocol and is left to the tool implementors. Certains outils intègrent les serveurs de langage de façon générique en ayant une extension qui peut commencer et communiquer avec n’importe quel type de serveur de langage.Some tools integrate language servers generically by having an extension that can start and talk to any kind of language server. D’autres, tels que Visual Studio Code, créez une extension personnalisée par serveur de langage, afin qu’une extension est toujours en mesure de fournir des fonctionnalités de langue personnalisé.Others, like VS Code, create a custom extension per language server, so that an extension is still able to provide some custom language features.

Pour simplifier l’implémentation de serveurs de langage et les clients, il existe les bibliothèques ou les kits de développement logiciel pour les parties client et serveur.To simplify the implementation of language servers and clients, there are libraries or SDKs for the client and server parts. Ces bibliothèques sont fournis pour des langues différentes.These libraries are provided for different languages. Par exemple, il existe un module npm de client language pour faciliter l’intégration d’un serveur de langage dans une extension VS Code et l’autre module npm de serveur language pour écrire une langue serveur à l’aide de Node.js.For example, there is a language client npm module to ease the integration of a language server into a VS Code extension and another language server npm module to write a language server using Node.js. Il s’agit d’actuel liste des bibliothèques de prise en charge.This is the current list of support libraries.

L’aide du protocole de serveur de langage dans Visual StudioUsing the Language Server Protocol in Visual Studio