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