1 //! Reflection implementation for protobuf types. 2 3 use std::collections::HashMap; 4 use std::default::Default; 5 use std::marker; 6 7 use core::Message; 8 use descriptor::DescriptorProto; 9 use descriptor::EnumDescriptorProto; 10 use descriptor::EnumValueDescriptorProto; 11 use descriptor::FieldDescriptorProto; 12 use descriptor::FieldDescriptorProto_Label; 13 use descriptor::FileDescriptorProto; 14 use descriptorx::find_enum_by_rust_name; 15 use descriptorx::find_message_by_rust_name; 16 use enums::ProtobufEnum; 17 use reflect::accessor::FieldAccessor; 18 19 pub mod accessor; 20 mod map; 21 mod optional; 22 mod repeated; 23 mod value; 24 25 use self::map::ReflectMap; 26 use self::repeated::ReflectRepeated; 27 28 pub use self::value::ProtobufValue; 29 pub use self::value::ProtobufValueRef; 30 31 /// Dynamic field 32 pub struct FieldDescriptor { 33 proto: &'static FieldDescriptorProto, 34 accessor: Box<FieldAccessor + 'static>, 35 } 36 37 impl FieldDescriptor { new( a: Box<FieldAccessor + 'static>, proto: &'static FieldDescriptorProto, ) -> FieldDescriptor38 fn new( 39 a: Box<FieldAccessor + 'static>, 40 proto: &'static FieldDescriptorProto, 41 ) -> FieldDescriptor { 42 assert_eq!(proto.get_name(), a.name_generic()); 43 FieldDescriptor { 44 proto: proto, 45 accessor: a, 46 } 47 } 48 49 /// Protobuf field descriptor proto(&self) -> &'static FieldDescriptorProto50 pub fn proto(&self) -> &'static FieldDescriptorProto { 51 self.proto 52 } 53 54 /// Field protobuf name name(&self) -> &'static str55 pub fn name(&self) -> &'static str { 56 self.proto.get_name() 57 } 58 59 /// If field repeated? is_repeated(&self) -> bool60 pub fn is_repeated(&self) -> bool { 61 self.proto.get_label() == FieldDescriptorProto_Label::LABEL_REPEATED 62 } 63 64 /// Is field set? has_field(&self, m: &Message) -> bool65 pub fn has_field(&self, m: &Message) -> bool { 66 self.accessor.has_field_generic(m) 67 } 68 69 /// Get length of `repeated` or `map` field len_field(&self, m: &Message) -> usize70 pub fn len_field(&self, m: &Message) -> usize { 71 self.accessor.len_field_generic(m) 72 } 73 74 /// Get singular `message` get_message<'a>(&self, m: &'a Message) -> &'a Message75 pub fn get_message<'a>(&self, m: &'a Message) -> &'a Message { 76 self.accessor.get_message_generic(m) 77 } 78 79 /// Get singular `enum` get_enum(&self, m: &Message) -> &'static EnumValueDescriptor80 pub fn get_enum(&self, m: &Message) -> &'static EnumValueDescriptor { 81 self.accessor.get_enum_generic(m) 82 } 83 84 /// Get singular `string` get_str<'a>(&self, m: &'a Message) -> &'a str85 pub fn get_str<'a>(&self, m: &'a Message) -> &'a str { 86 self.accessor.get_str_generic(m) 87 } 88 89 /// Get singular `bytes` get_bytes<'a>(&self, m: &'a Message) -> &'a [u8]90 pub fn get_bytes<'a>(&self, m: &'a Message) -> &'a [u8] { 91 self.accessor.get_bytes_generic(m) 92 } 93 94 /// Get singular `u32` get_u32(&self, m: &Message) -> u3295 pub fn get_u32(&self, m: &Message) -> u32 { 96 self.accessor.get_u32_generic(m) 97 } 98 99 /// Get singular `u64` get_u64(&self, m: &Message) -> u64100 pub fn get_u64(&self, m: &Message) -> u64 { 101 self.accessor.get_u64_generic(m) 102 } 103 104 /// Get singular `i32` get_i32(&self, m: &Message) -> i32105 pub fn get_i32(&self, m: &Message) -> i32 { 106 self.accessor.get_i32_generic(m) 107 } 108 109 /// Get singular `i64` get_i64(&self, m: &Message) -> i64110 pub fn get_i64(&self, m: &Message) -> i64 { 111 self.accessor.get_i64_generic(m) 112 } 113 114 /// Get singular `bool` get_bool(&self, m: &Message) -> bool115 pub fn get_bool(&self, m: &Message) -> bool { 116 self.accessor.get_bool_generic(m) 117 } 118 119 /// Get singular `f32` get_f32(&self, m: &Message) -> f32120 pub fn get_f32(&self, m: &Message) -> f32 { 121 self.accessor.get_f32_generic(m) 122 } 123 124 /// Get singular `f64` get_f64(&self, m: &Message) -> f64125 pub fn get_f64(&self, m: &Message) -> f64 { 126 self.accessor.get_f64_generic(m) 127 } 128 129 /// Get a field get_reflect<'a>(&self, m: &'a Message) -> ReflectFieldRef<'a>130 pub fn get_reflect<'a>(&self, m: &'a Message) -> ReflectFieldRef<'a> { 131 self.accessor.get_reflect(m) 132 } 133 } 134 135 trait MessageFactory { new_instance(&self) -> Box<Message>136 fn new_instance(&self) -> Box<Message>; 137 } 138 139 struct MessageFactoryTyped<M> { 140 _dummy: (), 141 _phantom_data: marker::PhantomData<M>, 142 } 143 144 impl<M> MessageFactoryTyped<M> { new() -> MessageFactoryTyped<M>145 fn new() -> MessageFactoryTyped<M> { 146 MessageFactoryTyped { 147 _dummy: (), 148 _phantom_data: marker::PhantomData, 149 } 150 } 151 } 152 153 impl<M: 'static + Message + Default> MessageFactory for MessageFactoryTyped<M> { new_instance(&self) -> Box<Message>154 fn new_instance(&self) -> Box<Message> { 155 let m: M = Default::default(); 156 Box::new(m) 157 } 158 } 159 160 /// Dynamic message type 161 pub struct MessageDescriptor { 162 full_name: String, 163 proto: &'static DescriptorProto, 164 factory: Box<MessageFactory + 'static>, 165 fields: Vec<FieldDescriptor>, 166 167 index_by_name: HashMap<String, usize>, 168 index_by_number: HashMap<u32, usize>, 169 } 170 171 impl MessageDescriptor { 172 /// Get underlying `DescriptorProto` object. get_proto(&self) -> &DescriptorProto173 pub fn get_proto(&self) -> &DescriptorProto { 174 self.proto 175 } 176 177 /// Get message descriptor for given message type. for_type<M: Message>() -> &'static MessageDescriptor178 pub fn for_type<M: Message>() -> &'static MessageDescriptor { 179 M::descriptor_static() 180 } 181 182 /// Create new message descriptor. 183 /// 184 /// This function is called from generated code and rarely needed otherwise. new<M: 'static + Message + Default>( rust_name: &'static str, fields: Vec<Box<FieldAccessor + 'static>>, file: &'static FileDescriptorProto, ) -> MessageDescriptor185 pub fn new<M: 'static + Message + Default>( 186 rust_name: &'static str, 187 fields: Vec<Box<FieldAccessor + 'static>>, 188 file: &'static FileDescriptorProto, 189 ) -> MessageDescriptor { 190 let proto = find_message_by_rust_name(file, rust_name); 191 192 let mut field_proto_by_name = HashMap::new(); 193 for field_proto in proto.message.get_field() { 194 field_proto_by_name.insert(field_proto.get_name(), field_proto); 195 } 196 197 let mut index_by_name = HashMap::new(); 198 let mut index_by_number = HashMap::new(); 199 for (i, f) in proto.message.get_field().iter().enumerate() { 200 index_by_number.insert(f.get_number() as u32, i); 201 index_by_name.insert(f.get_name().to_string(), i); 202 } 203 204 let mut full_name = file.get_package().to_string(); 205 if full_name.len() > 0 { 206 full_name.push('.'); 207 } 208 full_name.push_str(proto.message.get_name()); 209 210 MessageDescriptor { 211 full_name: full_name, 212 proto: proto.message, 213 factory: Box::new(MessageFactoryTyped::<M>::new()), 214 fields: fields 215 .into_iter() 216 .map(|f| { 217 let proto = *field_proto_by_name.get(&f.name_generic()).unwrap(); 218 FieldDescriptor::new(f, proto) 219 }) 220 .collect(), 221 index_by_name: index_by_name, 222 index_by_number: index_by_number, 223 } 224 } 225 226 /// Create a new message of this type new_instance(&self) -> Box<Message>227 pub fn new_instance(&self) -> Box<Message> { 228 self.factory.new_instance() 229 } 230 231 /// Protobuf message name name(&self) -> &'static str232 pub fn name(&self) -> &'static str { 233 self.proto.get_name() 234 } 235 236 /// Full protobuf message name full_name(&self) -> &str237 pub fn full_name(&self) -> &str { 238 &self.full_name[..] 239 } 240 241 /// Get all fields fields<'a>(&'a self) -> &'a [FieldDescriptor]242 pub fn fields<'a>(&'a self) -> &'a [FieldDescriptor] { 243 &self.fields 244 } 245 246 /// Find field by name field_by_name<'a>(&'a self, name: &str) -> &'a FieldDescriptor247 pub fn field_by_name<'a>(&'a self, name: &str) -> &'a FieldDescriptor { 248 // TODO: clone is weird 249 let &index = self.index_by_name.get(&name.to_string()).unwrap(); 250 &self.fields[index] 251 } 252 253 /// Find field by number field_by_number<'a>(&'a self, number: u32) -> &'a FieldDescriptor254 pub fn field_by_number<'a>(&'a self, number: u32) -> &'a FieldDescriptor { 255 let &index = self.index_by_number.get(&number).unwrap(); 256 &self.fields[index] 257 } 258 } 259 260 /// Dynamic enum value 261 #[derive(Clone)] 262 pub struct EnumValueDescriptor { 263 proto: &'static EnumValueDescriptorProto, 264 } 265 266 impl Copy for EnumValueDescriptor {} 267 268 impl EnumValueDescriptor { 269 /// Protobuf (not Rust) enum value name name(&self) -> &'static str270 pub fn name(&self) -> &'static str { 271 self.proto.get_name() 272 } 273 274 /// Enum value as integer value(&self) -> i32275 pub fn value(&self) -> i32 { 276 self.proto.get_number() 277 } 278 } 279 280 /// Dynamic enum type 281 pub struct EnumDescriptor { 282 proto: &'static EnumDescriptorProto, 283 values: Vec<EnumValueDescriptor>, 284 285 index_by_name: HashMap<String, usize>, 286 index_by_number: HashMap<i32, usize>, 287 } 288 289 impl EnumDescriptor { 290 /// Protobuf enum name name(&self) -> &'static str291 pub fn name(&self) -> &'static str { 292 self.proto.get_name() 293 } 294 295 /// `EnumDescriptor` for enum type for_type<E: ProtobufEnum>() -> &'static EnumDescriptor296 pub fn for_type<E: ProtobufEnum>() -> &'static EnumDescriptor { 297 E::enum_descriptor_static() 298 } 299 300 /// Create new enum descriptor. 301 /// 302 /// This function is called by generated code, and rarely needed otherwise. new(rust_name: &'static str, file: &'static FileDescriptorProto) -> EnumDescriptor303 pub fn new(rust_name: &'static str, file: &'static FileDescriptorProto) -> EnumDescriptor { 304 let proto = find_enum_by_rust_name(file, rust_name); 305 let mut index_by_name = HashMap::new(); 306 let mut index_by_number = HashMap::new(); 307 for (i, v) in proto.en.get_value().iter().enumerate() { 308 index_by_number.insert(v.get_number(), i); 309 index_by_name.insert(v.get_name().to_string(), i); 310 } 311 EnumDescriptor { 312 proto: proto.en, 313 values: proto 314 .en 315 .get_value() 316 .iter() 317 .map(|v| EnumValueDescriptor { proto: v }) 318 .collect(), 319 index_by_name: index_by_name, 320 index_by_number: index_by_number, 321 } 322 } 323 324 /// Find enum value by name value_by_name<'a>(&'a self, name: &str) -> &'a EnumValueDescriptor325 pub fn value_by_name<'a>(&'a self, name: &str) -> &'a EnumValueDescriptor { 326 // TODO: clone is weird 327 let &index = self.index_by_name.get(&name.to_string()).unwrap(); 328 &self.values[index] 329 } 330 331 /// Find enum value by number value_by_number<'a>(&'a self, number: i32) -> &'a EnumValueDescriptor332 pub fn value_by_number<'a>(&'a self, number: i32) -> &'a EnumValueDescriptor { 333 let &index = self.index_by_number.get(&number).unwrap(); 334 &self.values[index] 335 } 336 } 337 338 /// Dynamic field reference 339 pub enum ReflectFieldRef<'a> { 340 /// Repeated field 341 Repeated(&'a ReflectRepeated), 342 /// Map field 343 Map(&'a ReflectMap), 344 /// Optional field 345 Optional(Option<ProtobufValueRef<'a>>), 346 } 347