blob: 0740fdb327e1eddc86cc1fdeedbd3d96e7241611 [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;
Haibo Huangba676d32020-08-12 13:52:13 -07004use inside::protobuf_crate_path;
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -07005use protobuf::descriptor::*;
6use protobuf_name::ProtobufAbsolutePath;
7use scope::RootScope;
8use Customize;
9
10struct ExtGen<'a> {
11 file: &'a FileDescriptorProto,
12 root_scope: &'a RootScope<'a>,
13 field: &'a FieldDescriptorProto,
14 customize: Customize,
15}
16
17impl<'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 Huangba676d32020-08-12 13:52:13 -070024 &self.customize,
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -070025 )
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 Huangba676d32020-08-12 13:52:13 -070045 &self.customize,
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -070046 );
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 Huangba676d32020-08-12 13:52:13 -070065 let field_type = format!(
66 "{}::ext::ExtField{}",
67 protobuf_crate_path(&self.customize),
68 suffix
69 );
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -070070 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
87pub(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 Huang72fec012020-07-10 20:24:04 -070098 w.write_line("/// Extension fields");
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -070099 w.pub_mod("exts", |w| {
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -0700100 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}