前言

工作过程中可能会遇到项目中用到的protoc-gen-go插件和自己个人项目版本不一致的问题, 或者没有使用官方的 protoc-gen-go插件的情况, 这时候就需要一些黑科技来完美完成各自的需要.

假设我们目前有一个以上的非官方插件


方案一

直接go get下载第三方的protoc-gen-go

然后会自动安装第三方的protoc-gen-go工具到$GOPATH/bin目录下

注意: 只要安装的库的名字为protoc-gen-go, 下载时都会替换$GOPATH/bin下的protoc-gen-go可执行文件

该方法很暴力, 但是缺点是不够灵活

想换成官方插件, 可以把官方生成的改个名字一起放在$GOPATH/bin

此时该目录下形如

1
2
protoc-gen-go 
protoc-gen-go.official

前者是第三方插件, 后者为官方. 根据需求把正确的插件改名为protoc-gen-go, 千万不要搞混了

使用官方插件的项目

1
2
3
4
cd $GOPATH/bin
mv protoc-gen-go protoc-gen-go.other
mv protoc-gen-go.official protoc-gen-go
protoc --proto_path=. --go_out=.

使用第三方插件的项目

1
2
3
4
cd $GOPATH/bin
mv protoc-gen-go protoc-gen-go.official
mv protoc-gen-go.other protoc-gen-go
protoc --proto_path=. --go_out=.


方案二

如果你接触过其他 rpc 语言, 会发现其他语言的插件名字类似, 只是后缀不同

java 版的生成命令类似于

1
protoc --proto_path=. --java_out=. *.proto

golang版的生成命令类似于

1
protoc --proto_path=. --go_out=. *.proto

因为protoc 工具就是根据--NAME_out中的 NAME 匹配然后去自动选择protoc-gen-NAME插件的

知道这个就很容易了, 我们可以在不同的项目里用不同的生成代码命令

使用官方插件的项目

1
protoc --proto_path=. --go.official_out=. *.proto

protoc会自动在$PATH寻找protoc-gen-go.official工具去生成代码

使用第三方插件的项目

1
protoc --proto_path=. --go_out=. *.proto

protoc会自动在$PATH寻找protoc-gen-go工具去生成代码

扩展

protoc 还有个选项是plugins, 如果在项目里用到 grpc 就会使用这种代码生成命令

1
protoc --proto_path=. --go_out=plugins=grpc:. *.proto

protoc会自动在github.com/golang/protobuf/protoc-gen-go/目录下寻找groc/grpc.go作为插件

所以如果你依然不打算用官方的 grpc 插件, 依然可以根据修改插件名字, 放在该目录下, 最后修改plugins的参数来完成指定插件的操作