From 7ae72311d3e4722ba8a95acb95c60c0496b6cb75 Mon Sep 17 00:00:00 2001 From: Eugene Blikh Date: Sun, 17 May 2026 07:23:47 +0300 Subject: [PATCH] docs(readme): vendoring an upstream .proto schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consumers vendoring upstream protos (etcd, prometheus, pprof, …) hit annotation-import resolution that protoc-gen-tarantool can't fix on its own — mainline protoc rejects files with unresolved imports like versionpb / google.api / gogoproto. Document the standard workaround: strip the offending imports + their attached options, optionally rewrite cross-package imports to a flat layout, then run protoc. Reference implementation: tarantool-etcd's proto/_strip_annotations.py. --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/README.md b/README.md index 3df3bd2d22cc1e2c41d7e4dd484ed151805a4945..2e0394fa69965f0bb434187031de07506865e9aa 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,50 @@ prefix is prepended to the option's value. See For a full walk-through that takes a fresh `.proto` to a Tarantool process encoding and decoding it, see **[docs/howto/01-first-message.md](docs/howto/01-first-message.md)**. +## Vendoring an upstream `.proto` schema + +If you're vendoring someone else's `.proto` into your project (etcd, +prometheus, opentelemetry, pprof, …), `protoc-gen-tarantool` plus a +small preprocessor is the typical path. + +Upstream protos commonly import annotation extensions that only the +original generator consumes — `versionpb`, `google.api`, `gogoproto`, +`grpc.gateway.protoc_gen_openapiv2`. Mainline `protoc` won't parse a +file with an unresolved import, so the choice is between vendoring the +extension `.proto` files (lots of additional surface, no wire effect) +or stripping the imports and their attached options before generating. +Stripping is the lower-cost path — these annotations affect nothing on +the wire. + +A drop-in preprocessor (one `python3` script, no dependencies) should +drop `import "versionpb/...";` / `google/api/...` / `gogo.proto` / +`protoc-gen-openapiv2/...` lines, drop single-line and brace-balanced +`option (foo.bar) = ...;` blocks at file/message/field scope, and drop +inline field options `[(foo.bar) = "..."]`. Reference: tarantool-etcd's +[`proto/_strip_annotations.py`][strip] (~60 lines). + +The same preprocessor is also where you rewrite cross-package imports +to a flat layout: e.g. `import "etcd/api/mvccpb/kv.proto"` → +`import "mvccpb/kv.proto"`, so a single `protoc -I proto` resolves +every file without mirroring the upstream subdirectory tree. + +Putting it together: + +```bash +mkdir -p proto/ +for f in upstream//*.proto; do + python3 strip_annotations.py < "$f" > proto//"$(basename "$f")" +done +protoc -I proto --tarantool_out=prefix=myapp.proto:out $(find proto -name '*.proto') +``` + +One pitfall: this plugin is proto3-only. If an upstream schema mixes +proto2 and proto3, either skip the proto2 files (provided your proto3 +side doesn't import them) or wait for proto2 support — see PLAN.md's +deferred non-goals. + +[strip]: https://git.srht.bigb.es/tarantool-etcd/tree/master/item/proto/_strip_annotations.py + ## Generated API For each message `Foo` the plugin emits: