Chih-Hung Hsieh | 92ff605 | 2020-06-10 20:18:39 -0700 | [diff] [blame] | 1 | use super::code_writer::CodeWriter; |
| 2 | use super::rust_types_values::*; |
| 3 | use field::rust_field_name_for_protobuf_field_name; |
Haibo Huang | ba676d3 | 2020-08-12 13:52:13 -0700 | [diff] [blame] | 4 | use inside::protobuf_crate_path; |
Chih-Hung Hsieh | 92ff605 | 2020-06-10 20:18:39 -0700 | [diff] [blame] | 5 | use protobuf::descriptor::*; |
| 6 | use protobuf_name::ProtobufAbsolutePath; |
| 7 | use scope::RootScope; |
| 8 | use Customize; |
| 9 | |
| 10 | struct ExtGen<'a> { |
| 11 | file: &'a FileDescriptorProto, |
| 12 | root_scope: &'a RootScope<'a>, |
| 13 | field: &'a FieldDescriptorProto, |
| 14 | customize: Customize, |
| 15 | } |
| 16 | |
| 17 | impl<'a> ExtGen<'a> { |
| 18 | fn extendee_rust_name(&self) -> String { |
| 19 | type_name_to_rust_relative( |
| 20 | &ProtobufAbsolutePath::from(self.field.get_extendee()), |
| 21 | self.file, |
| 22 | true, |
| 23 | self.root_scope, |
Haibo Huang | ba676d3 | 2020-08-12 13:52:13 -0700 | [diff] [blame] | 24 | &self.customize, |
Chih-Hung Hsieh | 92ff605 | 2020-06-10 20:18:39 -0700 | [diff] [blame] | 25 | ) |
| 26 | } |
| 27 | |
| 28 | fn repeated(&self) -> bool { |
| 29 | match self.field.get_label() { |
| 30 | FieldDescriptorProto_Label::LABEL_REPEATED => true, |
| 31 | FieldDescriptorProto_Label::LABEL_OPTIONAL => false, |
| 32 | FieldDescriptorProto_Label::LABEL_REQUIRED => { |
| 33 | panic!("required ext field: {}", self.field.get_name()) |
| 34 | } |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | fn return_type_gen(&self) -> ProtobufTypeGen { |
| 39 | if self.field.has_type_name() { |
| 40 | let rust_name_relative = type_name_to_rust_relative( |
| 41 | &ProtobufAbsolutePath::from(self.field.get_type_name()), |
| 42 | self.file, |
| 43 | true, |
| 44 | self.root_scope, |
Haibo Huang | ba676d3 | 2020-08-12 13:52:13 -0700 | [diff] [blame] | 45 | &self.customize, |
Chih-Hung Hsieh | 92ff605 | 2020-06-10 20:18:39 -0700 | [diff] [blame] | 46 | ); |
| 47 | match self.field.get_field_type() { |
| 48 | FieldDescriptorProto_Type::TYPE_MESSAGE => { |
| 49 | ProtobufTypeGen::Message(rust_name_relative) |
| 50 | } |
| 51 | FieldDescriptorProto_Type::TYPE_ENUM => ProtobufTypeGen::Enum(rust_name_relative), |
| 52 | t => panic!("unknown type: {:?}", t), |
| 53 | } |
| 54 | } else { |
| 55 | ProtobufTypeGen::Primitive(self.field.get_field_type(), PrimitiveTypeVariant::Default) |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | fn write(&self, w: &mut CodeWriter) { |
| 60 | let suffix = if self.repeated() { |
| 61 | "Repeated" |
| 62 | } else { |
| 63 | "Optional" |
| 64 | }; |
Haibo Huang | ba676d3 | 2020-08-12 13:52:13 -0700 | [diff] [blame] | 65 | let field_type = format!( |
| 66 | "{}::ext::ExtField{}", |
| 67 | protobuf_crate_path(&self.customize), |
| 68 | suffix |
| 69 | ); |
Chih-Hung Hsieh | 92ff605 | 2020-06-10 20:18:39 -0700 | [diff] [blame] | 70 | w.pub_const( |
| 71 | rust_field_name_for_protobuf_field_name(self.field.get_name()).get(), |
| 72 | &format!( |
| 73 | "{}<{}, {}>", |
| 74 | field_type, |
| 75 | self.extendee_rust_name(), |
| 76 | self.return_type_gen().rust_type(&self.customize), |
| 77 | ), |
| 78 | &format!( |
| 79 | "{} {{ field_number: {}, phantom: ::std::marker::PhantomData }}", |
| 80 | field_type, |
| 81 | self.field.get_number() |
| 82 | ), |
| 83 | ); |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | pub(crate) fn write_extensions( |
| 88 | file: &FileDescriptorProto, |
| 89 | root_scope: &RootScope, |
| 90 | w: &mut CodeWriter, |
| 91 | customize: &Customize, |
| 92 | ) { |
| 93 | if file.get_extension().is_empty() { |
| 94 | return; |
| 95 | } |
| 96 | |
| 97 | w.write_line(""); |
Haibo Huang | 72fec01 | 2020-07-10 20:24:04 -0700 | [diff] [blame] | 98 | w.write_line("/// Extension fields"); |
Chih-Hung Hsieh | 92ff605 | 2020-06-10 20:18:39 -0700 | [diff] [blame] | 99 | w.pub_mod("exts", |w| { |
Chih-Hung Hsieh | 92ff605 | 2020-06-10 20:18:39 -0700 | [diff] [blame] | 100 | for field in file.get_extension() { |
| 101 | if field.get_field_type() == FieldDescriptorProto_Type::TYPE_GROUP { |
| 102 | continue; |
| 103 | } |
| 104 | |
| 105 | w.write_line(""); |
| 106 | ExtGen { |
| 107 | file: file, |
| 108 | root_scope: root_scope, |
| 109 | field: field, |
| 110 | customize: customize.clone(), |
| 111 | } |
| 112 | .write(w); |
| 113 | } |
| 114 | }); |
| 115 | } |