Skip to content

Compiler: Bump protobuf to 3.7.2 from 2.27.1 #291

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ description = "A Rust version of ttrpc."
rust-version = "1.70"

[dependencies]
protobuf = { version = "3.1.0" }
protobuf = { version = "3.7.2" }
libc = { version = "0.2.59", features = [ "extra_traits" ] }
nix = "0.26.2"
log = "0.4"
byteorder = "1.3.2"
thiserror = "1.0"
async-trait = { version = "0.1.31", optional = true }
async-stream = { version = "0.3.6", optional = true }
tokio = { version = "1", features = ["rt", "sync", "io-util", "macros", "time"], optional = true }
tokio = { version = "1", features = ["rt", "sync", "io-util", "macros", "time", "net"], optional = true }
futures = { version = "0.3", optional = true }
crossbeam = "0.8.0"

Expand All @@ -33,7 +33,7 @@ tokio-vsock = { version = "0.7.0", optional = true }
[build-dependencies]
# lock home to avoid conflict with latest version
home = "=0.5.9"
protobuf-codegen = "3.1.0"
protobuf-codegen = "3.7.2"

[features]
default = ["sync"]
Expand Down
4 changes: 2 additions & 2 deletions compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ readme = "README.md"
[dependencies]
# lock home to avoid conflict with latest version
home = "=0.5.9"
protobuf = "2.27.1"
protobuf-codegen = "2.27.1"
protobuf = "3.7.2"
protobuf-codegen = "3.7.2"
prost = "0.8"
prost-build = "0.8"
prost-types = "0.8"
Expand Down
180 changes: 78 additions & 102 deletions compiler/src/codegen.rs

Large diffs are not rendered by default.

19 changes: 16 additions & 3 deletions compiler/src/util.rs → compiler/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use protobuf_codegen::code_writer::CodeWriter;
use std::fmt;
use std::str;

pub mod scope;
pub mod writer;

use writer::CodeWriter;

// A struct that divide a name into serveral parts that meets rust's guidelines.
struct NameSpliter<'a> {
name: &'a [u8],
Expand Down Expand Up @@ -111,9 +115,9 @@ where
F: Fn(&mut CodeWriter),
{
if public {
w.expr_block(&format!("pub async fn {}", sig), cb);
w.expr_block(format!("pub async fn {}", sig), cb);
} else {
w.expr_block(&format!("async fn {}", sig), cb);
w.expr_block(format!("async fn {}", sig), cb);
}
}

Expand All @@ -131,6 +135,15 @@ where
async_fn_block(w, false, sig, cb);
}

// proto_name_to_rs is constructor as "{proto_path_to_rust_mod}.rs"
// see https://github.com/stepancheg/rust-protobuf/blob/v3.7.2/protobuf-codegen/src/gen/paths.rs#L43
pub fn proto_path_to_rust_mod(path: &str) -> String {
protobuf_codegen::proto_name_to_rs(path)
.strip_suffix(".rs")
.unwrap()
.to_string()
}

pub enum MethodType {
Unary,
ClientStreaming,
Expand Down
152 changes: 152 additions & 0 deletions compiler/src/util/scope.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
//! This module contains functionalities that where previously available in
//! the protobuf / protobuf-codegen crates, but were then removed.
//! The missing functionalities have been reimplemented in this module.

use protobuf::descriptor::{DescriptorProto, FileDescriptorProto};

// vendered from https://github.com/stepancheg/rust-protobuf/blob/v3.7.2/protobuf-codegen/src/gen/rust/keywords.rs
fn is_rust_keyword(ident: &str) -> bool {
#[rustfmt::skip]
static RUST_KEYWORDS: &[&str] = &[
"_",
"as",
"async",
"await",
"break",
"crate",
"dyn",
"else",
"enum",
"extern",
"false",
"fn",
"for",
"if",
"impl",
"in",
"let",
"loop",
"match",
"mod",
"move",
"mut",
"pub",
"ref",
"return",
"static",
"self",
"Self",
"struct",
"super",
"true",
"trait",
"type",
"unsafe",
"use",
"while",
"continue",
"box",
"const",
"where",
"virtual",
"proc",
"alignof",
"become",
"offsetof",
"priv",
"pure",
"sizeof",
"typeof",
"unsized",
"yield",
"do",
"abstract",
"final",
"override",
"macro",
];
RUST_KEYWORDS.contains(&ident)
}

// reimplementation based on https://github.com/stepancheg/rust-protobuf/blob/v3.7.2/protobuf-codegen/src/gen/scope.rs#L26
// it only implements the `find_message` method with not extra dependencies
pub struct RootScope<'a> {
pub file_descriptors: &'a [FileDescriptorProto],
}

// re-implementation of https://github.com/stepancheg/rust-protobuf/blob/v3.7.2/protobuf-codegen/src/gen/scope.rs#L340
// also based on https://github.com/stepancheg/rust-protobuf/blob/v3.7.2/protobuf-codegen/src/gen/scope.rs#L156
pub struct ScopedMessage<'a> {
pub fd: &'a FileDescriptorProto,
pub path: Vec<&'a DescriptorProto>,
pub msg: &'a DescriptorProto,
}

impl ScopedMessage<'_> {
pub fn prefix(&self) -> String {
let mut prefix = String::new();
for m in &self.path {
prefix.push_str(m.name());
prefix.push('.');
}
prefix
}

// rust type name prefix for this scope
pub fn rust_prefix(&self) -> String {
self.prefix().replace(".", "_")
}

// rust type name of this descriptor
pub fn rust_name(&self) -> String {
let mut r = self.rust_prefix();
// Only escape if prefix is not empty
if r.is_empty() && is_rust_keyword(self.msg.name()) {
r.push_str("message_");
}
r.push_str(self.msg.name());
r
}

// fully-qualified name of this type
pub fn rust_fq_name(&self) -> String {
format!(
"{}::{}",
super::proto_path_to_rust_mod(self.fd.name()),
self.rust_name()
)
}
}

impl<'a> RootScope<'a> {
pub fn find_message(&'a self, fqn: impl AsRef<str>) -> ScopedMessage<'a> {
let Some(fqn1) = fqn.as_ref().strip_prefix(".") else {
panic!("name must start with dot: {}", fqn.as_ref())
};
for fd in self.file_descriptors {
let mut fqn2 = match fqn1.strip_prefix(fd.package()) {
Some(rest) if fd.package().is_empty() => rest,
Some(rest) if rest.starts_with(".") => &rest[1..],
_ => continue,
};

assert!(!fqn2.starts_with("."));

let mut pending = Some(fd.message_type.as_slice());
let mut path = vec![];
while let Some(msgs) = pending.take() {
for msg in msgs {
fqn2 = match fqn2.strip_prefix(msg.name()) {
Some("") => return ScopedMessage { msg, path, fd },
Some(rest) if rest.starts_with(".") => &rest[1..],
_ => continue,
};
path.push(msg);
pending = Some(&msg.nested_type);
break;
}
}
}
panic!("enum not found by name: {}", fqn.as_ref())
}
}
79 changes: 79 additions & 0 deletions compiler/src/util/writer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! This module contains functionalities that where previously available in
//! the protobuf / protobuf-codegen crates, but were then removed.
//! The missing functionalities have been reimplemented in this module.

// adapted from https://github.com/stepancheg/rust-protobuf/blob/v3.7.2/protobuf-codegen/src/gen/code_writer.rs#L12
#[derive(Default)]
pub struct CodeWriter {
writer: String,
indent: String,
}

impl CodeWriter {
pub fn new() -> CodeWriter {
Self::default()
}

pub fn code(&self) -> &str {
&self.writer
}

pub fn take_code(&mut self) -> String {
std::mem::take(&mut self.writer)
}

pub fn write_line(&mut self, line: impl AsRef<str>) {
if line.as_ref().is_empty() {
self.writer.push('\n');
} else {
self.writer.push_str(&self.indent);
self.writer.push_str(line.as_ref());
self.writer.push('\n');
}
}

pub fn block(
&mut self,
first_line: impl AsRef<str>,
last_line: impl AsRef<str>,
cb: impl FnOnce(&mut CodeWriter),
) {
self.write_line(first_line);
self.indented(cb);
self.write_line(last_line);
}

pub fn expr_block(&mut self, prefix: impl AsRef<str>, cb: impl FnOnce(&mut CodeWriter)) {
self.block(format!("{} {{", prefix.as_ref()), "}", cb);
}

pub fn indented(&mut self, cb: impl FnOnce(&mut CodeWriter)) {
self.indent.push_str(" ");
cb(self);
self.indent.truncate(self.indent.len() - 4);
}

pub fn pub_fn(&mut self, sig: impl AsRef<str>, cb: impl FnOnce(&mut CodeWriter)) {
self.expr_block(format!("pub fn {}", sig.as_ref()), cb)
}

pub fn def_fn(&mut self, sig: impl AsRef<str>, cb: impl FnOnce(&mut CodeWriter)) {
self.expr_block(format!("fn {}", sig.as_ref()), cb)
}

pub fn pub_struct(&mut self, name: impl AsRef<str>, cb: impl FnOnce(&mut CodeWriter)) {
self.expr_block(format!("pub struct {}", name.as_ref()), cb);
}

pub fn field_decl(&mut self, name: impl AsRef<str>, field_type: impl AsRef<str>) {
self.write_line(format!("{}: {},", name.as_ref(), field_type.as_ref()));
}

pub fn impl_self_block(&mut self, name: impl AsRef<str>, cb: impl FnOnce(&mut CodeWriter)) {
self.expr_block(format!("impl {}", name.as_ref()), cb);
}

pub fn pub_trait(&mut self, name: impl AsRef<str>, cb: impl FnOnce(&mut CodeWriter)) {
self.expr_block(format!("pub trait {}", name.as_ref()), cb);
}
}
6 changes: 1 addition & 5 deletions example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ homepage = "https://github.com/alipay/ttrpc-rust"
description = "An example of ttrpc."

[dev-dependencies]
protobuf = "3.1.0"
protobuf = "3.7.2"
bytes = "0.4.11"
libc = "0.2.79"
byteorder = "1.3.2"
Expand Down Expand Up @@ -51,7 +51,3 @@ path = "./async-stream-client.rs"

[build-dependencies]
ttrpc-codegen = { path = "../ttrpc-codegen"}

[patch.crates-io]
ttrpc-compiler = { path = "../compiler"}

8 changes: 4 additions & 4 deletions ttrpc-codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ readme = "README.md"
[dependencies]
# lock home to avoid conflict with latest version
home = "=0.5.9"
protobuf-support = "3.2.0"
protobuf = { version = "2.27.1" }
protobuf-codegen = "3.5.1"
ttrpc-compiler = "0.7.0"
protobuf-support = "3.7.2"
protobuf = "3.7.2"
protobuf-codegen = "3.7.2"
ttrpc-compiler = { version = "0.7.0", path = "../compiler" }
Loading