Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Protocol Buffers (proto3)New to Visual Studio Code? Get it now.
Protocol Buffers (proto3)

Protocol Buffers (proto3)

weixu

|
34 installs
| (0) | Free
Protocol Buffers (proto3) editing — syntax highlighting, outline, and diagnostics powered by a Rust analyzer compiled to WebAssembly.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Protocol Buffers (proto3)

Protocol Buffers support for VS Code: syntax highlighting for .proto and for protobuf text-format files, plus real language features — diagnostics, outline, go to definition, references, rename, completion, hover, inlay hints and formatting. All of it comes from a Rust analyzer compiled to WebAssembly and running in the extension host. No language server, no protoc, no buf, no toolchain to install.

Features

  • Syntax highlighting for .proto. syntax, package, import (including the public and weak modifiers) and option; message, enum, service, rpc (with stream and returns) and oneof, each with its declared name scoped as a type or function; the field modifiers repeated, optional and required; map<K, V>; reserved and extensions ranges with their to / max keywords, and extend blocks. Field numbers get their own scope, separate from ordinary numbers, so you can colour them distinctly. All fifteen scalar types are recognised, as are dotted and leading-dot type references — the namespace segments and the type segment are scoped separately. Option names are highlighted both in option statements and in […] field options, with custom options in parentheses ([(my.pkg.custom) = true]) picked out as well. Line and block comments, single- and double-quoted strings with hex, octal, unicode and simple escapes (invalid escapes marked as such), decimal, hex, octal and float literals, and the true / false / inf / nan constants round it out. Both proto2 and proto3 spellings are covered — required, optional, group, extend and extensions are all in the grammar.

  • Diagnostics as you type (150 ms debounce) and on open and save. The analyzer reports lexical and parse errors (unterminated strings and comments, invalid escapes, unexpected tokens), unresolved, unused and circular imports, unknown types and non-type references, duplicate field numbers, field numbers out of range or inside the reserved 19000–19999 block, uses of reserved numbers and reserved names, duplicate declaration names, duplicate enum values, the proto3 rule that the first enum value must be zero, oneof members that are repeated or map or otherwise invalid, invalid map key types, and required in a proto3 file. Every message carries its code, so PROTO0030: … tells you which check fired.

  • Naming-convention warnings, off by default. Turning proto3.diagnostics.style on adds UpperCamelCase, lower_snake_case and SCREAMING_SNAKE_CASE checks plus an empty-message warning (PROTO0070 and up). They ship off so they do not duplicate what buf lint already tells you.

  • Cross-file navigation. On activation the extension scans the workspace for .proto files (up to 2000, skipping node_modules, .git and whatever your root .gitignore excludes) and feeds them to the analyzer, so Go to Definition, Find All References and Go to Symbol in Workspace work across files you have not opened. Rename updates every use site in the workspace.

  • Outline, breadcrumbs and folding. Messages, enums and their values, fields, oneofs, services and methods are published as nested document symbols. Folding ranges come from the parser rather than from indentation, and comment blocks fold as comments.

  • Hover and inlay hints. Hovering a type reference shows its fully-qualified name, kind and doc comment; hovering a field shows label type name = number plus its doc comment. Unresolved references show the candidate names that were tried. Inlay hints append the resolved FQN after short type references that come from another file, so you can see Timestamp: .google.protobuf.Timestamp without jumping away.

  • Completion of keywords and scalar types, plus every message, enum, enum value, field, service and method visible from the file you are editing, labelled by kind.

  • Quick fixes. When a type resolves to a file you have not imported, an Add import "…" action inserts the import in the right place. Organize imports sorts them (plain, then public, then weak, alphabetical within each) and drops duplicates; it is offered only when the order is not already canonical.

  • Formatting with a built-in pretty-printer: two-space indentation, one declaration per line, blank lines between top-level items, leading doc comments preserved. It is opinionated and does not preserve manual column alignment. If the file has parse errors the formatter declines rather than produce garbled output, so you see the error instead.

  • Semantic highlighting on top of the grammar, marking resolved messages and enums as types, enum values, field names and package segments — so colours follow what the analyzer actually resolved, not just what the regex matched.

  • Well-known types are bundled. any.proto, api.proto, descriptor.proto, duration.proto, empty.proto, field_mask.proto, source_context.proto, struct.proto, timestamp.proto, type.proto and wrappers.proto are compiled into the analyzer, so import "google/protobuf/timestamp.proto"; resolves — and Go to Definition on Timestamp works — without any include path configuration.

  • Editing niceties from the language configuration: // and /* */ comment toggling, bracket matching and auto-closing for {}, [], () and quotes, indent on {, dedent on }, and // region / // endregion folding markers.

syntax = "proto3";

package example.v1;

import "google/protobuf/timestamp.proto";

option java_package = "com.example.v1";

// An order placed by a customer.
message Order {
  reserved 4, 7 to 9;
  reserved "legacy_total";

  string id = 1;
  repeated LineItem items = 2;
  map<string, string> labels = 3 [deprecated = true];
  google.protobuf.Timestamp created_at = 5;

  oneof payment {
    Card card = 10;
    Invoice invoice = 11;
  }

  enum Status {
    STATUS_UNSPECIFIED = 0;
    STATUS_SHIPPED = 1;
  }
}

service Orders {
  rpc Get(GetOrderRequest) returns (Order);
  rpc Watch(WatchRequest) returns (stream Order);
}

Text format files

.txtpb, .textproto, .textpb, .pbtxt and .prototext are registered as a separate language with their own grammar: # comments, field names before : and before { or <, nested message blocks in both brace and angle form, repeated-value lists, extension field names and google.protobuf.Any type URLs in […], string escapes, numbers (including the f suffix and signed forms) and the text-format spellings of booleans and floats (t, f, True, infinity, nan).

Text-format files get parse diagnostics, an outline and folding on their own. Schema-aware checks switch on when the file carries the conventional header annotations:

# proto-file: example/v1/order.proto
# proto-message: example.v1.Order

id: "ord-1"
labels: [{ key: "tier" value: "gold" }]

With a # proto-message: header the analyzer resolves the message in your workspace and flags unknown fields, value kinds that do not match the declared field type, unknown enum values, singular fields set twice and conflicting oneof arms; a # proto-file: header additionally scopes the lookup so a wrong-file mistake is caught. Hover, Go to Definition and field-name completion work in text-format files under the same conditions. Without the header, structure features still work and the schema-aware ones stay quiet. Unknown # proto-*: keys and duplicated headers are reported.

Find All References, rename, formatting, inlay hints, quick fixes and semantic tokens apply to .proto files only.

Settings

Setting Default Description
proto3.includePaths [] Additional -I include paths for import "…" resolution. Absolute, or relative to the first workspace folder. Workspace folder roots are always searched.
proto3.diagnostics.onType true Recompute diagnostics while you type, debounced by 150 ms. Turn off to recompute only on open and save.
proto3.diagnostics.style off Set to on to emit the naming-convention warnings (PROTO0070+).
proto3.diagnostics.enabled true Declared, but not read by this version — diagnostics are always produced.
proto3.inlayHints.enabled true Declared, but not read by this version — inlay hints follow the editor's own editor.inlayHints.enabled setting.
proto3.trace.server off Declared, but not read by this version — no trace output is written.

Changing proto3.includePaths or proto3.diagnostics.style re-runs the analyzer over every open protobuf file immediately.

Commands

  • Proto3: Restart Analyzer (proto3.restart) — re-read the include paths, rescan the workspace for .proto files and recompute diagnostics. Useful after files change outside the editor or the index looks stale.

  • Proto3: Show Workspace Symbols (proto3.showSymbolTree) — open a scratch document listing every indexed symbol as kind fully.qualified.name (file). Handy for checking what the analyzer actually indexed.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft