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