1 use std::fmt; 2 3 use file_descriptor::file_descriptor_proto_expr; 4 use inside::protobuf_crate_path; 5 use oneof::OneofGen; 6 use oneof::OneofVariantGen; 7 use protobuf::descriptor::*; 8 use rust_name::RustIdentWithPath; 9 use scope::MessageWithScope; 10 use scope::RootScope; 11 use scope::WithScope; 12 use serde; 13 14 use super::code_writer::*; 15 use super::customize::customize_from_rustproto_for_message; 16 use super::customize::Customize; 17 use super::enums::*; 18 use super::field::*; 19 use super::rust_types_values::*; 20 21 /// Protobuf message Rust type name 22 #[derive(Debug, Clone, PartialEq, Eq)] 23 pub(crate) struct RustTypeMessage(pub RustIdentWithPath); 24 25 impl fmt::Display for RustTypeMessage { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 27 fmt::Display::fmt(&self.0, f) 28 } 29 } 30 31 impl RustTypeMessage { 32 /// Code which emits default instance. default_instance(&self, customize: &Customize) -> String33 pub fn default_instance(&self, customize: &Customize) -> String { 34 format!( 35 "<{} as {}::Message>::default_instance()", 36 self.0, 37 protobuf_crate_path(customize) 38 ) 39 } 40 } 41 42 /// Message info for codegen 43 pub(crate) struct MessageGen<'a> { 44 pub message: &'a MessageWithScope<'a>, 45 pub root_scope: &'a RootScope<'a>, 46 type_name: RustIdentWithPath, 47 pub fields: Vec<FieldGen<'a>>, 48 pub lite_runtime: bool, 49 customize: Customize, 50 } 51 52 impl<'a> MessageGen<'a> { new( message: &'a MessageWithScope<'a>, root_scope: &'a RootScope<'a>, customize: &Customize, ) -> MessageGen<'a>53 pub fn new( 54 message: &'a MessageWithScope<'a>, 55 root_scope: &'a RootScope<'a>, 56 customize: &Customize, 57 ) -> MessageGen<'a> { 58 let mut customize = customize.clone(); 59 customize.update_with(&customize_from_rustproto_for_message( 60 message.message.get_options(), 61 )); 62 63 let fields: Vec<_> = message 64 .fields() 65 .into_iter() 66 .map(|field| FieldGen::parse(field, root_scope, &customize)) 67 .collect(); 68 let lite_runtime = customize.lite_runtime.unwrap_or_else(|| { 69 message 70 .get_file_descriptor() 71 .get_options() 72 .get_optimize_for() 73 == FileOptions_OptimizeMode::LITE_RUNTIME 74 }); 75 MessageGen { 76 message, 77 root_scope, 78 type_name: message.rust_name().into(), 79 fields, 80 lite_runtime, 81 customize, 82 } 83 } 84 expose_oneof(&self) -> bool85 fn expose_oneof(&self) -> bool { 86 self.customize.expose_oneof.unwrap_or(true) 87 } 88 oneofs(&'a self) -> Vec<OneofGen<'a>>89 fn oneofs(&'a self) -> Vec<OneofGen<'a>> { 90 self.message 91 .oneofs() 92 .into_iter() 93 .map(|oneof| OneofGen::parse(self, oneof, &self.customize)) 94 .collect() 95 } 96 required_fields(&'a self) -> Vec<&'a FieldGen>97 fn required_fields(&'a self) -> Vec<&'a FieldGen> { 98 self.fields 99 .iter() 100 .filter(|f| match f.kind { 101 FieldKind::Singular(ref singular) => singular.flag.is_required(), 102 _ => false, 103 }) 104 .collect() 105 } 106 message_fields(&'a self) -> Vec<&'a FieldGen>107 fn message_fields(&'a self) -> Vec<&'a FieldGen> { 108 self.fields 109 .iter() 110 .filter(|f| f.proto_type == FieldDescriptorProto_Type::TYPE_MESSAGE) 111 .collect() 112 } 113 fields_except_oneof(&'a self) -> Vec<&'a FieldGen>114 fn fields_except_oneof(&'a self) -> Vec<&'a FieldGen> { 115 self.fields.iter().filter(|f| !f.is_oneof()).collect() 116 } 117 fields_except_group(&'a self) -> Vec<&'a FieldGen>118 fn fields_except_group(&'a self) -> Vec<&'a FieldGen> { 119 self.fields 120 .iter() 121 .filter(|f| f.proto_type != FieldDescriptorProto_Type::TYPE_GROUP) 122 .collect() 123 } 124 fields_except_oneof_and_group(&'a self) -> Vec<&'a FieldGen>125 fn fields_except_oneof_and_group(&'a self) -> Vec<&'a FieldGen> { 126 self.fields 127 .iter() 128 .filter(|f| !f.is_oneof() && f.proto_type != FieldDescriptorProto_Type::TYPE_GROUP) 129 .collect() 130 } 131 write_match_each_oneof_variant<F>(&self, w: &mut CodeWriter, cb: F) where F: Fn(&mut CodeWriter, &OneofVariantGen, &str, &RustType),132 fn write_match_each_oneof_variant<F>(&self, w: &mut CodeWriter, cb: F) 133 where 134 F: Fn(&mut CodeWriter, &OneofVariantGen, &str, &RustType), 135 { 136 for oneof in self.oneofs() { 137 w.if_let_stmt( 138 "::std::option::Option::Some(ref v)", 139 &format!("self.{}", oneof.oneof.field_name())[..], 140 |w| { 141 w.match_block("v", |w| { 142 for variant in oneof.variants_except_group() { 143 let ref field = variant.field; 144 let (refv, vtype) = if !field.elem_type_is_copy() { 145 ("ref v", field.elem().rust_storage_type().ref_type()) 146 } else { 147 ("v", field.elem().rust_storage_type()) 148 }; 149 w.case_block(format!("&{}({})", variant.path(), refv), |w| { 150 cb(w, &variant, "v", &vtype); 151 }); 152 } 153 }); 154 }, 155 ); 156 } 157 } 158 write_write_to_with_cached_sizes(&self, w: &mut CodeWriter)159 fn write_write_to_with_cached_sizes(&self, w: &mut CodeWriter) { 160 let sig = format!( 161 "write_to_with_cached_sizes(&self, os: &mut {}::CodedOutputStream<'_>) -> {}::ProtobufResult<()>", 162 protobuf_crate_path(&self.customize), 163 protobuf_crate_path(&self.customize), 164 ); 165 w.def_fn(&sig, |w| { 166 // To have access to its methods but not polute the name space. 167 for f in self.fields_except_oneof_and_group() { 168 f.write_message_write_field(w); 169 } 170 self.write_match_each_oneof_variant(w, |w, variant, v, v_type| { 171 variant.field.write_write_element(w, "os", v, v_type); 172 }); 173 w.write_line("os.write_unknown_fields(self.get_unknown_fields())?;"); 174 w.write_line("::std::result::Result::Ok(())"); 175 }); 176 } 177 write_get_cached_size(&self, w: &mut CodeWriter)178 fn write_get_cached_size(&self, w: &mut CodeWriter) { 179 w.def_fn("get_cached_size(&self) -> u32", |w| { 180 w.write_line("self.cached_size.get()"); 181 }); 182 } 183 write_default_instance(&self, w: &mut CodeWriter)184 fn write_default_instance(&self, w: &mut CodeWriter) { 185 w.def_fn( 186 &format!("default_instance() -> &'static {}", self.type_name), 187 |w| { 188 w.lazy_static_decl_get_simple( 189 "instance", 190 &self.type_name.to_string(), 191 &format!("{}::new", self.type_name), 192 &self.customize, 193 ); 194 }, 195 ); 196 } 197 write_compute_size(&self, w: &mut CodeWriter)198 fn write_compute_size(&self, w: &mut CodeWriter) { 199 // Append sizes of messages in the tree to the specified vector. 200 // First appended element is size of self, and then nested message sizes. 201 // in serialization order are appended recursively."); 202 w.comment("Compute sizes of nested messages"); 203 // there are unused variables in oneof 204 w.allow(&["unused_variables"]); 205 w.def_fn("compute_size(&self) -> u32", |w| { 206 // To have access to its methods but not polute the name space. 207 w.write_line("let mut my_size = 0;"); 208 for field in self.fields_except_oneof_and_group() { 209 field.write_message_compute_field_size("my_size", w); 210 } 211 self.write_match_each_oneof_variant(w, |w, variant, v, vtype| { 212 variant.field.write_element_size(w, v, vtype, "my_size"); 213 }); 214 w.write_line(&format!( 215 "my_size += {}::rt::unknown_fields_size(self.get_unknown_fields());", 216 protobuf_crate_path(&self.customize) 217 )); 218 w.write_line("self.cached_size.set(my_size);"); 219 w.write_line("my_size"); 220 }); 221 } 222 write_field_accessors(&self, w: &mut CodeWriter)223 fn write_field_accessors(&self, w: &mut CodeWriter) { 224 for f in self.fields_except_group() { 225 w.write_line(""); 226 let reconstruct_def = f.reconstruct_def(); 227 w.comment(&(reconstruct_def + ";")); 228 w.write_line(""); 229 f.write_message_single_field_accessors(w); 230 } 231 } 232 write_impl_self(&self, w: &mut CodeWriter)233 fn write_impl_self(&self, w: &mut CodeWriter) { 234 w.impl_self_block(&self.type_name.to_string(), |w| { 235 // TODO: new should probably be a part of Message trait 236 w.pub_fn(&format!("new() -> {}", self.type_name), |w| { 237 w.write_line("::std::default::Default::default()"); 238 }); 239 240 self.write_field_accessors(w); 241 }); 242 } 243 write_unknown_fields(&self, w: &mut CodeWriter)244 fn write_unknown_fields(&self, w: &mut CodeWriter) { 245 w.def_fn( 246 &format!( 247 "get_unknown_fields(&self) -> &{}::UnknownFields", 248 protobuf_crate_path(&self.customize) 249 ), 250 |w| { 251 w.write_line("&self.unknown_fields"); 252 }, 253 ); 254 w.write_line(""); 255 w.def_fn( 256 &format!( 257 "mut_unknown_fields(&mut self) -> &mut {}::UnknownFields", 258 protobuf_crate_path(&self.customize) 259 ), 260 |w| { 261 w.write_line("&mut self.unknown_fields"); 262 }, 263 ); 264 } 265 write_merge_from(&self, w: &mut CodeWriter)266 fn write_merge_from(&self, w: &mut CodeWriter) { 267 let sig = format!( 268 "merge_from(&mut self, is: &mut {}::CodedInputStream<'_>) -> {}::ProtobufResult<()>", 269 protobuf_crate_path(&self.customize), 270 protobuf_crate_path(&self.customize), 271 ); 272 w.def_fn(&sig, |w| { 273 w.while_block("!is.eof()?", |w| { 274 w.write_line(&format!("let (field_number, wire_type) = is.read_tag_unpack()?;")); 275 w.match_block("field_number", |w| { 276 for f in &self.fields_except_group() { 277 let number = f.proto_field.number(); 278 w.case_block(number.to_string(), |w| { 279 f.write_merge_from_field("wire_type", w); 280 }); 281 } 282 w.case_block("_", |w| { 283 w.write_line(&format!("{}::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;", protobuf_crate_path(&self.customize))); 284 }); 285 }); 286 }); 287 w.write_line("::std::result::Result::Ok(())"); 288 }); 289 } 290 write_descriptor_field(&self, fields_var: &str, field: &FieldGen, w: &mut CodeWriter)291 fn write_descriptor_field(&self, fields_var: &str, field: &FieldGen, w: &mut CodeWriter) { 292 let accessor_fn = field.accessor_fn(); 293 w.write_line(&format!( 294 "{}.push({}::reflect::accessor::{}(", 295 fields_var, 296 protobuf_crate_path(&self.customize), 297 accessor_fn.sig() 298 )); 299 w.indented(|w| { 300 w.write_line(&format!("\"{}\",", field.proto_field.name())); 301 match accessor_fn.style { 302 AccessorStyle::Lambda => { 303 w.write_line(&format!( 304 "|m: &{}| {{ &m.{} }},", 305 self.type_name, field.rust_name 306 )); 307 w.write_line(&format!( 308 "|m: &mut {}| {{ &mut m.{} }},", 309 self.type_name, field.rust_name 310 )); 311 } 312 AccessorStyle::HasGet => { 313 w.write_line(&format!("{}::has_{},", self.type_name, field.rust_name)); 314 w.write_line(&format!("{}::get_{},", self.type_name, field.rust_name)); 315 } 316 } 317 }); 318 w.write_line("));"); 319 } 320 write_descriptor_static(&self, w: &mut CodeWriter)321 fn write_descriptor_static(&self, w: &mut CodeWriter) { 322 w.def_fn( 323 &format!( 324 "descriptor_static() -> &'static {}::reflect::MessageDescriptor", 325 protobuf_crate_path(&self.customize) 326 ), 327 |w| { 328 w.lazy_static_decl_get( 329 "descriptor", 330 &format!( 331 "{}::reflect::MessageDescriptor", 332 protobuf_crate_path(&self.customize) 333 ), 334 &self.customize, 335 |w| { 336 let fields = self.fields_except_group(); 337 if fields.is_empty() { 338 w.write_line(&format!("let fields = ::std::vec::Vec::new();")); 339 } else { 340 w.write_line(&format!("let mut fields = ::std::vec::Vec::new();")); 341 } 342 for field in fields { 343 self.write_descriptor_field("fields", field, w); 344 } 345 w.write_line(&format!( 346 "{}::reflect::MessageDescriptor::new_pb_name::<{}>(", 347 protobuf_crate_path(&self.customize), 348 self.type_name 349 )); 350 w.indented(|w| { 351 w.write_line(&format!("\"{}\",", self.message.name_to_package())); 352 w.write_line("fields,"); 353 w.write_line(&file_descriptor_proto_expr(&self.message.scope)); 354 }); 355 w.write_line(")"); 356 }, 357 ); 358 }, 359 ); 360 } 361 write_is_initialized(&self, w: &mut CodeWriter)362 fn write_is_initialized(&self, w: &mut CodeWriter) { 363 w.def_fn(&format!("is_initialized(&self) -> bool"), |w| { 364 // TODO: use single loop 365 366 for f in self.required_fields() { 367 f.write_if_self_field_is_none(w, |w| { 368 w.write_line("return false;"); 369 }); 370 } 371 372 for f in self.message_fields() { 373 if let FieldKind::Map(..) = f.kind { 374 // TODO: check values 375 continue; 376 } 377 378 // TODO: 379 // if message is declared in this file and has no message fields, 380 // we could skip the check here 381 f.write_for_self_field(w, "v", |w, _t| { 382 w.if_stmt("!v.is_initialized()", |w| { 383 w.write_line("return false;"); 384 }); 385 }); 386 } 387 w.write_line("true"); 388 }); 389 } 390 write_impl_message(&self, w: &mut CodeWriter)391 fn write_impl_message(&self, w: &mut CodeWriter) { 392 w.impl_for_block( 393 &format!("{}::Message", protobuf_crate_path(&self.customize)), 394 &self.type_name.to_string(), |w| { 395 self.write_is_initialized(w); 396 w.write_line(""); 397 self.write_merge_from(w); 398 w.write_line(""); 399 self.write_compute_size(w); 400 w.write_line(""); 401 self.write_write_to_with_cached_sizes(w); 402 w.write_line(""); 403 self.write_get_cached_size(w); 404 w.write_line(""); 405 self.write_unknown_fields(w); 406 w.write_line(""); 407 w.def_fn("as_any(&self) -> &dyn (::std::any::Any)", |w| { 408 w.write_line("self as &dyn (::std::any::Any)"); 409 }); 410 w.def_fn("as_any_mut(&mut self) -> &mut dyn (::std::any::Any)", |w| { 411 w.write_line("self as &mut dyn (::std::any::Any)"); 412 }); 413 w.def_fn( 414 "into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)>", 415 |w| { 416 w.write_line("self"); 417 }, 418 ); 419 w.write_line(""); 420 w.def_fn( 421 &format!("descriptor(&self) -> &'static {}::reflect::MessageDescriptor", protobuf_crate_path(&self.customize)), 422 |w| { 423 w.write_line("Self::descriptor_static()"); 424 }, 425 ); 426 w.write_line(""); 427 w.def_fn(&format!("new() -> {}", self.type_name), |w| { 428 w.write_line(&format!("{}::new()", self.type_name)); 429 }); 430 if !self.lite_runtime { 431 w.write_line(""); 432 self.write_descriptor_static(w); 433 } 434 w.write_line(""); 435 self.write_default_instance(w); 436 }); 437 } 438 write_impl_value(&self, w: &mut CodeWriter)439 fn write_impl_value(&self, w: &mut CodeWriter) { 440 w.impl_for_block( 441 &format!( 442 "{}::reflect::ProtobufValue", 443 protobuf_crate_path(&self.customize) 444 ), 445 &self.type_name.to_string(), 446 |w| { 447 w.def_fn( 448 &format!( 449 "as_ref(&self) -> {}::reflect::ReflectValueRef", 450 protobuf_crate_path(&self.customize) 451 ), 452 |w| { 453 w.write_line(&format!( 454 "{}::reflect::ReflectValueRef::Message(self)", 455 protobuf_crate_path(&self.customize) 456 )) 457 }, 458 ) 459 }, 460 ) 461 } 462 write_impl_show(&self, w: &mut CodeWriter)463 fn write_impl_show(&self, w: &mut CodeWriter) { 464 w.impl_for_block("::std::fmt::Debug", &self.type_name.to_string(), |w| { 465 w.def_fn( 466 "fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result", 467 |w| { 468 w.write_line(&format!( 469 "{}::text_format::fmt(self, f)", 470 protobuf_crate_path(&self.customize) 471 )); 472 }, 473 ); 474 }); 475 } 476 write_impl_clear(&self, w: &mut CodeWriter)477 fn write_impl_clear(&self, w: &mut CodeWriter) { 478 w.impl_for_block( 479 &format!("{}::Clear", protobuf_crate_path(&self.customize)), 480 &format!("{}", self.type_name), 481 |w| { 482 w.def_fn("clear(&mut self)", |w| { 483 for f in self.fields_except_group() { 484 f.write_clear(w); 485 } 486 w.write_line("self.unknown_fields.clear();"); 487 }); 488 }, 489 ); 490 } 491 492 #[allow(dead_code)] supports_derive_partial_eq(&self) -> bool493 fn supports_derive_partial_eq(&self) -> bool { 494 // There's stack overflow in the compiler when struct has too many fields 495 // https://github.com/rust-lang/rust/issues/40119 496 self.fields.len() <= 500 497 } 498 write_struct(&self, w: &mut CodeWriter)499 fn write_struct(&self, w: &mut CodeWriter) { 500 let mut derive = vec!["PartialEq", "Clone", "Default"]; 501 if self.lite_runtime { 502 derive.push("Debug"); 503 } 504 w.derive(&derive); 505 serde::write_serde_attr( 506 w, 507 &self.customize, 508 "derive(::serde::Serialize, ::serde::Deserialize)", 509 ); 510 w.pub_struct(&self.type_name.to_string(), |w| { 511 if !self.fields_except_oneof().is_empty() { 512 w.comment("message fields"); 513 for field in self.fields_except_oneof() { 514 if field.proto_type == FieldDescriptorProto_Type::TYPE_GROUP { 515 w.comment(&format!("{}: <group>", &field.rust_name)); 516 } else { 517 let vis = if field.expose_field { 518 Visibility::Public 519 } else { 520 match field.kind { 521 FieldKind::Repeated(..) => Visibility::Default, 522 FieldKind::Singular(SingularField { ref flag, .. }) => { 523 match *flag { 524 SingularFieldFlag::WithFlag { .. } => Visibility::Default, 525 SingularFieldFlag::WithoutFlag => Visibility::Public, 526 } 527 } 528 FieldKind::Map(..) => Visibility::Public, 529 FieldKind::Oneof(..) => unreachable!(), 530 } 531 }; 532 w.field_decl_vis( 533 vis, 534 &field.rust_name.get(), 535 &field.full_storage_type().to_code(&self.customize), 536 ); 537 } 538 } 539 } 540 if !self.oneofs().is_empty() { 541 w.comment("message oneof groups"); 542 for oneof in self.oneofs() { 543 let vis = match self.expose_oneof() { 544 true => Visibility::Public, 545 false => Visibility::Default, 546 }; 547 w.field_decl_vis( 548 vis, 549 oneof.oneof.field_name().get(), 550 &oneof.full_storage_type().to_code(&self.customize), 551 ); 552 } 553 } 554 w.comment("special fields"); 555 serde::write_serde_attr(w, &self.customize, "serde(skip)"); 556 w.pub_field_decl( 557 "unknown_fields", 558 &format!("{}::UnknownFields", protobuf_crate_path(&self.customize)), 559 ); 560 serde::write_serde_attr(w, &self.customize, "serde(skip)"); 561 w.pub_field_decl( 562 "cached_size", 563 &format!("{}::CachedSize", protobuf_crate_path(&self.customize)), 564 ); 565 }); 566 } 567 write_impl_default_for_amp(&self, w: &mut CodeWriter)568 fn write_impl_default_for_amp(&self, w: &mut CodeWriter) { 569 w.impl_args_for_block( 570 &["'a"], 571 "::std::default::Default", 572 &format!("&'a {}", self.type_name), 573 |w| { 574 w.def_fn(&format!("default() -> &'a {}", self.type_name), |w| { 575 w.write_line(&format!( 576 "<{} as {}::Message>::default_instance()", 577 self.type_name, 578 protobuf_crate_path(&self.customize), 579 )); 580 }); 581 }, 582 ); 583 } 584 write(&self, w: &mut CodeWriter)585 pub fn write(&self, w: &mut CodeWriter) { 586 self.write_struct(w); 587 588 w.write_line(""); 589 self.write_impl_default_for_amp(w); 590 591 for oneof in self.oneofs() { 592 w.write_line(""); 593 oneof.write_enum(w); 594 } 595 596 w.write_line(""); 597 self.write_impl_self(w); 598 w.write_line(""); 599 self.write_impl_message(w); 600 w.write_line(""); 601 self.write_impl_clear(w); 602 if !self.lite_runtime { 603 w.write_line(""); 604 self.write_impl_show(w); 605 } 606 w.write_line(""); 607 self.write_impl_value(w); 608 609 let mut nested_prefix = self.type_name.to_string(); 610 nested_prefix.push_str("_"); 611 612 for nested in &self.message.to_scope().get_messages() { 613 // ignore map entries, because they are not used in map fields 614 if nested.map_entry().is_none() { 615 w.write_line(""); 616 MessageGen::new(nested, self.root_scope, &self.customize).write(w); 617 } 618 } 619 620 for enum_type in &self.message.to_scope().get_enums() { 621 w.write_line(""); 622 let current_file = self.message.get_scope().get_file_descriptor(); 623 EnumGen::new(enum_type, current_file, &self.customize, self.root_scope).write(w); 624 } 625 } 626 } 627