golang.org/x/tools/gopls@v0.15.3/doc/design/design.md (about)

     1  # `gopls` design documentation
     2  
     3  ## _A note from the future_
     4  
     5  What follows below is the original design document for gopls, aggregated from
     6  various sources spanning 2018 and 2019. Since then, all of the features listed
     7  below have been implemented, along with many others. The first two goals have
     8  been achieved: gopls is a full implementation of the LSP, and the default
     9  backend for VS Code Go and many other editors. The third goal has only been
    10  partially realized: while gopls has gained many features, it is not extensible
    11  in the sense used in this document: the only way to extend gopls is to modify
    12  gopls. The fourth goal is not achieved: while some notable companies are able
    13  to use gopls with Bazel, the experience is subpar, and the Go command is the
    14  only officially supported build system.
    15  
    16  On the other hand, two of the explicit non-goals have been reconsidered. One is
    17  minor: syntax highlighting is now supported in the LSP by way of semantic
    18  tokens. The other is major: as gopls gained popularity, it became apparent that
    19  its memory footprint was a problem. The size of developer workspaces was
    20  increasing faster than the RAM available in typically development environments
    21  (particularly with containerized development). Gopls now uses a hybrid of
    22  on-disk indexes and in-memory caches, described in more detail in our
    23  [blog post on scalability](https://go.dev/blog/gopls-scalability).
    24  
    25  Notably, in anticipating difficulties this doc turned out to be prescient.
    26  Gopls has indeed struggled against the core standary library packages upon
    27  which it is built, and its user experience is still limited by the LSP.
    28  Nevertheless, sticking with the standard library and LSP was the right
    29  approach, as despite our small team these decisions have helped gopls keep up
    30  with the evolving Go language (i.e. generics), and to integrate with many new
    31  text editors.
    32  
    33  Gopls development continues, more than four years later, with a focus on
    34  simplicity, reliability, and extensibility. The new, opt-in
    35  [Go telemetry](https://github.com/golang/tools/releases/tag/gopls%2Fv0.14.0)
    36  will help us attain a higher standard of stability in our releases than we've
    37  been able to achieve through Github issues alone. Furthermore, telemetry will
    38  allow us to focus on high-priority features, and deprecate historical
    39  workarounds that burden the codebase. With greater velocity, we look forward
    40  to working with the community on improved refactoring, static analysis, and
    41  whatever else the future brings.
    42  
    43  - _Rob Findley (rfindley@google.com), 2023_
    44  
    45  ## Goals
    46  
    47  * `gopls` should **become the default editor backend** for the major editors used by Go programmers, fully supported by the Go team.
    48  * `gopls` will be a **full implementation of LSP**, as described in the [LSP specification], to standardize as many of its features as possible.
    49  * `gopls` will be **clean and extensible** so that it can encompass additional features in the future, allowing Go tooling to become best in class once more.
    50  * `gopls` will **support alternate build systems and file layouts**, allowing Go development to be simpler and more powerful in any environment.
    51  
    52  ## Context
    53  
    54  While Go has a number of excellent and useful command-line tools that enhance the developer experience, it has become clear that integrating these tools with IDEs can pose challenges.
    55  
    56  Support of these tools has relied on the goodwill of community members, and they have been put under a large burden of support at times as the language, toolchain and environments change. As a result many tools have ceased to work, have had support problems, or become confusing with forks and replacements, or provided an experience that is not as good as it could be.
    57  See the section below on [existing solutions](#existing-solutions) for more problems and details.
    58  
    59  This is fine for tools used occasionally, but for core IDE features, this is not acceptable.
    60  Autocompletion, jump to definition, formatting, and other such features should always work, as they are key for Go development.
    61  
    62  The Go team will create an editor backend that works in any build system.
    63  It will also be able to improve upon the latency of Go tools, since each tool will no longer have to individually run the type-checker on each invocation, instead there will be a long-running process and data can be shared between the definitions, completions, diagnostics, and other features.
    64  
    65  By taking ownership of these tools and packaging them together in the form of gopls, the Go team will ensure that the Go development experience isn’t unnecessarily complicated for Go users.
    66  Having one editor backend will simplify the lives of Go developers, the Go team, and the maintainers of Go editor plugins.
    67  
    68  See Rebecca's excellent GopherCon keynote [talk] and [slides] for some more context.
    69  
    70  ## Non-Goals
    71  
    72  * Command line speed
    73  
    74    Although gopls will have a command line mode, it will be optimized for long running and not command responsiveness, as such it may not be the right tool for things like CI systems.
    75    For such cases there will have to be an alternate tool using the same underlying libraries for consistency.
    76  
    77  * Low memory environments
    78  
    79    In order to do a good job of processing large projects with very low latencies gopls will be holding a lot of information in memory.
    80    It is presumed that developers are normally working on systems with significant RAM and this will not be a problem.
    81    In general this is upheld by the large memory usage of existing IDE solutions (like IntelliJ)
    82  
    83  * Syntax highlighting
    84  
    85    At the moment there is no editor that delegates this functionality to a separate binary, and no standard way of doing it.
    86  
    87  ## Existing solutions
    88  
    89  Every year the Go team conducts a survey, asking developers about their experiences with the language.
    90  
    91  One question that is asked is “How do you feel about your editor?”.
    92  
    93  The responses told a very negative story. Some categorized quotes:
    94  
    95  * Setup
    96    * "Hard to install and configure"
    97    * "Inadequate documentation"
    98  * Performance
    99    * "Performance is very poor"
   100    * "Pretty slow in large projects"
   101  * Reliability
   102    * "Features work one day, but not the next"
   103    * "Tooling is not updated with new language features"
   104  
   105  Each editor has its own plugin that shells out to a variety of tools, many of which break with new Go releases or because they are no longer maintained.
   106  
   107  The individual tools each have to do the work to understand the code and all its transitive dependencies.
   108  
   109  Each feature is a different tool, with a different set of patterns for its command line, a different way to accept input and parse output, a different way of specifying source code locations.
   110  To support its existing feature set, VSCode installed 24 different command line tools, many of which have options or forks to configure. When looking at the set of tools that needed to be migrated to modules, across all the editors, there were 63 separate tools.
   111  
   112  All these tools need to understand the code, and they use the same standard libraries to do it. Those libraries are optimized for these kinds of tools, but even so processing that much code takes a lot of time time. Almost none of the tools are capable of returning results within 100ms.
   113  As developers type in their editor, multiple of these features need to activate, which means they are not just paying the cost once, but many times. The overall effect is an editing experience that feels sluggish, and features that are either not enabled or sometimes produce results that appear so slowly they are no longer useful when they arrive. This is a problem that increases with the size of the code base, which means it is getting worse over time, and is especially bad for the kinds of large code bases companies are dealing with as they use Go for more major tasks.
   114  
   115  ## Requirements
   116  
   117  ### Complete feature set
   118  
   119  For gopls to be considered a success it has to implement the full feature set discussed [below](#Features).
   120  This is the set of features that users need in order to feel as productive as they were with the tooling it is replacing. It does not include every feature of previous implementations, there are some features that are almost never used that should be dropped (like guru's pointer analysis) and some other features that do not easily fit and will have to be worked around (replacing the save hook/linter).
   121  
   122  ### Equivalent or better experience
   123  
   124  For all of those features, the user experience must match or exceed the current one available in all editors.
   125  This is an easy statement to make, but a hard one to validate or measure. Many of the possible measures fail to capture the experience.
   126  
   127  For instance, if an attempt was made to measure the latency of a jump to definition call, the results would be fairly consistent from the old godef tool. From the gopls implementation there may be a much larger range of latencies, with the best being orders of magnitude faster, and the worse slightly worse, because gopls attempts to do far more work, but manages to cache it across calls.
   128  
   129  Or for a completion call, it might be slower but produce a better first match such that users accept it more often, resulting in an overall better experience.
   130  
   131  For the most part this has to rely on user reports. If users are refusing to switch because the experience is not better, it is clearly not done, if they are switching but most people are complaining, there are probably enough areas that are better to make the switch compelling but other areas which are worse. If most people are switching and either staying silent or being positive, it is probably done. When writing tools, the user is all that matters.
   132  
   133  ### Solid community of contributors
   134  
   135  The scope and scale of the problem gopls is trying to solve is untenable for the core Go team, it is going to require a strong community to make it all happen.
   136  
   137  This implies the code must be easy to contribute to, and easy for many developers to work on in parallel. The functionality needs to be well decoupled, and have a thorough testing story.
   138  
   139  ### Latencies that fall within user tolerance
   140  
   141  There has been a lot of research on acceptable latencies for user actions.
   142  <!-- TODO: research links -->
   143  The main result that affects gopls is that feedback in direct response to continuous user actions needs to be under 100ms to be imperceptible, and anything above 200ms aggravates the user.
   144  This means in general the aim has to be <100ms for anything that happens as the developer types.
   145  There will always be cases where gopls fails to meet this deadline, and there needs to be ways to make the user experience okay in those cases, but in general the point of this deadline is to inform the basic architecture design, any solution that cannot theoretically meet this goal in the long term is the wrong answer.
   146  
   147  ### Easy to configure
   148  
   149  Developers are very particular, and have very differing desires in their coding experience. gopls is going to have to support a significant amount of flexibility, in order to meet those desires.
   150  The default settings however with no configuration at all must be the one that is best experience for most users, and where possible the features must be flexible without configuration so that the client can easily make the choices about treatment without changing its communication with gopls.
   151  
   152  ## Difficulties
   153  
   154  ### Volume of data
   155  
   156  <!-- TODO: project sizes -->
   157  * Small:
   158  * Medium:
   159  * Large:
   160  * Corporate mono-repo: Much much bigger
   161  
   162  Parsing and type checking large amounts of code is quite expensive, and the converted forms use a lot of space. As gopls has to keep updating this information while the developer types, it needs to manage how it caches the converted forms very carefully to balance memory use vs speed.
   163  
   164  ### Cache invalidation
   165  
   166  The basic unit of operation for the type checking is the package, but the basic unit of operation for an editor is the file.
   167  gopls needs to be able to map files to packages efficiently, so that when files change it knows which packages need to be updated (along with any other packages that transitively depended on them).
   168  This is made especially difficult by the fact that changing the content of a file can modify which packages it is considered part of (either by changing the package declaration or the build tags), a file can be in more than one package, and changes can be made to files without using the editor, in which case it will not notify us of the changes.
   169  
   170  ### Inappropriate core functionality
   171  
   172  The base libraries for Go (things like [go/token], [go/ast] and [go/types]) are all designed for compiler-like applications.
   173  They tend to worry more about throughput than memory use, they have structures that are intended to grow and then be thrown away at program exit, and they are not designed to keep going in the presence of errors in the source they are handling.
   174  They also have no abilities to do incremental changes.
   175  
   176  Making a long running service work well with those libraries is a very large challenge, but writing new libraries would be far more work, and cause a significant long term cost as both sets of libraries would have to be maintained. Right now it is more important to get a working tool into the hands of users. In the long term this decision may have to be revisited, new low level libraries may be the only way to keep pushing the capabilities forwards.
   177  
   178  ### Build system capabilities
   179  
   180  gopls is supposed to be build system agnostic, but it must use the build system to discover how files map to packages. When it tries to do so, even when the functionality is the same, the costs (in time, CPU and memory) are very different, and can significantly impact the user experience. Designing how gopls interacts with the build system to try to minimize or hide these differences is hard.
   181  
   182  ### Build tags
   183  
   184  The build tag system in Go is quite powerful, and has many use cases. Source files can exclude themselves using powerful boolean logic on the set of active tags.
   185  It is however designed for specifying the set of active tags on the command line, and the libraries are all designed to cope with only one valid combination at a time. There is also no way to work out the set of valid combinations.
   186  
   187  Type checking a file requires knowledge of all the other files in the same package, and that set of files is modified by the build tags. The set of exported identifiers of a package is also affected by which files are in the package, and thus its build tags.
   188  
   189  This means that even for files or packages that have no build tag controls it is not possible to produce correct results without knowing the set of build tags to consider.
   190  This makes it very hard to produce useful results when viewing a file.
   191  
   192  ### Features not supported by LSP
   193  
   194  There are some things it would be good to be able to do that do not fit easily into the existing LSP protocol.
   195  For instance, displaying control flow information, automatic struct tags, complex refactoring...
   196  
   197  Each feature will have to be considered carefully, and either propose a change to LSP, or add a way to have gopls specific extensions to the protocol that are still easy to use in all the editor plugins.
   198  
   199  To avoid these at the start, only core LSP features will be implemented, as they are sufficient to meet the baseline requirements anyway, but the potential features need to be kept in mind in the core architecture.
   200  
   201  ### Distribution
   202  
   203  Making sure that users are using the right version of gopls is going to be a problem. Each editor plugin is probably going to install the tools in its own way, some will choose to install it system wide, some will keep their own copy.
   204  
   205  Because it is a brand new tool, it will be changing rapidly. If users are not informed they are on an old version they will be experiencing problems that have already been fixed, which is worse for them, and then probably reporting them, which wastes time for the gopls team. There needs to be a mechanism for gopls to check if is up to date, and a recommended way to install an up to date version.
   206  
   207  ### Debugging user problems
   208  
   209  gopls is essentially a very stateful long running server on the developer's machine. Its basic operation is affected by many things, from the users environment to the contents of the local build cache. The data it is operating on is often a confidential code base that cannot be shared.
   210  All of these things make it hard for users to report a bug usefully, or create a minimal reproduction.
   211  
   212  There needs to be easy ways for users to report what information they can, and ways to attempt to reproduce problems without their entire state. This is also needed to produce regression tests.
   213  
   214  ## Basic design decisions
   215  
   216  There are some fundamental architecture decisions that affect much of the rest of the design of the tool, making fundamental trade offs that impact the user experience.
   217  
   218  ### Process lifetime: *managed by the editor*
   219  
   220  Processing a large code base to fully type check and then analyze it within the latency requirements is not feasible, and is one of the primary problems with the existing solutions. This remains true even if the computed information was cached on disk, as running analyzers and type checkers ends up requiring the full AST of all files in the dependency graph.
   221  It is theoretically possible to do better, but only with a major re-write of the existing parsing and type checking libraries, something that is not feasible at this time.
   222  
   223  This implies that gopls should be a long running process, that is able to cache and pre-calculate results in memory so that when a request arrives it can produce the answer much faster.
   224  
   225  It could run as a daemon on the user's machine, but there are a lot of issues with managing a daemon. It may well be the right choice in the long term, and it should be allowed for in the fundamental architecture design, but to start with it will instead have a process that lasts as long as the editor that starts it, and that can easily be restarted.
   226  
   227  ### Caching: *in memory*
   228  
   229  Persistent disk caches are very expensive to maintain, and require solving a lot of extra problems.
   230  Although building the information required is expensive compared to the latencies required of the requests, it is fairly minor compared to the startup times of an editor, so it is expected that rebuilding the information when gopls is restarted will be acceptable.
   231  
   232  The advantage gained from this is that gopls becomes stateless across restarts which means if it has issues or gets its state confused, a simple restart will often fix the problem.
   233  It also means that when users report problems, the entire state of the on disk cache is not needed to diagnose and reproduce the issue.
   234  
   235  ### Communication: *stdin/stdout JSON*
   236  
   237  The LSP specification defines the JSON messages that are normally used, but it does not define how those message should be sent, and there are implementations of the LSP that do not use JSON (for instance, Protocol buffers are an option).
   238  
   239  The constraints on gopls are that it must be easy to integrate into *every editor* on *all operating systems*, and that it should not have large external dependencies.
   240  
   241  JSON is part of the Go standard library, and is also the native language of LSP, so it makes the most sense. By far the best supported communication mechanism is the standard input and output of a process, and the common client implementations all have ways of using [JSON rpc 2] in this mode.  There were no complete and low dependency implementations of this protocol in Go, but it is a fairly small protocol on top of the JSON library that can be implemented with a moderate effort, and would be a generally useful library to have anyway.
   242  
   243  In the future it is expected to run in separated client server mode, so writing it in a way that could use sockets instead of stdin/stdout from the start was the best way to make sure it remained possible. It was also a huge debugging aid to be able to run the gopls server by hand and watch/debug it outside the editor.
   244  
   245  ### Running other tools: *no*
   246  
   247  <!--- TODO: subprocess discuss --->
   248  
   249  ## Features
   250  
   251  <!--TODO(rstambler): Generate a file that lists all of the supported features.-->
   252  
   253  There is a set of features that gopls needs to expose to be a comprehensive IDE solution.
   254  The following is the minimum set of features, along with their existing solutions and how they should map to the LSP.
   255  
   256  ### Introspection
   257  
   258  Introspection features tell developers information about their code while they work. They do not make or suggest changes.
   259  
   260  ---
   261  Diagnostics | Static analysis results of the code, including compilation and lint errors
   262  ----------- | ---
   263  Requires    | Full go/analysis run, which needs full AST, type and SSA information
   264  LSP         | [`textDocument/publishDiagnostics`]
   265  Previous    | `go build`, `go vet`, `golint`, [errcheck], [staticcheck] <!-- TODO: and all the rest -->
   266  |           | This is one of the most important IDE features, allowing fast turn around without having to run compilers and checkers in the shell. Often used to power problem lists, gutter markers and squiggle underlines in the IDE. <br/> There is some complicated design work to do in order to let users customize the set of checks being run, preferably without having to recompile the main LSP binary.
   267  
   268  ---
   269  Hover    | Information about the code under the cursor.
   270  -------- | ---
   271  Requires | AST and type information for the file and all dependencies
   272  LSP      | [`textDocument/hover`]
   273  Previous | [godoc], [gogetdoc]
   274  |        | Used when reading code to display information known to the compiler but not always obvious from the code. For instance it may return the types of identifiers, or the documentation.
   275  
   276  ---
   277  Signature help | Function parameter information and documentation
   278  -------------- | ---
   279  Requires       | AST and type information for the file and all dependencies
   280  LSP            | [`textDocument/signatureHelp`]
   281  Previous       | [gogetdoc]
   282  |              | As a function call is being typed into code, it is helpful to know the parameters of that call to enable the developer to call it correctly.
   283  
   284  ### Navigation
   285  
   286  Navigation features are designed to make it easier for a developer to find their way round a code base.
   287  
   288  ---
   289  Definition | Select an identifier, and jump to the code where that identifier was defined.
   290  ---------- | ---
   291  Requires   | Full type information for file and all dependencies
   292  LSP        | [`textDocument/declaration`]
   293  |          | [`textDocument/definition`]
   294  |          | [`textDocument/typeDefinition`]
   295  Previous   | [godef] |
   296  |          | Asking the editor to open the place where a symbol was defined is one of the most commonly used code navigation tools inside an IDE when available. It is especially valuable when exploring an unfamiliar code base.<br/>Due to a limitation of the compiler output, it is not possible to use the binary data for this task (specifically it does not know column information) and thus it must parse from source.
   297  
   298  ---
   299  Implementation | Reports the types that implement an interface
   300  -------------- | ---
   301  Requires       | Full workspace type knowledge
   302  LSP            | [`textDocument/implementation`]
   303  Previous       | [impl]
   304  |              | This feature is hard to scale up to large code bases, and is going to take thought to get right. It may be feasible to implemented a more limited form in the meantime.
   305  
   306  ---
   307  Document symbols | Provides the set of top level symbols in the current file.
   308  ---------------- | ---
   309  Requires         | AST of the current file only
   310  LSP              | [`textDocument/documentSymbol`]
   311  Previous         | [go-outline], [go-symbols]
   312  |                | Used to drive things like outline mode.
   313  
   314  ---
   315  References | Find all references to the symbol under the cursor.
   316  ---------- | ---
   317  Requires   | AST and type information for the **reverse** transitive closure
   318  LSP        | [`textDocument/references`]
   319  Previous   | [guru]
   320  |          | This requires knowledge of every package that could possible depend on any packages the current file is part of. In the past this has been implemented either by global knowledge, which does not scale, or by specifying a "scope" which confused users to the point where they just did not use the tools. gopls is probably going to need a more powerful solution in the long term, but to start with automatically limiting the scope may produce acceptable results. This would probably be the module if known, or some sensible parent directory otherwise.
   321  
   322  ---
   323  Folding  | Report logical hierarchies of blocks
   324  -------- | ---
   325  Requires | AST of the current file only
   326  LSP      | [`textDocument/foldingRange`]
   327  Previous | [go-outline]
   328  |        | This is normally used to provide expand and collapse behavior in editors.
   329  
   330  ---
   331  Selection | Report regions of logical selection around the cursor
   332  --------- | ---
   333  Requires  | AST of the current file only
   334  LSP       | [`textDocument/selectionRange`]
   335  Previous  | [guru]
   336  |         | Used in editor features like expand selection.
   337  
   338  
   339  ### Edit assistance
   340  
   341  These features suggest or apply edits to the code for the user, including refactoring features, for which there are many potential use cases.
   342  Refactoring is one of the places where Go tools could potentially be very strong, but have not been so far, and thus there is huge potential for improvements in the developer experience.
   343  There is not yet a clear understanding of the kinds of refactoring people need or how they should express them however, and there are weaknesses in the LSP protocol around this.
   344  This means it may be much more of a research project.
   345  
   346  
   347  ---
   348  Format   | Fix the formatting of the file
   349  -------- | ---
   350  Requires | AST of current file
   351  LSP      | [`textDocument/formatting`]
   352  |        | [`textDocument/rangeFormatting`]
   353  |        | [`textDocument/onTypeFormatting`]
   354  Previous | [gofmt], [goimports], [goreturns]
   355  |        | It will use the standard format package. <br/> Current limitations are that it does not work on malformed code. It may need some very careful changes to the formatter to allow for formatting an invalid AST or changes to force the AST to a valid mode. These changes would improve range and file mode as well, but are basically vital to onTypeFormatting
   356  
   357  ---
   358  Imports  | Rewrite the imports block automatically to match the symbols used.
   359  -------- | ---
   360  Requires | AST of the current file and full symbol knowledge for all candidate packages.
   361  LSP      | [`textDocument/codeAction`]
   362  Previous | [goimports], [goreturns]
   363  |        | This needs knowledge of packages that are not yet in use, and the ability to find those packages by name. <br/> It also needs exported symbol information for all the packages it discovers. <br/> It should be implemented using the standard imports package, but there may need to be exposed a more fine grained API than just a file rewrite for some of the interactions.
   364  
   365  ---
   366  Autocompletion | Makes suggestions to complete the entity currently being typed.
   367  -------------- | ---
   368  Requires       | AST and type information for the file and all dependencies<br/> Also full exported symbol knowledge for all packages.
   369  LSP            | [`textDocument/completion`]
   370  |              | [`completionItem/resolve`]
   371  Previous       | [gocode]
   372  |              | Autocomplete is one of the most complicated features, and the more it knows the better its suggestions can be. For instance it can autocomplete into packages that are not yet being imported if it has their public symbols. It can make better suggestions of options if it knows what kind of program you are writing. It can suggest better arguments if it knows how you normally call a function. It can suggest entire patterns of code if it knows they are common. Unlike many other features, which have a specific task, and once it is doing that task the feature is done, autocomplete will never be finished. Balancing and improving both the candidates and how they are ranked will be a research problem for a long time to come.
   373  
   374  ---
   375  Rename   | Rename an identifier
   376  -------- | ---
   377  Requires | AST and type information for the **reverse** transitive closure
   378  LSP      | [`textDocument/rename`]
   379  |        | [`textDocument/prepareRename`]
   380  Previous | [gorename]
   381  |        | This uses the same information that find references does, with all the same problems and limitations. It is slightly worse because the changes it suggests make it intolerant of incorrect results. It is also dangerous using it to change the public API of a package.
   382  
   383  ---
   384  Suggested fixes | Suggestions that can be manually or automatically accepted to change the code
   385  --------------- | ---
   386  Requires        | Full go/analysis run, which needs full AST, type and SSA information
   387  LSP             | [`textDocument/codeAction`]
   388  Previous        | N/A
   389  |               | This is a brand new feature powered by the new go/analysis engine, and it should allow a huge amount of automated refactoring.
   390  
   391  [LSP specification]: https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/
   392  [talk]: TODO
   393  [slides]: https://github.com/gophercon/2019-talks/blob/master/RebeccaStambler-GoPleaseStopBreakingMyEditor/slides.pdf "Go, please stop breaking my editor!"
   394  [JSON rpc 2]: https://www.jsonrpc.org/specification
   395  
   396  [errcheck]: https://github.com/kisielk/errcheck
   397  [go-outline]: https://github.com/lukehoban/go-outline
   398  [go-symbols]: https://github.com/acroca/go-symbols
   399  [gocode]: https://github.com/stamblerre/gocode
   400  [godef]: https://github.com/rogpeppe/godef
   401  [godoc]: https://golang.org/cmd/godoc
   402  [gofmt]: https://golang.org/cmd/gofmt
   403  [gogetdoc]: https://github.com/zmb3/gogetdoc
   404  [goimports]: https://pkg.go.dev/golang.org/x/tools/cmd/goimports
   405  [gorename]: https://pkg.go.dev/golang.org/x/tools/cmd/gorename
   406  [goreturns]: https://github.com/sqs/goreturns
   407  [gotags]: https://github.com/jstemmer/gotags
   408  [guru]: https://pkg.go.dev/golang.org/x/tools/cmd/guru
   409  [impl]: https://github.com/josharian/impl
   410  [staticcheck]: https://staticcheck.io/docs/
   411  [go/types]: https://golang.org/pkg/go/types/
   412  [go/ast]: https://golang.org/pkg/go/ast/
   413  [go/token]: https://golang.org/pkg/go/token/
   414  
   415  [`completionItem/resolve`]:https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#completionItem_resolve
   416  [`textDocument/codeAction`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_codeAction
   417  [`textDocument/completion`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_completion
   418  [`textDocument/declaration`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_declaration
   419  [`textDocument/definition`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_definition
   420  [`textDocument/documentLink`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_documentLink
   421  [`textDocument/documentSymbol`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_documentSymbol
   422  [`textDocument/foldingRange`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_foldingRange
   423  [`textDocument/formatting`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_formatting
   424  [`textDocument/highlight`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_highlight
   425  [`textDocument/hover`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_hover
   426  [`textDocument/implementation`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_implementation
   427  [`textDocument/onTypeFormatting`]:https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_onTypeFormatting
   428  [`textDocument/prepareRename`]:https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_prepareRename
   429  [`textDocument/publishDiagnostics`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_publishDiagnostics
   430  [`textDocument/rangeFormatting`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_rangeFormatting
   431  [`textDocument/references`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_references
   432  [`textDocument/rename`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_rename
   433  [`textDocument/selectionRange`]:https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_selectionRange
   434  [`textDocument/signatureHelp`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_signatureHelp
   435  [`textDocument/typeDefinition`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#textDocument_typeDefinition
   436  [`workspace/didChangeWatchedFiles`]: https://github.com/Microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-14.md#workspace_didChangeWatchedFiles