Proto Utils
面向 VS Code 的 Proto3 一体化插件:语法高亮 · 跳转定义 · 悬停文档 · TypeScript 类型生成 · 编辑器内 gRPC 调用。
零外部依赖——无需安装 protoc、buf 或任何命令行工具。
功能总览
| 能力 |
说明 |
| 🖋 语言服务 |
Proto3 语法高亮,内置标量与自定义类型着色区分 |
| 🔍 跳转与悬停 |
同文件 / import / package 命名空间的类型跳转;悬停显示类型摘要与前导注释 |
| 🧭 大纲导航 |
message / enum / service / rpc 方法全部进入大纲与符号搜索 |
| 🏗 TS 类型生成 |
message / enum / repeated / map / oneof → TypeScript;service → <Name>Client 调用接口(四种流式方向) |
| 📞 RPC 工作台 |
按 schema 自动生成请求表单,直接调用一元 / 服务端流 gRPC 方法,响应折叠树展示 |
| 🩺 实时诊断 |
语法错就地飘红、缺失类型与重名在引用处标红,支持一键补 import |
界面速览
RPC 工作台
按 proto schema 自动生成的请求表单:每个字段带类型徽标、可选/必填标记与 proto 注释;嵌套 message 与枚举就地展开;Headers 编辑器随调用携带 metadata。

一元调用 · 响应折叠树
响应数据以 DevTools 风格折叠树逐级展示,长字符串截断、int64 以字符串往返保持精度;「Response metadata」折叠块展示服务器返回的 headers/trailers。

服务端流 · 分 chunk 折叠
服务端流按 chunk 折叠展示,可单独展开某条消息,随时取消;长流只保留最近 200 条,计数仍为真实总量。

亮色主题
工作台配色自动跟随 VS Code 明/暗主题切换(暗色 GitHub Dark、亮色 GitHub Light)。

快速上手
- 打开包含
.proto 文件的工作区,插件自动索引。
- 生成类型:右键
.proto 文件 → Generate TypeScript Types,或 Ctrl+Shift+P 运行全量生成。
- 调用 gRPC:rpc 方法上方点击「▶ 调用」,在工作台填表发送——只需在设置里把
protoUtils.runner.server 指向你的 gRPC 服务地址,protoUtils.runner.protoDir 指向 proto 目录。
功能
- 为
.proto 文件提供 Proto3 语法高亮
- 区分内置标量类型和自定义类型
- 支持同文件、导入文件和 package 命名空间中的类型定义跳转
- 悬停在类型引用或定义上时显示类型摘要(种类 + 限定名)与定义处前导注释
- 大纲/符号导航:列出
message、enum、service 及 service 下的 rpc 方法
- 将
message、enum、repeated、map 和 oneof 生成为 TypeScript 类型
- 将
service 生成为客户端调用接口(<Name>Client,流式方向用 AsyncIterable 表达)
- 根据多个
.proto 文件之间的类型引用生成 TypeScript import type(默认带 .ts 后缀;跨模块同名类型自动取别名,避免重复标识符)
- 单文件生成或一键全量生成全部 proto
- 在 rpc 方法上方提供「▶ 调用」CodeLens,一键打开 RPC 工作台并预选方法
- RPC 工作台:按 proto schema 自动生成请求表单,发起一元与服务端流调用;响应数据以可折叠 JSON 树展示(嵌套对象/数组逐级展开收起)
- 保存
.proto 文件或工作台加载 proto 后报告诊断:语法错就地飘红(可收窄到出错 token),缺失类型/重名在引用处与声明处飘红;工作台错误卡片同步以红色波浪线标出出错点
基本使用
编辑和跳转
在工作区中打开 .proto 文件后,插件会自动激活并索引工作区内的 Proto3 文件。
- 语法高亮会自动生效。
- 按住
Ctrl 并点击类型名称,可跳转到对应的 message 或 enum 定义。
- macOS 使用
Cmd + 点击。
跨文件跳转需要目标类型所在的文件位于当前 VS Code 工作区中,并通过 Proto import 或 package 名称可解析。
生成 TypeScript 类型
可以通过以下任一方式生成类型:
- 在编辑器或资源管理器中右键点击
.proto 文件,选择 Proto Utils: Generate TypeScript Types(仅当前文件)或 Proto Utils: Generate TypeScript Types (All Protos)(全部 proto,含跨文件 import 目标)。
- 打开命令面板运行同名命令。使用命令面板的单文件命令时,应先打开目标
.proto 文件。
默认情况下,生成文件写入工作区的 generated/ 目录。若 Proto 文件为 protos/account/user.proto(且 proto 都在 protos/ 下):
syntax = "proto3";
package account.profile;
message User {
string user_name = 1;
repeated string roles = 2;
}
默认(pathMapping: "file")输出路径为:
generated/user.ts
生成内容类似:
// Generated by proto-utils. Do not edit.
export interface User {
userName: string;
roles: string[];
}
每次执行生成命令都会覆盖对应的输出文件,请勿手动修改生成文件。
service 生成客户端调用接口
每个 service 生成一个 <Name>Client 接口,方法签名的请求/响应类型按流式方向推导:
| RPC 形态 |
生成的签名 |
| 一元 |
(request: Req) => Promise<Resp> |
| 服务端流 |
(request: Req) => AsyncIterable<Resp> |
| 客户端流 |
(request: AsyncIterable<Req>) => Promise<Resp> |
| 双向流 |
(request: AsyncIterable<Req>) => AsyncIterable<Resp> |
跨文件的请求/响应类型自动生成 import type(默认带 .ts 后缀,可用 protoUtils.codeGen.importExtension 关闭);不同模块的同名类型(如两处 ResponseStatus)会自动按路径取确定性别名,避免重复标识符报错。
调用 RPC(RPC 工作台)
在 .proto 文件中,每个 rpc 方法上方都会出现「▶ 调用」CodeLens。点击后 RPC 工作台打开并预选该方法;也可以通过命令面板运行 Proto Utils: Open RPC Runner,或右键 .proto 编辑器选择同名命令,手动选择服务和方法。
- 表单按请求消息的字段 schema 自动生成,嵌套 message 以 JSON/JSON5 编辑(支持注释、尾逗号、单引号、裸键名)。
- 一元调用在响应区以可折叠 JSON 树展示结果,嵌套对象/数组默认收起、逐级展开,长字符串截断,附「全部展开/全部收起」快捷按钮;服务端流调用按 chunk 折叠展示,可随时取消;长流只保留最近 200 条的折叠数据与原始 JSON(计数仍为真实总量),防止内存与页面被无限撑大。原始 JSON 仍可一键复制。
- 响应区带「Response metadata / 响应 metadata」折叠块,展示服务器返回的 headers 与 trailers(二进制
-bin 键以 base64 显示),有数据才出现。
- proto 文件变更(保存、外部修改)会自动刷新服务列表,不丢表单状态。
- 搜索框为模糊匹配(子序列,大小写不敏感):
ldp 可命中 ExecuteOpenLDProg;子串命中仍然有效。
- client-streaming 与双向流暂不支持(见
docs/adr/0007)。
- 工作台界面配色自动跟随 VS Code 明/暗主题(暗色为 GitHub Dark、亮色为 GitHub Light 固定配色,见
docs/adr/0011)。
工作台依赖的设置:
| 配置项 |
默认值 |
作用 |
protoUtils.runner.server |
"localhost:50051" |
gRPC 服务器地址(host:port) |
protoUtils.runner.protoDir |
"" |
proto 目录,必须指向 .proto 文件所在目录本身(import 相对它解析,指到父目录会导致跨文件类型解析失败);空 = 工作区根;相对路径相对 workspace folder 解析。显式配置后,代码生成也只扫描该目录(不再扫工作区) |
protoUtils.runner.tls |
false |
是否使用 TLS 通道(默认明文) |
protoUtils.runner.tlsRootCert |
"" |
根证书 PEM 路径;空 = 系统默认 CA;相对路径相对 workspace folder 解析 |
protoUtils.runner.tlsClientCert |
"" |
客户端证书 PEM 路径(双向 TLS;须与 tlsClientKey 成对配置) |
protoUtils.runner.tlsClientKey |
"" |
客户端私钥 PEM 路径(双向 TLS;须与 tlsClientCert 成对配置) |
protoUtils.runner.metadata |
[] |
每次调用默认携带的请求头,一行一条 "Key: Value";工作台 Headers 编辑器可在每次调用前增删 |
protoUtils.runner.timeoutMs |
15000 |
一元调用超时(毫秒),走 grpc deadline;0 = 不限。服务端流始终不限时 |
TLS、请求头与超时
- TLS:开启
runner.tls 后按 createSsl 语义建通道——只配 tlsRootCert 为单向 TLS;再成对配置 tlsClientCert/tlsClientKey 为双向 TLS(只给一个会在调用时报错)。PEM 路径支持绝对路径或相对 workspace folder。
- 请求头(metadata):
runner.metadata 里的条目作为每个方法 Headers 编辑器的初始值;在编辑器里增删改只影响后续调用,不回写设置。空 key 的行会被丢弃。
- 超时:一元调用在
timeoutMs 后未响应即返回 DEADLINE_EXCEEDED(0 = 不限);服务端流不受此限,可随时手动取消。
- int64 往返:
int64/uint64/sint64/fixed64/sfixed64 字段以字符串往返(表单用文本输入,响应里也是字符串),避免超过 2^53 的数值被截断;请求侧直接填十进制字符串即可。32 位整型仍为数字。
从 rpc_runner 迁移:把 rpc.config.json 里的 server 与 protoDir 两个值抄到上述 VS Code 设置即可。port 与 generatedDir 已删除(不再有 HTTP 服务与 proto-loader-gen-types 生成)。工作台与 gRPC 依赖(@grpc/grpc-js)采用懒加载,只在首次打开工作台时载入,不影响编辑功能激活速度。
修改 protoUtils.runner.* 设置后,下一次调用/刷新即按新配置执行,无需重开工作台(0.3.44 起;顶栏显示的服务器地址在重开面板后更新)。
配置
在 VS Code 设置中搜索 Proto Utils,或在工作区的 .vscode/settings.json 中配置 protoUtils.codeGen.*。
| 配置项 |
类型与可选值 |
默认值 |
作用 |
protoUtils.codeGen.outputDir |
string |
"generated" |
输出目录,相对于工作区根目录 |
protoUtils.codeGen.enumStyle |
"enum" | "union" |
"enum" |
将 Proto enum 生成为 TypeScript enum 或字符串字面量联合类型 |
protoUtils.codeGen.optionalMessageFields |
boolean |
true |
是否为非 repeated 的 message 类型字段添加 ? |
protoUtils.codeGen.optionalScalarFields |
boolean |
false |
是否为标量字段添加 ? |
protoUtils.codeGen.fieldNaming |
"camelCase" | "preserve" |
"camelCase" |
将字段名转换为 camelCase,或保留 Proto 原始名称 |
protoUtils.codeGen.pathMapping |
"file" | "package" |
"file" |
输出路径映射:相对 proto 公共根镜像目录结构,或按 package 语句 |
protoUtils.codeGen.importExtension |
"ts" | "none" |
"ts" |
生成的 import 路径是否带 .ts 后缀 |
protoUtils.codeGen.oneofStyle |
"optional" | "union" |
"optional" |
将 oneof 生成为可选字段或互斥联合类型 |
protoUtils.codeGen.int64Style |
"number" | "bigint" | "string" |
"number" |
64 位整数类型(int64/uint64/sint64/fixed64/sfixed64)的 TypeScript 映射 |
protoUtils.scan.excludeDirs |
string[] |
[] |
扫描 proto 时额外跳过的目录(runner 与代码生成共用);条目为目录名、workspace 相对路径或绝对路径 |
示例配置:
{
"protoUtils.codeGen.outputDir": "src/generated",
"protoUtils.codeGen.enumStyle": "union",
"protoUtils.codeGen.optionalMessageFields": true,
"protoUtils.codeGen.optionalScalarFields": false,
"protoUtils.codeGen.fieldNaming": "camelCase",
"protoUtils.codeGen.pathMapping": "file",
"protoUtils.codeGen.importExtension": "ts",
"protoUtils.codeGen.oneofStyle": "union",
"protoUtils.scan.excludeDirs": ["third_party"]
}
输出路径映射
默认 "file" 模式:先取所有 proto 文件的最长公共目录作为根,输出保留相对该根的目录结构。proto 全部平级时输出就是平铺:
protos/user.proto → <outputDir>/user.ts (所有 proto 平级位于 protos/)
protos/account/admin/x.proto → <outputDir>/account/admin/x.ts (公共根为 protos/ 时保留子结构)
使用 "package" 时,插件根据 package 语句生成路径:
package my.service;
对应:
<outputDir>/my/service.ts
如果文件没有 package,则回退到 "file" 模式的路径规则。
类型映射
| Proto3 类型 |
TypeScript 类型 |
double、float |
number |
各种 32 位整数类型(int32、uint32、sint32、fixed32、sfixed32) |
number |
各种 64 位整数类型(int64、uint64、sint64、fixed64、sfixed64) |
number(默认;由 protoUtils.codeGen.int64Style 决定,可为 bigint 或 string) |
bool |
boolean |
string |
string |
bytes |
Uint8Array |
repeated T |
T[] |
map<K, V> |
Record<K, V> |
message |
interface |
enum |
enum 或字符串字面量联合类型 |
service |
<Name>Client 调用接口(见「service 生成客户端调用接口」) |