protoc 自動生成go文件最重要,也比較容易混淆的問題時,是生成路徑的參數(shù),本文簡要介紹編寫protoc go插件的參數(shù)形式,以及影響go文件生成的路徑
命令行參數(shù)
通常protoc-gen-go生成器不需要命令行參數(shù)。但是,在某些復(fù)雜的情況下,它們是完成任務(wù)的唯一方法,尤其是在設(shè)置要在生成的代碼中使用的導(dǎo)入路徑時。
- 傳遞參數(shù)
通過將參數(shù)值放在--go_out后,傳遞給go生成器。參數(shù)是由多個鍵值對(key=value)使用“,”連接起來的字符串, 如"a=111,b=222,c=333"。
下面的例子中, 參數(shù) a=111,b=222以及import_prefix=xxx/傳給 test 生成器,protoc-gen-test 是自定義的測試代碼,會打印接收到的參數(shù)值。

protoc --test_out=a=111,b=222,import_prefix=xxx/:./db/ --plugin=protoc-gen-test=./protoc-gen-test feed.proto
2021/03/05 11:13:58 protoc-gen-test: info: map[string]string{"a":"111", "b":"222", "import_prefix":"xxx/"}
proto-gen-go的路徑參數(shù)
影響 proto-gen-go 中的路徑參數(shù)由如下幾個:
- import_prefix=xxx/: 它為所有生成的import路徑添加前綴
- go_package : proto file 文件中的option選項, 控制生成文件的包路徑
- import_path=foo/bar:如果文件沒有聲明go_package,則用作包名。如果它包含斜杠,那么最右邊的斜杠將被忽略。
- Mfoo/bar.proto=quux/shme: M參數(shù),指定.proto文件編譯后的包名(foo/bar.proto編譯后為包名為quux/shme)
- paths
其中import_prefix 和 M 參數(shù)的區(qū)別是:import_prefix 是整體, M 參數(shù)是每個包單獨修改
import_prefix
包公共前綴, 會在生成的import導(dǎo)入源前統(tǒng)一添加引用路徑前綴
為使用import_prefix 生成的文件
package com_ktkt_srv_feed
// Code generated by protoc-gen-test. DO NOT EDIT.
// source: feed.proto
package com_ktkt_srv_feed
import (
proto "github.com/golang/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
使用 import_prefix=xxx/生成的文件, 會在import的路徑前自動添加 xxx/前綴
// Code generated by protoc-gen-test. DO NOT EDIT.
// source: feed.proto
package com_ktkt_srv_feed
import (
proto "xxx/github.com/golang/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
go_package options
protocol buffer language 的 package 概念和go語言中的概念不太吻合。因此增加了一個go_package 的選項,定義了go包文件的導(dǎo)入路徑,路徑的最后一個部分,將成為go package的名稱。
package com.ktkt.srv.feed;
option go_package = "github.com/test/aaa/bbb/testpb";
執(zhí)行生成命令
protoc --test_out=./db/ --plugin=protoc-gen-test=./protoc-gen-test feed.proto
生成的文件路徑:

最終生成的文件, go包名為testpb, 為go_package的最終一級路徑
// Code generated by protoc-gen-test. DO NOT EDIT.
// source: feed.proto
package testpb
import (
proto "github.com/golang/protobuf/proto"
)
var _ = proto.Marshal
import_path
如果沒有g(shù)o_package 選項, import_path 確定包名稱。如果import_path 包含斜線, 則最右側(cè)斜線之前的內(nèi)容都會被忽略掉, 最右側(cè)斜線后面的內(nèi)容作為包名
M<proto filename>=<go import path>
M的作用是修改單個包的生成和引用路徑
例如: Mfoo/bar.proto=quux/shme 聲明 foo/bar.proto生成的包為 quux/shme。 這也取決于 import_prefix 參數(shù).
使用:
1. 在定義proto文件時, 添加import,引入外部proto文件
2. 生成時指定M選項
syntax = "proto3";
package stock;
import "google/api/annotations.proto";
protoc -I=$GOPATH/src --gogo_out=plugins=Mgoogle/api/annotations.proto=github.com/gogo/googleapis/google/api:. input/*.proto
paths
用于指定生成文件的路徑的結(jié)構(gòu),有兩個值
- paths=import 相對于導(dǎo)入路徑, 默認值
- paths=source_relative 相對于輸入文件,即proto文件的路徑
參考文獻: