|
| 1 | +# Puppet Language Server |
| 2 | + |
| 3 | +## Description |
| 4 | + |
| 5 | +The Puppet Language Server is an out-of-process server which a language server client can conect to and then issue requests for long running tasks. For example, parsing files for validity or installing a module. |
| 6 | + |
| 7 | +The language server complies with version 3.0 of the [Language Server Protocol](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md) although not all capabilities are implemented. For example the `documentSymbol` provider is not available to the client. |
| 8 | + |
| 9 | +The architecture of the puppet language server is that: |
| 10 | + |
| 11 | +- The language server is written in Ruby which means it has access to a pretty much every thing Puppet Agent does; facts, parser, lexer, compiler etc.. This means the language server is extremely powerful |
| 12 | + |
| 13 | +- It _only_ requires the ruby environment from the Puppet Agent to be able to run. This means gems with Native Extensions can not be used, and that any gems not explicitly supplied by Puppet Agent must be vendored inside the langauge server. |
| 14 | + |
| 15 | +Note - This requirement may disappear with the advent of a Puppet SDK, however at the time of writing that was not available. |
| 16 | + |
| 17 | +## Source Layout |
| 18 | + |
| 19 | +The source code for the language server is laid out as follows: |
| 20 | + |
| 21 | +``` |
| 22 | ++- lib |
| 23 | +| +- languageserver |
| 24 | +| | +- Files in this directory are for creating the various |
| 25 | +| | generic messages as part of the language server protocol |
| 26 | +| | |
| 27 | +| +- puppet-languageserver |
| 28 | +| +- Files in this directory are for the implementing the |
| 29 | +| actual puppet language server |
| 30 | +| |
| 31 | ++- puppet-languageserver - This file is the main entrypoint to run the server |
| 32 | +``` |
| 33 | + |
| 34 | +The server README contains information on how to run the server |
| 35 | + |
| 36 | +## Architecture |
| 37 | + |
| 38 | +The language server is built up in layers, similar to the OSI model in networking; where each layer builds up on top the next. |
| 39 | + |
| 40 | +``` |
| 41 | ++-----------------------------+ |
| 42 | +| | |
| 43 | +| Puppet / Facter / Hiera | |
| 44 | +| | |
| 45 | ++-----------------------------+ |
| 46 | +| | |
| 47 | +| Puppet Helpers | |
| 48 | +| | |
| 49 | ++-----------------------------+ |
| 50 | +| | |
| 51 | +| Providers | |
| 52 | +| | |
| 53 | ++-----------------------------+ |
| 54 | +| | |
| 55 | +| Message Router | |
| 56 | +| | |
| 57 | ++-----------------------------+ |
| 58 | +| | |
| 59 | +| JSON RPC Handler | |
| 60 | +| | |
| 61 | ++-----------------------------+ |
| 62 | +| | |
| 63 | +| Generic client connection | |
| 64 | +| | |
| 65 | ++-----------------------------+ |
| 66 | +| | |
| 67 | +| TCP Server | |
| 68 | +| | |
| 69 | ++-----------------------------+ |
| 70 | +``` |
| 71 | + |
| 72 | +### TCP Server |
| 73 | + |
| 74 | +The TCP server (`simple_tcp_server.rb`) is responsible for listening on a TCP port and then transferring raw data to/from client socket to the `Generic client connection` layer |
| 75 | + |
| 76 | +### Generic client connection |
| 77 | + |
| 78 | +The client connection (`simple_tcp_server.rb`) exposes very simple methods to receive data from a client, send data to a client and close a connection to a client. |
| 79 | + |
| 80 | +### JSON RPC Handler |
| 81 | + |
| 82 | +The JSON RPC Handler (`json_rpc_handler.rb`) receives the raw bytes from the connection and extracts the [JSON RPC](http://www.jsonrpc.org/specification) headers and message and passes it to the `Message Router` layer. Conversely, the handler will take response from the `Message Router` and wrap them in the required JSON RPC headers prior to transmission. |
| 83 | + |
| 84 | +### Message Router |
| 85 | + |
| 86 | +The message router (`message_router.rb`) receives requests and notifications, as defined by the [language server protocol](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#base-protocol-json-structures) and then either deals with the messages directly or calls on a `Provider` to calculate the correct response. |
| 87 | + |
| 88 | +The `Message Router` also holds a virtual document store, which contains an in-memory copy of the documents being edited on the language client. |
| 89 | + |
| 90 | +### Providers |
| 91 | + |
| 92 | +The provider classes (`completion_provider.rb`, `document_validator.rb`, `hover_provider.rb`) implement the various puppet languages services. Typically they mirror the language service services, e.g. the `textDocument/hover` request is serviced by the hover provider. |
| 93 | + |
| 94 | +### Puppet Helpers |
| 95 | + |
| 96 | +Many of the providers use common code. The Puppet Helpers (`facter_helper.rb`, `puppet_helper.rb`, `puppet_parser_helper.rb`) abstract away common tasks which make the providers smaller and easier to edit. The helpers also provider a caching layer so that |
| 97 | +Puppet and Facter do not need to be evaluated as often, for example getting all of the facter facts. |
| 98 | + |
| 99 | +### Puppet / Facter / Hiera |
| 100 | + |
| 101 | +At this layer any calls are using Puppet directly, for example; Calling facter or executing a catalog compilation. |
| 102 | + |
0 commit comments