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 lite-runtime customization options #399

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions proto/rustproto.proto
Expand Up @@ -35,6 +35,9 @@ extend google.protobuf.FileOptions {
optional bool serde_derive_all = 17030;
// Guard serde annotations with cfg attr.
optional string serde_derive_cfg_all = 17031;

// When true, will only generate codes that works with lite runtime.
optional bool lite_runtime_all = 17035;
}

extend google.protobuf.MessageOptions {
Expand Down
13 changes: 13 additions & 0 deletions protobuf-codegen/src/customize.rs
Expand Up @@ -31,6 +31,8 @@ pub struct Customize {
pub serde_derive: Option<bool>,
/// When `serde_derive` is set, serde annotations will be guarded with `#[cfg(cfg, ...)]`.
pub serde_derive_cfg: Option<String>,
/// Enable lite runtime
pub lite_runtime: Option<bool>,

// When adding more options please keep in sync with `parse_from_parameter` below.
/// Make sure `Customize` is always used with `..Default::default()`
Expand Down Expand Up @@ -83,6 +85,9 @@ impl Customize {
if let Some(ref v) = that.serde_derive_cfg {
self.serde_derive_cfg = Some(v.clone());
}
if let Some(v) = that.lite_runtime {
self.lite_runtime = Some(v);
}
}

/// Update unset fields of self with fields from other customize
Expand Down Expand Up @@ -131,6 +136,8 @@ impl Customize {
r.serde_derive = Some(parse_bool(v)?);
} else if n == "serde_derive_cfg" {
r.serde_derive_cfg = Some(v.to_owned());
} else if n == "lite_runtime" {
r.lite_runtime = Some(parse_bool(v)?);
} else {
return Err(CustomizeParseParameterError::UnknownOptionName(
n.to_owned(),
Expand All @@ -153,6 +160,7 @@ pub fn customize_from_rustproto_for_message(source: &MessageOptions) -> Customiz
let singular_field_option = rustproto::exts::singular_field_option.get(source);
let serde_derive = rustproto::exts::serde_derive.get(source);
let serde_derive_cfg = rustproto::exts::serde_derive_cfg.get(source);
let lite_runtime = None;
Customize {
expose_oneof,
expose_fields,
Expand All @@ -165,6 +173,7 @@ pub fn customize_from_rustproto_for_message(source: &MessageOptions) -> Customiz
singular_field_option,
serde_derive,
serde_derive_cfg,
lite_runtime,
_future_options: (),
}
}
Expand All @@ -182,6 +191,7 @@ pub fn customize_from_rustproto_for_field(source: &FieldOptions) -> Customize {
let singular_field_option = rustproto::exts::singular_field_option_field.get(source);
let serde_derive = None;
let serde_derive_cfg = None;
let lite_runtime = None;
Customize {
expose_oneof,
expose_fields,
Expand All @@ -194,6 +204,7 @@ pub fn customize_from_rustproto_for_field(source: &FieldOptions) -> Customize {
singular_field_option,
serde_derive,
serde_derive_cfg,
lite_runtime,
_future_options: (),
}
}
Expand All @@ -210,6 +221,7 @@ pub fn customize_from_rustproto_for_file(source: &FileOptions) -> Customize {
let singular_field_option = rustproto::exts::singular_field_option_all.get(source);
let serde_derive = rustproto::exts::serde_derive_all.get(source);
let serde_derive_cfg = rustproto::exts::serde_derive_cfg_all.get(source);
let lite_runtime = rustproto::exts::lite_runtime_all.get(source);
Customize {
expose_oneof,
expose_fields,
Expand All @@ -222,6 +234,7 @@ pub fn customize_from_rustproto_for_file(source: &FileOptions) -> Customize {
singular_field_option,
serde_derive,
serde_derive_cfg,
lite_runtime,
_future_options: (),
}
}
13 changes: 8 additions & 5 deletions protobuf-codegen/src/enums.rs
Expand Up @@ -70,16 +70,19 @@ impl<'a> EnumGen<'a> {
root_scope,
)
};
EnumGen {
enum_with_scope,
type_name: rust_name,
lite_runtime: enum_with_scope
let lite_runtime = customize.lite_runtime.unwrap_or_else(|| {
enum_with_scope
.get_scope()
.get_file_descriptor()
.options
.get_message()
.get_optimize_for()
== FileOptions_OptimizeMode::LITE_RUNTIME,
== FileOptions_OptimizeMode::LITE_RUNTIME
});
EnumGen {
enum_with_scope,
type_name: rust_name,
lite_runtime,
customize: customize.clone(),
}
}
Expand Down
10 changes: 8 additions & 2 deletions protobuf-codegen/src/lib.rs
Expand Up @@ -128,6 +128,13 @@ fn gen_file(
let scope = FileScope {
file_descriptor: file,
}.to_scope();
let lite_runtime = customize.lite_runtime.unwrap_or_else(|| {
file
.options
.get_message()
.get_optimize_for()
== FileOptions_OptimizeMode::LITE_RUNTIME
});

let mut v = Vec::new();

Expand All @@ -150,8 +157,7 @@ fn gen_file(

write_extensions(file, &root_scope, &mut w);

let optimize_mode = file.options.get_message().get_optimize_for();
if optimize_mode != FileOptions_OptimizeMode::LITE_RUNTIME {
if !lite_runtime {
w.write_line("");
write_file_descriptor_data(file, &mut w);
}
Expand Down
36 changes: 24 additions & 12 deletions protobuf-codegen/src/message.rs
Expand Up @@ -40,17 +40,20 @@ impl<'a> MessageGen<'a> {
.into_iter()
.map(|field| FieldGen::parse(field, root_scope, &customize))
.collect();
let lite_runtime = customize.lite_runtime.unwrap_or_else(|| {
message
.get_file_descriptor()
.options
.get_message()
.get_optimize_for()
== FileOptions_OptimizeMode::LITE_RUNTIME
});
MessageGen {
message: message,
root_scope: root_scope,
type_name: message.rust_name(),
fields: fields,
lite_runtime: message
.get_file_descriptor()
.options
.get_message()
.get_optimize_for()
== FileOptions_OptimizeMode::LITE_RUNTIME,
lite_runtime,
customize,
}
}
Expand All @@ -73,7 +76,8 @@ impl<'a> MessageGen<'a> {
.filter(|f| match f.kind {
FieldKind::Singular(ref singular) => singular.flag.is_required(),
_ => false,
}).collect()
})
.collect()
}

fn message_fields(&'a self) -> Vec<&'a FieldGen> {
Expand Down Expand Up @@ -415,11 +419,19 @@ impl<'a> MessageGen<'a> {
}

fn write_impl_default_for_amp(&self, w: &mut CodeWriter) {
w.impl_args_for_block(&["'a"], "::std::default::Default", &format!("&'a {}", self.type_name), |w| {
w.def_fn(&format!("default() -> &'a {}", self.type_name), |w| {
w.write_line(&format!("<{} as ::protobuf::Message>::default_instance()", self.type_name));
});
});
w.impl_args_for_block(
&["'a"],
"::std::default::Default",
&format!("&'a {}", self.type_name),
|w| {
w.def_fn(&format!("default() -> &'a {}", self.type_name), |w| {
w.write_line(&format!(
"<{} as ::protobuf::Message>::default_instance()",
self.type_name
));
});
},
);
}

fn write_dummy_impl_partial_eq(&self, w: &mut CodeWriter) {
Expand Down
13 changes: 13 additions & 0 deletions protobuf-test/src/common/v2/test_enable_lite_runtime.rs
@@ -0,0 +1,13 @@
use protobuf_test_common::*;

use super::test_enable_lite_runtime_pb::*;

#[test]
fn test_lite_runtime() {
let mut m = TestLiteRuntime::new();
m.set_v(10);
test_serialize_deserialize("08 0a", &m);

// test it doesn't crash
format!("{:?}", m);
}
18 changes: 18 additions & 0 deletions protobuf-test/src/common/v2/test_enable_lite_runtime_pb.proto
@@ -0,0 +1,18 @@
syntax = "proto2";

import "rustproto.proto";
option (rustproto.generate_accessors_all) = true;
option (rustproto.lite_runtime_all) = true;


package test_enable_lite_runtime;

enum EnumTestLiteRuntime {
UNKNOWN = 0;
ONE = 1;
TWO = 2;
}

message TestLiteRuntime {
optional int32 v = 1;
}