A Language Server Protocol implementation for Google Protocol Buffers, written in Go.
This project was originally created to streamline my own workflow. Some implementations may not be optimal and the features may feel incomplete, but it serves my needs well enough as it is. That said, if you have a better solution in mind, I'd be happy to switch to yours.
- Rust version: https://github.com/lasorda/protobuf-lsp
- Repository: https://github.com/lasorda/protobuf-language-server
- Document symbol (tree view with nested message / enum support)
- Go to definition (supports nested message / enum)
- Find references
- Hover (shows the definition of message / enum, including nested types)
- Document formatting / range formatting (via
clang-format) - Code completion (triggered by
.) - Jump from a C++ header to the corresponding proto definition (only global message and enum)
If you use VSCode or any Open VSX-compatible editor (Cursor, VSCodium, Windsurf, ...), you can install the extension directly without building the binary yourself:
- VSCode Marketplace: https://marketplace.visualstudio.com/items?itemName=panzhihao.protobuf-language-server
- Open VSX Registry: https://open-vsx.org/extension/panzhihao/protobuf-language-server
The extension launches the protobuf-language-server binary found in your PATH. To use a custom path, set protobuf-language-server.serverPath in VSCode settings.
See vscode-extension/README.md for more details.
Requires Go 1.19+.
# Clean the module cache (optional)
go clean -modcache
# Install to `go env GOPATH`/bin
go install github.com/lasorda/protobuf-language-server@masterMake sure $(go env GOPATH)/bin is in your PATH:
# Verify
protobuf-language-server --help| Flag | Description | Default |
|---|---|---|
--stdio |
Communicate over stdio (the default LSP transport) | false |
--listen |
Listen on the given TCP address (e.g. 127.0.0.1:8080) |
empty (use stdio) |
--logs |
Log file path | logs.DefaultLogFilePath() |
Just install the extension (see the links above).
Neovim + coc.nvim
Add the following to :CocConfig:
Neovim + nvim-lspconfig
local configs = require('lspconfig.configs')
local util = require('lspconfig.util')
configs.protobuf_language_server = {
default_config = {
cmd = { 'protobuf-language-server' },
filetypes = { 'proto', 'cpp' },
root_dir = util.root_pattern('.git'),
single_file_support = true,
settings = {
["additional-proto-dirs"] = {
-- extra directories to search when resolving proto imports
-- "vendor",
-- "third_party",
}
},
}
}
require('lspconfig').protobuf_language_server.setup {
-- your custom config
}Any LSP-aware editor (Emacs lsp-mode, Sublime LSP, Helix, ...) works. Key configuration points:
- command:
protobuf-language-server - filetypes:
proto(addcppif you want the C++ header jump feature) - settings.additional-proto-dirs: extra directories searched when resolving proto imports (relative to the workspace root or absolute)
| Setting | Type | Default | Description |
|---|---|---|---|
additional-proto-dirs |
string[] |
[] |
Extra directories searched when resolving proto imports (relative or absolute) |
.
├── main.go # Entry point, registers LSP handlers
├── components/ # LSP handler implementations (completion / hover / ...)
├── proto/ # proto parsing, type definitions and views
│ ├── parser/
│ ├── types/
│ └── view/
├── go-lsp/ # In-tree LSP / JSON-RPC library (used by this project)
└── vscode-extension/ # VSCode extension (TypeScript)
MIT