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