• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::gen::code_writer::CodeWriter;
2 use crate::gen::field::elem::FieldElem;
3 use crate::gen::field::elem::FieldElemEnum;
4 use crate::gen::field::option_kind::OptionKind;
5 use crate::gen::field::repeated::RepeatedField;
6 use crate::gen::field::repeated::RepeatedFieldKind;
7 use crate::gen::field::singular::SingularField;
8 use crate::gen::field::singular::SingularFieldFlag;
9 use crate::gen::field::FieldGen;
10 use crate::gen::field::FieldKind;
11 use crate::gen::field::MapField;
12 use crate::gen::inside::protobuf_crate_path;
13 use crate::gen::oneof::OneofField;
14 use crate::gen::rust_types_values::RustType;
15 use crate::gen::scope::WithScope;
16 
17 struct AccessorFn {
18     name: String,
19     // function type params after first underscore
20     type_params: Vec<String>,
21     callback_params: Vec<String>,
22 }
23 
24 impl AccessorFn {
sig(&self) -> String25     fn sig(&self) -> String {
26         let mut s = self.name.clone();
27         s.push_str("::<_");
28         for p in &self.type_params {
29             s.push_str(", ");
30             s.push_str(&p);
31         }
32         s.push_str(">");
33         s
34     }
35 }
36 
37 impl FieldGen<'_> {
make_accessor_fns_lambda(&self) -> Vec<String>38     fn make_accessor_fns_lambda(&self) -> Vec<String> {
39         let message = self.proto_field.message.rust_name();
40         vec![
41             format!("|m: &{}| {{ &m.{} }}", message, self.rust_name),
42             format!("|m: &mut {}| {{ &mut m.{} }}", message, self.rust_name),
43         ]
44     }
45 
make_accessor_fns_has_get_set(&self) -> Vec<String>46     fn make_accessor_fns_has_get_set(&self) -> Vec<String> {
47         let message = self.proto_field.message.rust_name();
48         vec![
49             format!("{}::{}", message, self.has_name()),
50             format!("{}::{}", message, self.rust_name),
51             format!("{}::{}", message, self.set_name()),
52         ]
53     }
54 
make_accessor_fns_has_get_mut_set(&self) -> Vec<String>55     fn make_accessor_fns_has_get_mut_set(&self) -> Vec<String> {
56         let message = self.proto_field.message.rust_name();
57         vec![
58             format!("{}::{}", message, self.has_name()),
59             format!("{}::{}", message, self.rust_name),
60             format!("{}::{}", message, self.mut_name()),
61             format!("{}::{}", message, self.set_name()),
62         ]
63     }
64 
accessor_fn_map(&self, map_field: &MapField) -> AccessorFn65     fn accessor_fn_map(&self, map_field: &MapField) -> AccessorFn {
66         let MapField { .. } = map_field;
67         AccessorFn {
68             name: "make_map_simpler_accessor".to_owned(),
69             type_params: vec![format!("_"), format!("_")],
70             callback_params: self.make_accessor_fns_lambda(),
71         }
72     }
73 
accessor_fn_repeated(&self, repeated_field: &RepeatedField) -> AccessorFn74     fn accessor_fn_repeated(&self, repeated_field: &RepeatedField) -> AccessorFn {
75         let RepeatedField { .. } = repeated_field;
76         let name = match repeated_field.kind() {
77             RepeatedFieldKind::Vec => "make_vec_simpler_accessor",
78         };
79         AccessorFn {
80             name: name.to_owned(),
81             type_params: vec![format!("_")],
82             callback_params: self.make_accessor_fns_lambda(),
83         }
84     }
85 
accessor_fn_oneof_enum(&self, oneof: &OneofField, en: &FieldElemEnum) -> AccessorFn86     fn accessor_fn_oneof_enum(&self, oneof: &OneofField, en: &FieldElemEnum) -> AccessorFn {
87         let message = self.proto_field.message.rust_name();
88 
89         let variant_path = oneof.variant_path(&self.proto_field.message.scope.rust_path_to_file());
90 
91         let getter = CodeWriter::with_no_error(|w| {
92             w.expr_block(
93                 &format!(
94                     "|message: &{}| match &message.{}",
95                     message, oneof.oneof_field_name
96                 ),
97                 |w| {
98                     w.case_expr(
99                         &format!("::std::option::Option::Some({}(e))", variant_path),
100                         "::std::option::Option::Some(*e)",
101                     );
102                     w.case_expr("_", "::std::option::Option::None");
103                 },
104             );
105         });
106 
107         let setter = CodeWriter::with_no_error(|w| {
108             w.expr_block(
109                 &format!(
110                     "|message: &mut {}, e: {}::EnumOrUnknown<{}>|",
111                     message,
112                     protobuf_crate_path(&self.customize),
113                     en.enum_rust_type(&self.file_and_mod())
114                         .to_code(&self.customize)
115                 ),
116                 |w| {
117                     w.write_line(&format!(
118                         "message.{} = ::std::option::Option::Some({}(e));",
119                         oneof.oneof_field_name, variant_path
120                     ));
121                 },
122             )
123         });
124 
125         let default = self.xxx_default_value_rust();
126 
127         AccessorFn {
128             name: "make_oneof_enum_accessors".to_owned(),
129             type_params: vec![format!("_")],
130             callback_params: vec![getter, setter, default],
131         }
132     }
133 
accessor_fn_singular_without_flag(&self, _elem: &FieldElem) -> AccessorFn134     fn accessor_fn_singular_without_flag(&self, _elem: &FieldElem) -> AccessorFn {
135         AccessorFn {
136             name: "make_simpler_field_accessor".to_owned(),
137             type_params: vec![format!("_")],
138             callback_params: self.make_accessor_fns_lambda(),
139         }
140     }
141 
accessor_fn_singular_with_flag( &self, elem: &FieldElem, _option_kind: OptionKind, ) -> AccessorFn142     fn accessor_fn_singular_with_flag(
143         &self,
144         elem: &FieldElem,
145         _option_kind: OptionKind,
146     ) -> AccessorFn {
147         match elem {
148             FieldElem::Message(m) => AccessorFn {
149                 name: "make_message_field_accessor".to_owned(),
150                 type_params: vec![format!("{}", m.rust_name_relative(&self.file_and_mod()))],
151                 callback_params: self.make_accessor_fns_lambda(),
152             },
153             FieldElem::Primitive(..) | FieldElem::Enum(..) => AccessorFn {
154                 name: "make_option_accessor".to_owned(),
155                 type_params: vec!["_".to_owned()],
156                 callback_params: self.make_accessor_fns_lambda(),
157             },
158             FieldElem::Group => {
159                 unreachable!("no accessor for group field");
160             }
161         }
162     }
163 
accessor_fn_oneof(&self, oneof: &OneofField) -> AccessorFn164     fn accessor_fn_oneof(&self, oneof: &OneofField) -> AccessorFn {
165         let OneofField { ref elem, .. } = oneof;
166 
167         let reference = self
168             .proto_field
169             .message
170             .scope
171             .file_and_mod(self.customize.clone());
172 
173         if let FieldElem::Enum(en) = &oneof.elem {
174             return self.accessor_fn_oneof_enum(oneof, en);
175         }
176 
177         if elem.is_copy() {
178             return AccessorFn {
179                 name: "make_oneof_copy_has_get_set_simpler_accessors".to_owned(),
180                 type_params: vec![format!("_")],
181                 callback_params: self.make_accessor_fns_has_get_set(),
182             };
183         }
184 
185         if let RustType::Message(name) = elem.rust_storage_elem_type(&reference) {
186             return AccessorFn {
187                 name: "make_oneof_message_has_get_mut_set_accessor".to_owned(),
188                 type_params: vec![format!("{}", name)],
189                 callback_params: self.make_accessor_fns_has_get_mut_set(),
190             };
191         }
192 
193         // string or bytes
194         AccessorFn {
195             name: "make_oneof_deref_has_get_set_simpler_accessor".to_owned(),
196             type_params: vec![format!("_")],
197             callback_params: self.make_accessor_fns_has_get_set(),
198         }
199     }
200 
accessor_fn(&self) -> AccessorFn201     fn accessor_fn(&self) -> AccessorFn {
202         match self.kind {
203             FieldKind::Repeated(ref repeated_field) => self.accessor_fn_repeated(repeated_field),
204             FieldKind::Map(ref map_field) => self.accessor_fn_map(map_field),
205             FieldKind::Singular(SingularField {
206                 ref elem,
207                 flag: SingularFieldFlag::WithoutFlag,
208             }) => self.accessor_fn_singular_without_flag(elem),
209             FieldKind::Singular(SingularField {
210                 ref elem,
211                 flag: SingularFieldFlag::WithFlag { option_kind, .. },
212             }) => self.accessor_fn_singular_with_flag(elem, option_kind),
213             FieldKind::Oneof(ref oneof) => self.accessor_fn_oneof(oneof),
214         }
215     }
216 
write_push_accessor(&self, fields_var: &str, w: &mut CodeWriter)217     pub fn write_push_accessor(&self, fields_var: &str, w: &mut CodeWriter) {
218         let accessor_fn = self.accessor_fn();
219         w.write_line(&format!(
220             "{}.push({}::reflect::rt::v2::{}(",
221             fields_var,
222             protobuf_crate_path(&self.customize),
223             accessor_fn.sig()
224         ));
225         w.indented(|w| {
226             w.write_line(&format!("\"{}\",", self.proto_field.name()));
227             for callback in &accessor_fn.callback_params {
228                 let callback_lines: Vec<&str> = callback.lines().collect();
229                 for (i, callback_line) in callback_lines.iter().enumerate() {
230                     let comma = if i == callback_lines.len() - 1 {
231                         ","
232                     } else {
233                         ""
234                     };
235                     w.write_line(&format!("{}{}", callback_line, comma));
236                 }
237             }
238         });
239         w.write_line("));");
240     }
241 }
242