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