1use protobuf::descriptor::*;
2use protobuf::descriptorx::*;
3
4use super::enums::*;
5use super::rust_types_values::*;
6use super::field::*;
7use super::code_writer::*;
8use super::customize::Customize;
9use super::customize::customize_from_rustproto_for_message;
10use oneof::OneofGen;
11use oneof::OneofVariantGen;
12
13
14pub struct MessageGen<'a> {
16 message: &'a MessageWithScope<'a>,
17 root_scope: &'a RootScope<'a>,
18 type_name: String,
19 pub fields: Vec<FieldGen<'a>>,
20 pub lite_runtime: bool,
21 customize: Customize,
22}
23
24impl<'a> MessageGen<'a> {
25 pub fn new(
26 message: &'a MessageWithScope<'a>,
27 root_scope: &'a RootScope<'a>,
28 customize: &Customize)
29 -> MessageGen<'a>
30 {
31 let mut customize = customize.clone();
32 customize.update_with(&customize_from_rustproto_for_message(message.message.get_options()));
33
34 let fields: Vec<_> = message
35 .fields()
36 .into_iter()
37 .map(|field| FieldGen::parse(field, root_scope, &customize))
38 .collect();
39 MessageGen {
40 message: message,
41 root_scope: root_scope,
42 type_name: message.rust_name(),
43 fields: fields,
44 lite_runtime: message
45 .get_file_descriptor()
46 .get_options()
47 .get_optimize_for() ==
48 FileOptions_OptimizeMode::LITE_RUNTIME,
49 customize,
50 }
51 }
52
53 fn expose_oneof(&self) -> bool {
54 self.customize.expose_oneof.unwrap_or(true)
55 }
56
57 fn oneofs(&'a self) -> Vec<OneofGen<'a>> {
58 self.message
59 .oneofs()
60 .into_iter()
61 .map(|oneof| OneofGen::parse(self, oneof, &self.customize))
62 .collect()
63 }
64
65 fn required_fields(&'a self) -> Vec<&'a FieldGen> {
66 self.fields
67 .iter()
68 .filter(|f| match f.kind {
69 FieldKind::Singular(ref singular) => singular.flag.is_required(),
70 _ => false,
71 })
72 .collect()
73 }
74
75 fn message_fields(&'a self) -> Vec<&'a FieldGen> {
76 self.fields
77 .iter()
78 .filter(|f| f.proto_type == FieldDescriptorProto_Type::TYPE_MESSAGE)
79 .collect()
80 }
81
82 fn fields_except_oneof(&'a self) -> Vec<&'a FieldGen> {
83 self.fields
84 .iter()
85 .filter(|f| !f.is_oneof())
86 .collect()
87 }
88
89 fn fields_except_group(&'a self) -> Vec<&'a FieldGen> {
90 self.fields
91 .iter()
92 .filter(|f| f.proto_type != FieldDescriptorProto_Type::TYPE_GROUP)
93 .collect()
94 }
95
96 fn fields_except_oneof_and_group(&'a self) -> Vec<&'a FieldGen> {
97 self.fields
98 .iter()
99 .filter(|f| {
100 !f.is_oneof() && f.proto_type != FieldDescriptorProto_Type::TYPE_GROUP
101 })
102 .collect()
103 }
104
105
106 fn write_match_each_oneof_variant<F>(&self, w: &mut CodeWriter, cb: F)
107 where
108 F : Fn(&mut CodeWriter, &OneofVariantGen, &str, &RustType),
109 {
110 for oneof in self.oneofs() {
111 w.if_let_stmt("::std::option::Option::Some(ref v)", &format!("self.{}", oneof.name())[..], |w| {
112 w.match_block("v", |w| {
113 for variant in oneof.variants_except_group() {
114 let ref field = variant.field;
115 let (refv, vtype) =
116 if !field.elem_type_is_copy() {
117 ("ref v", field.elem().rust_storage_type().ref_type())
118 } else {
119 ("v", field.elem().rust_storage_type())
120 };
121 w.case_block(format!("&{}({})", variant.path(), refv), |w| {
122 cb(w, &variant, "v", &vtype);
123 });
124 }
125 });
126 });
127 }
128 }
129
130 fn write_write_to_with_cached_sizes(&self, w: &mut CodeWriter) {
131 w.def_fn("write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()>", |w| {
132 for f in self.fields_except_oneof_and_group() {
134 f.write_message_write_field(w);
135 }
136 self.write_match_each_oneof_variant(w, |w, variant, v, v_type| {
137 variant.field.write_write_element(w, "os", v, v_type);
138 });
139 w.write_line("os.write_unknown_fields(self.get_unknown_fields())?;");
140 w.write_line("::std::result::Result::Ok(())");
141 });
142 }
143
144 fn write_get_cached_size(&self, w: &mut CodeWriter) {
145 w.def_fn("get_cached_size(&self) -> u32", |w| {
146 w.write_line("self.cached_size.get()");
147 });
148 }
149
150 fn write_default_instance(&self, w: &mut CodeWriter) {
151 w.def_fn(&format!("default_instance() -> &'static {}", self.type_name), |w| {
152 w.lazy_static_decl_get_simple(
153 "instance",
154 &self.type_name,
155 &format!("{}::new", self.type_name));
156 });
157 }
158
159 fn write_compute_size(&self, w: &mut CodeWriter) {
160 w.comment("Compute sizes of nested messages");
164 w.allow(&["unused_variables"]);
166 w.def_fn("compute_size(&self) -> u32", |w| {
167 w.write_line("let mut my_size = 0;");
169 for field in self.fields_except_oneof_and_group() {
170 field.write_message_compute_field_size("my_size", w);
171 }
172 self.write_match_each_oneof_variant(w, |w, variant, v, vtype| {
173 variant.field.write_element_size(w, v, vtype, "my_size");
174 });
175 w.write_line(
176 "my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());",
177 );
178 w.write_line("self.cached_size.set(my_size);");
179 w.write_line("my_size");
180 });
181 }
182
183 fn write_field_accessors(&self, w: &mut CodeWriter) {
184 for f in self.fields_except_group() {
185 w.write_line("");
186 let reconstruct_def = f.reconstruct_def();
187 w.comment(&(reconstruct_def + ";"));
188 w.write_line("");
189 f.write_message_single_field_accessors(w);
190 }
191 }
192
193 fn write_impl_self(&self, w: &mut CodeWriter) {
194 w.impl_self_block(&self.type_name, |w| {
195 w.pub_fn(&format!("new() -> {}", self.type_name), |w| {
197 w.write_line("::std::default::Default::default()");
198 });
199
200 self.write_field_accessors(w);
201 });
202 }
203
204 fn write_unknown_fields(&self, w: &mut CodeWriter) {
205 w.def_fn(
206 "get_unknown_fields(&self) -> &::protobuf::UnknownFields",
207 |w| { w.write_line("&self.unknown_fields"); },
208 );
209 w.write_line("");
210 w.def_fn("mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields", |w| {
211 w.write_line("&mut self.unknown_fields");
212 });
213 }
214
215 fn write_merge_from(&self, w: &mut CodeWriter) {
216 w.def_fn(&format!("merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()>"), |w| {
217 w.while_block("!is.eof()?", |w| {
218 w.write_line(&format!("let (field_number, wire_type) = is.read_tag_unpack()?;"));
219 w.match_block("field_number", |w| {
220 for f in &self.fields_except_group() {
221 let number = f.proto_field.number();
222 w.case_block(number.to_string(), |w| {
223 f.write_merge_from_field("wire_type", w);
224 });
225 }
226 w.case_block("_", |w| {
227 w.write_line("::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;");
228 });
229 });
230 });
231 w.write_line("::std::result::Result::Ok(())");
232 });
233 }
234
235 fn write_descriptor_field(&self, fields_var: &str, field: &FieldGen, w: &mut CodeWriter) {
236 let accessor_fn = field.accessor_fn();
237 w.write_line(&format!(
238 "{}.push(::protobuf::reflect::accessor::{}(",
239 fields_var,
240 accessor_fn.sig()
241 ));
242 w.indented(|w| {
243 w.write_line(&format!("\"{}\",", field.proto_field.name()));
244 match accessor_fn.style {
245 AccessorStyle::Lambda => {
246 w.write_line(&format!("|m: &{}| {{ &m.{} }},", self.type_name, field.rust_name));
247 w.write_line(&format!("|m: &mut {}| {{ &mut m.{} }},", self.type_name, field.rust_name));
248 }
249 AccessorStyle::HasGet => {
250 w.write_line(&format!("{}::has_{},", self.type_name, field.rust_name));
251 w.write_line(&format!("{}::get_{},", self.type_name, field.rust_name));
252 }
253 }
254 });
255 w.write_line("));");
256 }
257
258 fn write_descriptor_static(&self, w: &mut CodeWriter) {
259 w.def_fn(&format!("descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor"), |w| {
260 w.lazy_static_decl_get("descriptor", "::protobuf::reflect::MessageDescriptor", |w| {
261 let fields = self.fields_except_group();
262 if fields.is_empty() {
263 w.write_line(&format!("let fields = ::std::vec::Vec::new();"));
264 } else {
265 w.write_line(&format!("let mut fields = ::std::vec::Vec::new();"));
266 }
267 for field in fields {
268 self.write_descriptor_field("fields", field, w);;
269 }
270 w.write_line(&format!(
271 "::protobuf::reflect::MessageDescriptor::new::<{}>(", self.type_name));
272 w.indented(|w| {
273 w.write_line(&format!("\"{}\",", self.type_name));
274 w.write_line("fields,");
275 w.write_line("file_descriptor_proto()");
276 });
277 w.write_line(")");
278 });
279 });
280 }
281
282 fn write_is_initialized(&self, w: &mut CodeWriter) {
283 w.def_fn(&format!("is_initialized(&self) -> bool"), |w| {
284 for f in self.required_fields() {
287 f.write_if_self_field_is_none(w, |w| { w.write_line("return false;"); });
288 }
289
290 for f in self.message_fields() {
291 if let FieldKind::Map(..) = f.kind {
292 continue;
294 }
295
296 f.write_for_self_field(w, "v", |w, _t| {
300 w.if_stmt(
301 "!v.is_initialized()",
302 |w| { w.write_line("return false;"); },
303 );
304 });
305 }
306 w.write_line("true");
307 });
308 }
309
310 fn write_impl_message(&self, w: &mut CodeWriter) {
311 w.impl_for_block("::protobuf::Message", &self.type_name, |w| {
312 self.write_is_initialized(w);
313 w.write_line("");
314 self.write_merge_from(w);
315 w.write_line("");
316 self.write_compute_size(w);
317 w.write_line("");
318 self.write_write_to_with_cached_sizes(w);
319 w.write_line("");
320 self.write_get_cached_size(w);
321 w.write_line("");
322 self.write_unknown_fields(w);
323 w.write_line("");
324 w.def_fn("as_any(&self) -> &::std::any::Any", |w| {
325 w.write_line("self as &::std::any::Any");
326 });
327 w.def_fn("as_any_mut(&mut self) -> &mut ::std::any::Any", |w| {
328 w.write_line("self as &mut ::std::any::Any");
329 });
330 w.def_fn("into_any(self: Box<Self>) -> ::std::boxed::Box<::std::any::Any>", |w| {
331 w.write_line("self");
332 });
333 w.write_line("");
334 w.def_fn("descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor", |w| {
335 w.write_line("Self::descriptor_static()");
336 });
337 w.write_line("");
338 w.def_fn(&format!("new() -> {}", self.type_name), |w| {
339 w.write_line(&format!("{}::new()", self.type_name));
340 });
341 if !self.lite_runtime {
342 w.write_line("");
343 self.write_descriptor_static(w);
344 }
345 w.write_line("");
346 self.write_default_instance(w);
347 });
348 }
349
350 fn write_impl_value(&self, w: &mut CodeWriter) {
351 w.impl_for_block("::protobuf::reflect::ProtobufValue", &self.type_name, |w| {
352 w.def_fn(
353 "as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef",
354 |w| w.write_line("::protobuf::reflect::ProtobufValueRef::Message(self)"),
355 )
356 })
357 }
358
359 fn write_impl_show(&self, w: &mut CodeWriter) {
360 w.impl_for_block("::std::fmt::Debug", &self.type_name, |w| {
361 w.def_fn("fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result", |w| {
362 w.write_line("::protobuf::text_format::fmt(self, f)");
363 });
364 });
365 }
366
367 fn write_impl_clear(&self, w: &mut CodeWriter) {
368 w.impl_for_block("::protobuf::Clear", &self.type_name, |w| {
369 w.def_fn("clear(&mut self)", |w| {
370 for f in self.fields_except_group() {
372 let clear_field_func = f.clear_field_func();
373 w.write_line(&format!("self.{}();", clear_field_func));
374 }
375 w.write_line("self.unknown_fields.clear();");
376 });
377 });
378 }
379
380 fn write_struct(&self, w: &mut CodeWriter) {
381 let mut derive = vec!["PartialEq", "Clone", "Default"];
382 if self.lite_runtime {
383 derive.push("Debug");
384 }
385 w.derive(&derive);
386 w.pub_struct(&self.type_name, |w| {
387 if !self.fields_except_oneof().is_empty() {
388 w.comment("message fields");
389 for field in self.fields_except_oneof() {
390 if field.proto_type == FieldDescriptorProto_Type::TYPE_GROUP {
391 w.comment(&format!("{}: <group>", &field.rust_name));
392 } else {
393 let vis = if field.expose_field {
394 Visibility::Public
395 } else {
396 match field.kind {
397 FieldKind::Repeated(..) => Visibility::Default,
398 FieldKind::Singular(SingularField { ref flag, .. }) => {
399 match *flag {
400 SingularFieldFlag::WithFlag { .. } => Visibility::Default,
401 SingularFieldFlag::WithoutFlag => Visibility::Public,
402 }
403 }
404 FieldKind::Map(..) => Visibility::Public,
405 FieldKind::Oneof(..) => unreachable!(),
406 }
407 };
408 w.field_decl_vis(
409 vis,
410 &field.rust_name,
411 &field.full_storage_type().to_string(),
412 );
413 }
414 }
415 }
416 if !self.oneofs().is_empty() {
417 w.comment("message oneof groups");
418 for oneof in self.oneofs() {
419 let vis = match self.expose_oneof() {
420 true => Visibility::Public,
421 false => Visibility::Default,
422 };
423 w.field_decl_vis(vis, oneof.name(), &oneof.full_storage_type().to_string());
424 }
425 }
426 w.comment("special fields");
427 w.field_decl("unknown_fields", "::protobuf::UnknownFields");
429 w.field_decl("cached_size", "::protobuf::CachedSize");
430 });
431 }
432
433 pub fn write(&self, w: &mut CodeWriter) {
434 self.write_struct(w);
435
436 for oneof in self.oneofs() {
437 w.write_line("");
438 oneof.write_enum(w);
439 }
440
441 w.write_line("");
442 self.write_impl_self(w);
443 w.write_line("");
444 self.write_impl_message(w);
445 w.write_line("");
446 self.write_impl_clear(w);
447 if !self.lite_runtime {
448 w.write_line("");
449 self.write_impl_show(w);
450 }
451 w.write_line("");
452 self.write_impl_value(w);
453
454 let mut nested_prefix = self.type_name.to_string();
455 nested_prefix.push_str("_");
456
457 for nested in &self.message.to_scope().get_messages() {
458 if nested.map_entry().is_none() {
460 w.write_line("");
461 MessageGen::new(nested, self.root_scope, &self.customize).write(w);
462 }
463 }
464
465 for enum_type in &self.message.to_scope().get_enums() {
466 w.write_line("");
467 let current_file = self.message.get_scope().get_file_descriptor();
468 EnumGen::new(enum_type, current_file, &self.customize).write(w);
469 }
470 }
471}