blob: 637e18f15188f848e6064c5a4adf034e9652d233 [file] [log] [blame]
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -07001use super::code_writer::CodeWriter;
2use super::rust_types_values::*;
3use field::rust_field_name_for_protobuf_field_name;
4use protobuf::descriptor::*;
5use protobuf_name::ProtobufAbsolutePath;
6use scope::RootScope;
7use Customize;
8
9struct ExtGen<'a> {
10 file: &'a FileDescriptorProto,
11 root_scope: &'a RootScope<'a>,
12 field: &'a FieldDescriptorProto,
13 customize: Customize,
14}
15
16impl<'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
80pub(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 Huang72fec012020-07-10 20:24:04 -070091 w.write_line("/// Extension fields");
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -070092 w.pub_mod("exts", |w| {
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -070093 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}