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