Skip to content

continue prost - #286

Open
jokemanfire wants to merge 13 commits into
containerd:masterfrom
jokemanfire:prost
Open

continue prost #286
jokemanfire wants to merge 13 commits into
containerd:masterfrom
jokemanfire:prost

Conversation

@jokemanfire

@jokemanfire jokemanfire commented Feb 24, 2025

Copy link
Copy Markdown
Member

work continue with #173

Closes #258

@jokemanfire jokemanfire changed the title continue prost continue prost (not complete) Feb 24, 2025
@Tim-Zhang

Tim-Zhang commented Feb 25, 2025

Copy link
Copy Markdown
Member

@jokemanfire I appreciate you taking on this work very much.
Why don't we directly reopen #173 and continue the work?
Just let me know if there are any difficulties.

Thanks agian.

@jokemanfire

Copy link
Copy Markdown
Member Author

@jokemanfire I appreciate you taking on this work very much. Why don't we directly reopen #173 and continue the work? Just let me know if there are any difficulties.

Thanks agian.

There are some conflicts and API changes that need to be resolved and some code needs to be packaged to adapt to the current API. It's not easy to operate with the previous version of PR. I need to add some commit to complete this feature. I have communicated with the original author.

@jokemanfire

Copy link
Copy Markdown
Member Author

@Tim-Zhang @justxuewei Local test all pass but i don't know how to install protoc in CI.

@jokemanfire jokemanfire changed the title continue prost (not complete) continue prost Mar 13, 2025
@Tim-Zhang

Copy link
Copy Markdown
Member

@jokemanfire
jokemanfire force-pushed the prost branch 3 times, most recently from 21ebbd3 to 4a76b7b Compare April 1, 2025 12:19
@jokemanfire
jokemanfire force-pushed the prost branch 3 times, most recently from a29312f to 5fadae0 Compare April 9, 2025 09:50
@jokemanfire

jokemanfire commented Apr 9, 2025

Copy link
Copy Markdown
Member Author

Basically enough @Tim-Zhang @justxuewei just take a look . :)

@justxuewei

justxuewei commented Apr 10, 2025

Copy link
Copy Markdown
Contributor

Nice work, thanks @jokemanfire! Could you cleanup your commits? It makes us easier to review and maintain.

  1. Use git rebase instead of git merge.
  2. Modify the commit title to {subsystem}: {brief title for your changes}, and give it a brief introduction in the commit message.
  3. Split your commits, and don't mix bugfixes, refactoring and new features.
  4. Please modify this PR title to something like "codegen: Introduce a new codegen using prost".

Thanks!

@jokemanfire

Copy link
Copy Markdown
Member Author

Nice work, thanks @jokemanfire! Could you cleanup your commits? It makes us easier to review and maintain.好的工作,谢谢!你能清理一下你的提交吗?这让我们更容易审查和维护。

  1. Use git rebase instead of git merge.使用 git rebase 代替 git merge
  2. Modify the commit title to {subsystem}: {brief title for your changes}, and give it a brief introduction in the commit message.修改提交标题为 {subsystem}: {brief title for your changes} ,并在提交信息中简要介绍。
  3. Split your commits, and don't mix bugfixes, refactoring and new features.拆分您的提交,不要混合修复错误、重构和新功能。
  4. Please modify this PR title to something like "codegen: Introduce a new codegen using prost".请将此 PR 标题修改为类似于“codegen:引入使用 prost 的新代码生成器”的标题。

Thanks!  谢谢!

I have changed it.

@jokemanfire
jokemanfire force-pushed the prost branch 5 times, most recently from 00fce61 to 735a10e Compare April 10, 2025 07:40
@justxuewei

Copy link
Copy Markdown
Contributor

Once this feature gets merged, I prefer to bump a major version to 2 to avoid some compatibility issues, as it nearly changes the entire codegen engine. WDYT? @jokemanfire @Tim-Zhang

@jokemanfire

Copy link
Copy Markdown
Member Author

Once this feature gets merged, I prefer to bump a major version to 2 to avoid some compatibility issues, as it nearly changes the entire codegen engine. WDYT? 一旦这个功能合并,我更倾向于将主版本号提升到 2,以避免一些兼容性问题,因为它几乎改变了整个代码生成引擎。你怎么看?@jokemanfire @Tim-Zhang

This modification is indeed quite significant, and I agree. It depends on the maintainer's thoughts

Comment thread build.rs
let path: PathBuf = [out_dir.clone(), "mod.rs".to_string()].iter().collect();
fs::write(path, "pub mod ttrpc;").unwrap();

generate_ttrpc(&out_dir);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get unified internal APIs which was defined in ttrpc.proto, how about keeping build script untouched?

I think we can try to avoid so many condition compiling sentences like #[cfg(not(feature = "prost"))] in code.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right ,I think adding a transformation to the camel hump naming convention can reduce this conditional compilation code

@jokemanfire

Copy link
Copy Markdown
Member Author

I tried to minimize conditional compilation as much as possible @Tim-Zhang @justxuewei

@jokemanfire

jokemanfire commented Jun 24, 2025

Copy link
Copy Markdown
Member Author

@Tim-Zhang Can you take some time to advance this feature? In the previous puncture, it was found that the prost library uses less memory during operation than the Rust Protobuf library

Tim-Zhang

This comment was marked as outdated.

@Tim-Zhang Tim-Zhang left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several generator edge cases, size-limit regressions, and CI issues remain. The inline comments also include refactoring and idiomatic-Rust feedback focused on containing backend-specific behavior, reducing duplication, and avoiding unnecessary allocations and API divergence. Please address the inline findings before merge and add focused fixtures for imported types, multiple services with overlapping method names, and package-less schemas.

Comment thread README.md Outdated
Comment thread src/lib.rs
Comment thread codegen/src/svcgen.rs Outdated
Comment thread codegen/src/svcgen.rs Outdated
Comment thread codegen/src/svcgen.rs Outdated
Comment thread codegen/src/codegen.rs Outdated
Comment thread Cargo.toml
Comment thread codegen/src/util.rs
let mut camel_case_name = String::with_capacity(name.len());
for s in NameSpliter::new(name) {
let mut chs = s.chars();
camel_case_name.extend(chs.next().unwrap().to_uppercase());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor/correctness: this custom name splitter can yield an empty segment after leading underscores and then panic at this unwrap; it also reimplements casing already handled by established Rust casing utilities and by normalized prost-build names. Prefer those normalized names or a well-tested casing helper.

Comment thread example2/Cargo.toml
Comment thread .gitignore Outdated
@Tim-Zhang
Tim-Zhang dismissed their stale review August 5, 2026 13:15

Superseded by the inline review with additional refactoring feedback.

@Tim-Zhang

Copy link
Copy Markdown
Member

@jokemanfire I have left a few review comments, and btw please resolve the conflicts, thanks.

@jokemanfire

Copy link
Copy Markdown
Member Author

@jokemanfire I have left a few review comments, and btw please resolve the conflicts, thanks.

thanks , I will take some time to resolve it.

justxuewei and others added 12 commits August 10, 2026 11:32
This commit refactors the ttrpc-codegen and the compiler, and merges the two
crates into a single crate, named "codegen". The codegen uses prost crate, a
protobuf compiler for Rust.

Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
The ttrpc provides a "prost" feature to support the new version of
codegen. An "example2" has been added to demonstrate how to use the
codegen.

Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
Install protoc when executing `make deps` of the ttrpc. Add codegen's
check and build, and example2' build to the ci testing.

Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
Fix all issues reported by cargo clippy to make ci testing pass.

Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
merge from remote branch.
ref: containerd#173

Co-authored-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
fix ci for protoc

Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
because of the api change
1. fix the marco in prost
2. fix the test

Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
fix rebase error.

Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
skip build example2 in windows

Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
while use protoc,rename the Code enum.

Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
fix marco

Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
Resolve Tim-Zhang's review on containerd#286 and adapt the prost backend to the
master workspace.

codegen (prost):
- Use path-aware type_token() for method input/output types instead of
  format_ident!(), which panicked on qualified paths like
  super::google::protobuf::Empty.
- Emit package-level imports once via finalize_package instead of per
  service, fixing E0252 on packages with multiple services.
- Prefix per-method handler types with the service name so overlapping
  method names (Foo.Get / Bar.Get) no longer collide.
- Make NameSpliter robust against empty segments to avoid panics on
  underscore-only / trailing-underscore names.
- Refactor CodegenBuilder to owned PathBuf/Vec<PathBuf>, direct defaults,
  and build(self); drop the unrelated P: Default bound.
- Add focused fixtures for imported types, overlapping method names, and
  package-less schemas.

runtime / deps:
- Align the prost family to 0.13 across ttrpc, prost-build, codegen, and
  example2 to avoid version drift.
- Configure docs.rs with an explicit compatible feature set instead of
  all-features (prost and rustprotobuf are mutually exclusive).

build / ci / docs:
- Makefile: use $(OS) so the Windows branch is reachable.
- bvt.yml: keep shell: bash on the multi-command Build step.
- .gitignore: drop duplicate example2 rules.
- README: document default-features = false for the prost feature.
- build.rs: operate on the generated content in place (no clone).

rebase onto master:
- Adopt master's Cargo workspace; keep codegen and example2 as standalone
  workspace roots to avoid the ttrpc-codegen name collision.
- Silence clippy::doc_overindented_list_items in prost-generated code.
- Fix a stray brace in tests/run-examples.rs introduced during rebase.

Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request continues the migration path toward supporting tokio-rs/prost alongside the existing rust-protobuf backend, adding a new standalone prost-based codegen crate plus a new example2 tree to exercise the prost workflow, and updating CI/build plumbing to install protoc and test both backends.

Changes:

  • Add prost + rustprotobuf mutually-exclusive feature support in the ttrpc crate, with conditional encode/decode paths across sync/async runtimes.
  • Introduce a new standalone codegen/ crate (prost-build based) and a new example2/ project that uses it.
  • Update CI and build scripts (including a new install_protoc.sh) to ensure protoc is available and both backends build/test appropriately.

Reviewed changes

Copilot reviewed 54 out of 55 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
ttrpc-codegen/Makefile Add local check/test targets for the legacy codegen crate.
compiler/Makefile Add local check/test targets for the compiler crate.
tests/run-examples.rs Run examples conditionally for rustprotobuf vs prost and add per-example working directory support.
src/ttrpc.proto Change proto package to ttrpc (aligns with prost codegen expectations).
src/sync/utils.rs Add prost-specific request/response helpers and macro variants.
src/sync/server.rs Add prost decode/encode handling in sync server request path.
src/sync/mod.rs Export utils as public module (macros/helpers used externally).
src/sync/client.rs Add prost-specific oversize/status handling in sync client.
src/proto.rs Add Codec impl for prost messages and gate protobuf stream codecs behind feature flags.
src/lib.rs Re-export sync helpers and enforce mutual exclusivity of prost/rustprotobuf.
src/error.rs Make Error -> Response and get_status work for both backends.
src/context.rs Construct metadata KeyValue values compatibly for both backends.
src/asynchronous/utils.rs Add prost variants of async handler/client macros and gate existing ones.
src/asynchronous/server.rs Adjust async server response/status paths for prost message layout/size checks.
src/asynchronous/client.rs Make async client request conversion/status handling work for both backends.
README.md Document how to use the prost backend and its differences.
Makefile Split CI checks/tests to run rustprotobuf and prost configurations (and skip prost where needed on Windows).
install_protoc.sh Add helper to install protoc across GitHub Actions runner OSes.
example2/utils.rs Add shared utilities for the prost-based example project.
example2/server.rs Add sync prost example server.
example2/protocols/sync/mod.rs Include generated sync prost protocol modules.
example2/protocols/protos/streaming.proto Add streaming proto schema for example2.
example2/protocols/protos/oci.proto Add OCI proto schema for example2.
example2/protocols/protos/health.proto Add health proto schema for example2.
example2/protocols/protos/google/protobuf/test_empty.proto Add test Empty message for example2 protos.
example2/protocols/protos/google/protobuf/empty.proto Vendor protobuf well-known Empty type for example2 compilation.
example2/protocols/protos/google/protobuf/descriptor.proto Vendor protobuf descriptor type for example2 compilation.
example2/protocols/protos/github.com/kata-containers/agent/pkg/types/types.proto Vendor kata agent types proto used by example2.
example2/protocols/protos/github.com/gogo/protobuf/gogoproto/gogo.proto Vendor gogo proto options used by example2 schemas.
example2/protocols/protos/agent.proto Vendor kata agent service proto used by example2.
example2/protocols/mod.rs Define example2 protocol module layout.
example2/protocols/hack/update-generated-proto.sh Add script for updating/regenerating vendored protos + rust output.
example2/protocols/asynchronous/mod.rs Include generated async prost protocol modules.
example2/Makefile Add build/build-examples/deps targets (including protoc install).
example2/client.rs Add sync prost example client.
example2/Cargo.toml Define example2 crate dependencies and examples (prost + ttrpc prost feature).
example2/build.rs Generate sync/async prost services via new codegen crate.
example2/async_stream_server.rs Add async streaming server example for prost.
example2/async_stream_client.rs Add async streaming client example for prost.
example2/async_server.rs Add async unary server example for prost.
example2/async_client.rs Add async unary client example for prost.
example/protocols/sync/mod.rs Adjust example protocol module exports for legacy layout.
example/protocols/asynchronous/mod.rs Adjust example async protocol module exports for legacy layout.
example/Cargo.toml Ensure example explicitly enables rustprotobuf backend feature.
codegen/src/util.rs Add identifier casing/type-path helper utilities for prost codegen.
codegen/src/svcgen.rs Implement prost-build ServiceGenerator for ttrpc services/clients (sync+async+streaming).
codegen/src/lib.rs Export the codegen API surface.
codegen/src/codegen.rs Implement codegen builder + header injection using prost-build and fd_set introspection.
codegen/README.md Document how to use the new prost-based codegen crate.
codegen/Makefile Add build/test/check/deps targets for codegen crate.
codegen/Cargo.toml Define new standalone ttrpc-codegen (prost-based) crate.
Cargo.toml Add optional prost deps, define prost vs rustprotobuf features, and exclude new standalone crates from workspace.
build.rs Generate ttrpc protos via protobuf-codegen or prost-build depending on selected backend, with prost enum variant rewriting.
.gitignore Ignore generated protocol Rust files while keeping mod.rs tracked for both example trees.
.github/workflows/bvt.yml Install protoc in CI and build example2 as part of the build job.
Suppressed comments (2)

src/sync/utils.rs:182

  • In the prost client macro, merge is called with an immutable slice. prost::Message::merge needs &mut input (e.g. &mut &[u8]), otherwise this won’t compile.
    src/asynchronous/utils.rs:317
  • In the prost async client macro, merge is called with an immutable slice. prost::Message::merge requires &mut input (e.g. &mut &[u8]), otherwise it won’t compile.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/sync/utils.rs
Comment thread src/asynchronous/utils.rs
Comment thread src/sync/server.rs
Comment thread src/sync/client.rs
Comment thread src/sync/utils.rs Outdated
Comment thread src/error.rs Outdated
Comment thread README.md
Comment thread tests/run-examples.rs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 54 out of 55 changed files in this pull request and generated 2 comments.

Suppressed comments (10)

src/sync/utils.rs:113

  • With the prost backend, prost::Message::merge expects a mutable Buf (e.g. &mut &[u8]). Passing an immutable &[u8] won’t type-check, so this macro expansion will fail to compile under --features prost.
    src/sync/utils.rs:182
  • In the prost client_request! macro, prost::Message::merge requires a mutable Buf (e.g. &mut &[u8]). The current merge(&res.payload as &[u8]) will not compile with prost 0.13.
    src/asynchronous/utils.rs:317
  • In the prost async_client_request! macro, prost::Message::merge requires a mutable Buf (e.g. &mut &[u8]). The current merge(&res.payload as &[u8]) won’t type-check with prost 0.13.
    tests/run-examples.rs:126
  • In the prost test block, the sync server/client example is commented out, so CI no longer exercises the basic sync example under the prost backend even though example2 provides it.
    src/sync/client.rs:166
  • For the prost backend, the oversize check currently only considers req.payload.len(), but the encoded request size also includes service, method, metadata, etc. This can bypass the max message size check with large metadata. Use the encoded size instead (via the existing Codec::size() implementation).
    src/sync/utils.rs:58
  • The prost response_to_channel variant doesn’t enforce check_oversize like the rustprotobuf path does. That can send oversized responses and violate the library’s message size limits. Mirror the existing oversize handling before sending.

This issue also appears in the following locations of the same file:

  • line 110
  • line 179
    compiler/Makefile:8
  • make -C compiler (as invoked by .github/workflows/bvt.yml) now defaults to running only the check target, which means the build job no longer actually builds/tests this crate by default. Add an explicit all default target (or restore the previous include-based targets) so CI and local make behave as expected.
.PHONY: check
check:
	cargo fmt --all -- --check
	cargo clippy --all-targets -- -D warnings

ttrpc-codegen/Makefile:8

  • make -C ttrpc-codegen (as invoked by .github/workflows/bvt.yml) now defaults to running only the check target, so the build job no longer builds/tests this crate by default. Add an all default target so make continues to validate both linting and tests.
    Makefile:3
  • PROTOC is introduced but not used anywhere in the Makefile (no $(PROTOC) references). This adds confusion for maintainers; either wire it into the relevant targets or remove it.
PROTOC ?= $(shell which protoc 2>/dev/null || echo $(HOME)/protoc/bin/protoc)

all: debug test

src/error.rs:17

  • use crate::proto::{self, ...} imports proto::self but it’s never referenced, and the surrounding #[allow(unused_imports)] masks that. This can hide real unused-import issues; remove the unused import and the allow.

Comment thread src/asynchronous/utils.rs
Comment thread src/sync/server.rs
- error.rs: drop the unused `self` (proto module) import and the
  `#[allow(unused_imports)]` that masked it; Code/Response/Status are the
  only proto items referenced in this file.
- sync/utils.rs: replace `#[allow(unused_imports)]` with explicit
  `#[cfg(not(feature = "prost"))]` gating for `Codec` and `check_oversize`,
  which are only used by the rustprotobuf backend (`Codec` provides the
  `encode()` trait method). Shared imports remain ungated.
- README.md: fix "genereated" typo.
- tests/run-examples.rs: remove a commented-out dead example2 call.

Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
@jokemanfire
jokemanfire requested a review from Tim-Zhang August 12, 2026 09:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

can we change protobuf to tokio-rs/prost?

4 participants