Skip to content
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

Add support for wrapping message in Option #657

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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: 6 additions & 0 deletions proto/rustproto.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ extend google.protobuf.FileOptions {
optional bool tokio_bytes_all = 17011;
// Use `bytes::Bytes` for `string` fields
optional bool tokio_bytes_for_string_all = 17012;
// Use `Option` for `message` fields.
optional bool option_for_message_all = 17013;

// When true, will only generate codes that works with lite runtime.
optional bool lite_runtime_all = 17035;
Expand All @@ -33,6 +35,8 @@ extend google.protobuf.MessageOptions {
optional bool tokio_bytes = 17011;
// Use `bytes::Bytes` for `string` fields
optional bool tokio_bytes_for_string = 17012;
// Use `Option` for `message` fields.
optional bool option_for_message = 17013;
}

extend google.protobuf.FieldOptions {
Expand All @@ -44,4 +48,6 @@ extend google.protobuf.FieldOptions {
optional bool tokio_bytes_field = 17011;
// Use `bytes::Bytes` for `string` fields
optional bool tokio_bytes_for_string_field = 17012;
// Use `Option` for `message` fields.
optional bool option_for_message_field = 17013;
}
12 changes: 12 additions & 0 deletions protobuf-codegen/src/customize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ pub struct Customize {
pub(crate) tokio_bytes: Option<bool>,
/// Use `bytes::Bytes` for `string` fields
pub(crate) tokio_bytes_for_string: Option<bool>,
/// Use `Option` for `message` fields.
pub(crate) option_for_message: Option<bool>,
/// Enable lite runtime.
pub(crate) lite_runtime: Option<bool>,
/// Generate `mod.rs` in the output directory.
Expand Down Expand Up @@ -148,6 +150,11 @@ impl Customize {
self
}

pub fn option_for_message(mut self, option_for_message: bool) -> Self {
self.option_for_message = Some(option_for_message);
self
}

/// Generate code for "lite runtime". Generated code contains no code for reflection.
/// So the generated code (and more importantly, generated binary size) is smaller,
/// but reflection, text format, JSON serialization won't work.
Expand Down Expand Up @@ -188,6 +195,9 @@ impl Customize {
if let Some(v) = that.tokio_bytes_for_string {
self.tokio_bytes_for_string = Some(v);
}
if let Some(v) = that.option_for_message {
self.option_for_message = Some(v)
}
if let Some(v) = that.lite_runtime {
self.lite_runtime = Some(v);
}
Expand Down Expand Up @@ -232,6 +242,8 @@ impl Customize {
r.tokio_bytes = Some(parse_bool(v)?);
} else if n == "tokio_bytes_for_string" {
r.tokio_bytes_for_string = Some(parse_bool(v)?);
} else if n == "option_for_message" {
r.option_for_message = Some(parse_bool(v)?);
} else if n == "lite_runtime" {
r.lite_runtime = Some(parse_bool(v)?);
} else if n == "gen_mod_rs" {
Expand Down
6 changes: 6 additions & 0 deletions protobuf-codegen/src/customize/rustproto_proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub(crate) fn customize_from_rustproto_for_message(source: &MessageOptions) -> C
let generate_getter = rustproto::exts::generate_getter.get(source);
let tokio_bytes = rustproto::exts::tokio_bytes.get(source);
let tokio_bytes_for_string = rustproto::exts::tokio_bytes_for_string.get(source);
let option_for_message = rustproto::exts::option_for_message.get(source);
let lite_runtime = None;
let gen_mod_rs = None;
let inside_protobuf = None;
Expand All @@ -21,6 +22,7 @@ pub(crate) fn customize_from_rustproto_for_message(source: &MessageOptions) -> C
generate_getter,
tokio_bytes,
tokio_bytes_for_string,
option_for_message,
lite_runtime,
gen_mod_rs,
inside_protobuf,
Expand All @@ -37,6 +39,7 @@ pub(crate) fn customize_from_rustproto_for_field(source: &FieldOptions) -> Custo
let generate_getter = rustproto::exts::generate_getter_field.get(source);
let tokio_bytes = rustproto::exts::tokio_bytes_field.get(source);
let tokio_bytes_for_string = rustproto::exts::tokio_bytes_for_string_field.get(source);
let option_for_message = rustproto::exts::option_for_message_field.get(source);
let lite_runtime = None;
let gen_mod_rs = None;
let inside_protobuf = None;
Expand All @@ -46,6 +49,7 @@ pub(crate) fn customize_from_rustproto_for_field(source: &FieldOptions) -> Custo
generate_getter,
tokio_bytes,
tokio_bytes_for_string,
option_for_message,
lite_runtime,
gen_mod_rs,
inside_protobuf,
Expand All @@ -58,6 +62,7 @@ pub(crate) fn customize_from_rustproto_for_file(source: &FileOptions) -> Customi
let generate_getter = rustproto::exts::generate_getter_all.get(source);
let tokio_bytes = rustproto::exts::tokio_bytes_all.get(source);
let tokio_bytes_for_string = rustproto::exts::tokio_bytes_for_string_all.get(source);
let option_for_message = rustproto::exts::option_for_message_all.get(source);
let lite_runtime = rustproto::exts::lite_runtime_all.get(source);
let gen_mod_rs = None;
let inside_protobuf = None;
Expand All @@ -67,6 +72,7 @@ pub(crate) fn customize_from_rustproto_for_file(source: &FileOptions) -> Customi
generate_getter,
tokio_bytes,
tokio_bytes_for_string,
option_for_message,
lite_runtime,
inside_protobuf,
gen_mod_rs,
Expand Down
19 changes: 13 additions & 6 deletions protobuf-codegen/src/gen/field/accessor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,21 @@ impl FieldGen<'_> {
fn accessor_fn_singular_with_flag(
&self,
elem: &FieldElem,
_option_kind: OptionKind,
option_kind: OptionKind,
) -> AccessorFn {
match elem {
FieldElem::Message(m) => AccessorFn {
name: "make_message_field_accessor".to_owned(),
type_params: vec![format!("{}", m.rust_name_relative(&self.file_and_mod()))],
callback_params: self.make_accessor_fns_lambda(),
},
FieldElem::Message(m) => {
let name = if option_kind == OptionKind::MessageField {
"make_message_field_accessor".to_owned()
} else {
"make_option_accessor".to_owned()
};
AccessorFn {
name,
type_params: vec![format!("{}", m.rust_name_relative(&self.file_and_mod()))],
callback_params: self.make_accessor_fns_lambda(),
}
}
FieldElem::Primitive(..) | FieldElem::Enum(..) => AccessorFn {
name: "make_option_accessor".to_owned(),
type_params: vec!["_".to_owned()],
Expand Down
28 changes: 22 additions & 6 deletions protobuf-codegen/src/gen/field/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,11 @@ impl<'a> FieldGen<'a> {
let required = field.field.proto().label()
== field_descriptor_proto::Label::LABEL_REQUIRED;
let option_kind = match field.field.proto().type_() {
field_descriptor_proto::Type::TYPE_MESSAGE => OptionKind::MessageField,
field_descriptor_proto::Type::TYPE_MESSAGE
if customize.option_for_message != Some(true) =>
{
OptionKind::MessageField
}
_ => OptionKind::Option,
};

Expand Down Expand Up @@ -995,11 +999,23 @@ impl<'a> FieldGen<'a> {
fn write_merge_from_singular_case_block(&self, s: &SingularField, w: &mut CodeWriter) {
w.case_block(&format!("{}", self.tag()), |w| match s.elem {
FieldElem::Message(..) => {
w.write_line(&format!(
"{}::rt::read_singular_message_into_field(is, &mut self.{})?;",
protobuf_crate_path(&self.customize),
self.rust_name,
));
if let SingularFieldFlag::WithFlag {
option_kind: OptionKind::Option { .. },
..
} = &s.flag
{
w.write_line(&format!(
"{}::rt::read_option_message_into_field(is, &mut self.{})?;",
protobuf_crate_path(&self.customize),
self.rust_name,
));
} else {
w.write_line(&format!(
"{}::rt::read_singular_message_into_field(is, &mut self.{})?;",
protobuf_crate_path(&self.customize),
self.rust_name,
));
}
}
_ => {
let read_proc = s.elem.read_one_liner();
Expand Down
6 changes: 6 additions & 0 deletions protobuf-parse/src/proto/rustproto.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ extend google.protobuf.FileOptions {
optional bool tokio_bytes_all = 17011;
// Use `bytes::Bytes` for `string` fields
optional bool tokio_bytes_for_string_all = 17012;
// Use `Option` for `message` fields.
optional bool option_for_message_all = 17013;

// When true, will only generate codes that works with lite runtime.
optional bool lite_runtime_all = 17035;
Expand All @@ -33,6 +35,8 @@ extend google.protobuf.MessageOptions {
optional bool tokio_bytes = 17011;
// Use `bytes::Bytes` for `string` fields
optional bool tokio_bytes_for_string = 17012;
// Use `Option` for `message` fields.
optional bool option_for_message = 17013;
}

extend google.protobuf.FieldOptions {
Expand All @@ -44,4 +48,6 @@ extend google.protobuf.FieldOptions {
optional bool tokio_bytes_field = 17011;
// Use `bytes::Bytes` for `string` fields
optional bool tokio_bytes_for_string_field = 17012;
// Use `Option` for `message` fields.
optional bool option_for_message_field = 17013;
}
14 changes: 14 additions & 0 deletions protobuf/src/rt/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ use crate::CodedOutputStream;
use crate::Message;
use crate::MessageField;

/// Read option `message` field.
pub fn read_option_message_into_field<M>(
is: &mut CodedInputStream,
target: &mut Option<M>,
) -> crate::Result<()>
where
M: Message,
{
let mut m = M::new();
is.merge_message(&mut m)?;
*target = Some(m);
Ok(())
}

/// Read singular `message` field.
pub fn read_singular_message_into_field<M>(
is: &mut CodedInputStream,
Expand Down
1 change: 1 addition & 0 deletions protobuf/src/rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub(crate) mod repeated;
pub(crate) mod singular;
pub(crate) mod unknown_or_group;

pub use message::read_option_message_into_field;
pub use message::read_singular_message_into_field;
pub use message::write_message_field_with_cached_size;
pub use packed::vec_packed_bool_size;
Expand Down
Loading