tree: 91eb82c4ec56559188ae5bbcdb1785fe4584cad8 [path history] [tgz]
  1. go.ts
  3. requests.ts

Generate Go types and signatures for the LSP protocol


  1. Make sure node is installed. As explained at the node site you may need npm install @types/node for the node runtime types
  2. Install the typescript compiler, with npm install typescript
  3. Make sure tsc and node are in your execution path.
  4. Get the typescript code for the jsonrpc protocol with git clone


To generate the protocol types (x/tools/internal/lsp/protocol/tsprotocol.go) tsc go.ts && node go.js [-d dir] [-o out.go]

and for simple checking

gofmt -w out.go && golint out.go && go build out.go

-d dir names the directory into which the vscode-languageserver-node repository was cloned. It defaults to $(HOME).

-o out.go says where the generated go code goes. It defaults to tsprotocol.go.

To generate the client and server boilerplate (tsclient.go and tsserver.go) tsc requests.ts && node requests.js [-d dir] && gofmt -w tsclient.go tsserver.go

-d dir is the same as above. The output files are written into the current directory.


  1. go.ts and requests.ts use the Typescript compiler's API, which is introduced in their wiki.
  2. Because the Typescript and Go type systems are incompatible, go.ts and request.ts are filled with heuristics and special cases. Therefore they are tied to a specific commit of vscode-languageserver-node. The hash code of the commit is included in the header of tsprotocol.go and stored in the variable gitHash in go.ts. It is checked (see git() in go.ts) on every execution of go.ts.
  3. Generating the ts*.go files is only semi-automated. Please file an issue if the released version is too far behind.
  4. For the impatient, first change gitHash by hand (git() shows how to find the hash).
    1. Then try to run go.ts and requests.ts. This will likely fail because the heuristics don't cover some new case. For instance, some simple type like string might have changed to a union type string | [number,number]. (Look at the UnionTypeNode code near line 588 of go.ts.) Another example is that some formal parameter generated by requests.ts will have anonymous structure type, which is essentially unusable. (See the code related to ourTypes.)
    2. Next step is to try to move the generated code to internal/lsp/protocol and try to build gopls and its tests. This will likely fail because types have changed. Generally the fixes are fairly easy. (The code for ourTypes was a case where changes had to be made to requests.ts.)
    3. Since there are not adequate integration tests, the next step is to run gopls. A common failure will be a nil dereference, because some previously simple default is now in an optional structure.