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