diff options
Diffstat (limited to 'src/reflect/message.rs')
-rw-r--r-- | src/reflect/message.rs | 282 |
1 files changed, 0 insertions, 282 deletions
diff --git a/src/reflect/message.rs b/src/reflect/message.rs deleted file mode 100644 index 0db9821..0000000 --- a/src/reflect/message.rs +++ /dev/null @@ -1,282 +0,0 @@ -use std::collections::HashMap; -use std::marker; - -use crate::descriptor::DescriptorProto; -use crate::descriptor::FileDescriptorProto; -use crate::descriptorx::find_message_by_rust_name; -use crate::reflect::acc::FieldAccessor; -use crate::reflect::find_message_or_enum::find_message_or_enum; -use crate::reflect::find_message_or_enum::MessageOrEnum; -use crate::reflect::FieldDescriptor; -use crate::Message; - -trait MessageFactory: Send + Sync + 'static { - fn new_instance(&self) -> Box<dyn Message>; -} - -struct MessageFactoryImpl<M>(marker::PhantomData<M>); - -impl<M> MessageFactory for MessageFactoryImpl<M> -where - M: 'static + Message + Default + Clone + PartialEq, -{ - fn new_instance(&self) -> Box<dyn Message> { - let m: M = Default::default(); - Box::new(m) - } -} - -/// Dynamic message type -pub struct MessageDescriptor { - full_name: String, - proto: &'static DescriptorProto, - factory: &'static dyn MessageFactory, - fields: Vec<FieldDescriptor>, - - index_by_name: HashMap<String, usize>, - index_by_name_or_json_name: HashMap<String, usize>, - index_by_number: HashMap<u32, usize>, -} - -impl MessageDescriptor { - /// Get underlying `DescriptorProto` object. - pub fn get_proto(&self) -> &DescriptorProto { - self.proto - } - - /// Get a message descriptor for given message type - pub fn for_type<M: Message>() -> &'static MessageDescriptor { - M::descriptor_static() - } - - fn compute_full_name(package: &str, path_to_package: &str, proto: &DescriptorProto) -> String { - let mut full_name = package.to_owned(); - if path_to_package.len() != 0 { - if full_name.len() != 0 { - full_name.push('.'); - } - full_name.push_str(path_to_package); - } - if full_name.len() != 0 { - full_name.push('.'); - } - full_name.push_str(proto.get_name()); - full_name - } - - // Non-generic part of `new` is a separate function - // to reduce code bloat from multiple instantiations. - fn new_non_generic_by_rust_name( - rust_name: &'static str, - fields: Vec<FieldAccessor>, - file: &'static FileDescriptorProto, - factory: &'static dyn MessageFactory, - ) -> MessageDescriptor { - let proto = find_message_by_rust_name(file, rust_name); - - let mut field_proto_by_name = HashMap::new(); - for field_proto in proto.message.get_field() { - field_proto_by_name.insert(field_proto.get_name(), field_proto); - } - - let mut index_by_name = HashMap::new(); - let mut index_by_name_or_json_name = HashMap::new(); - let mut index_by_number = HashMap::new(); - - let mut full_name = file.get_package().to_string(); - if full_name.len() > 0 { - full_name.push('.'); - } - full_name.push_str(proto.message.get_name()); - - let fields: Vec<_> = fields - .into_iter() - .map(|f| { - let proto = *field_proto_by_name.get(&f.name).unwrap(); - FieldDescriptor::new(f, proto) - }) - .collect(); - for (i, f) in fields.iter().enumerate() { - assert!(index_by_number - .insert(f.proto().get_number() as u32, i) - .is_none()); - assert!(index_by_name - .insert(f.proto().get_name().to_owned(), i) - .is_none()); - assert!(index_by_name_or_json_name - .insert(f.proto().get_name().to_owned(), i) - .is_none()); - - let json_name = f.json_name().to_owned(); - - if json_name != f.proto().get_name() { - assert!(index_by_name_or_json_name.insert(json_name, i).is_none()); - } - } - MessageDescriptor { - full_name, - proto: proto.message, - factory, - fields, - index_by_name, - index_by_name_or_json_name, - index_by_number, - } - } - - // Non-generic part of `new` is a separate function - // to reduce code bloat from multiple instantiations. - fn new_non_generic_by_pb_name( - protobuf_name_to_package: &'static str, - fields: Vec<FieldAccessor>, - file_descriptor_proto: &'static FileDescriptorProto, - factory: &'static dyn MessageFactory, - ) -> MessageDescriptor { - let (path_to_package, proto) = - match find_message_or_enum(file_descriptor_proto, protobuf_name_to_package) { - (path_to_package, MessageOrEnum::Message(m)) => (path_to_package, m), - (_, MessageOrEnum::Enum(_)) => panic!("not a message"), - }; - - let mut field_proto_by_name = HashMap::new(); - for field_proto in proto.get_field() { - field_proto_by_name.insert(field_proto.get_name(), field_proto); - } - - let mut index_by_name = HashMap::new(); - let mut index_by_name_or_json_name = HashMap::new(); - let mut index_by_number = HashMap::new(); - - let full_name = MessageDescriptor::compute_full_name( - file_descriptor_proto.get_package(), - &path_to_package, - &proto, - ); - let fields: Vec<_> = fields - .into_iter() - .map(|f| { - let proto = *field_proto_by_name.get(&f.name).unwrap(); - FieldDescriptor::new(f, proto) - }) - .collect(); - - for (i, f) in fields.iter().enumerate() { - assert!(index_by_number - .insert(f.proto().get_number() as u32, i) - .is_none()); - assert!(index_by_name - .insert(f.proto().get_name().to_owned(), i) - .is_none()); - assert!(index_by_name_or_json_name - .insert(f.proto().get_name().to_owned(), i) - .is_none()); - - let json_name = f.json_name().to_owned(); - - if json_name != f.proto().get_name() { - assert!(index_by_name_or_json_name.insert(json_name, i).is_none()); - } - } - MessageDescriptor { - full_name, - proto, - factory, - fields, - index_by_name, - index_by_name_or_json_name, - index_by_number, - } - } - - /// Construct a new message descriptor. - /// - /// This operation is called from generated code and rarely - /// need to be called directly. - #[doc(hidden)] - #[deprecated( - since = "2.12", - note = "Please regenerate .rs files from .proto files to use newer APIs" - )] - pub fn new<M: 'static + Message + Default + Clone + PartialEq>( - rust_name: &'static str, - fields: Vec<FieldAccessor>, - file: &'static FileDescriptorProto, - ) -> MessageDescriptor { - let factory = &MessageFactoryImpl(marker::PhantomData::<M>); - MessageDescriptor::new_non_generic_by_rust_name(rust_name, fields, file, factory) - } - - /// Construct a new message descriptor. - /// - /// This operation is called from generated code and rarely - /// need to be called directly. - #[doc(hidden)] - pub fn new_pb_name<M: 'static + Message + Default + Clone + PartialEq>( - protobuf_name_to_package: &'static str, - fields: Vec<FieldAccessor>, - file_descriptor_proto: &'static FileDescriptorProto, - ) -> MessageDescriptor { - let factory = &MessageFactoryImpl(marker::PhantomData::<M>); - MessageDescriptor::new_non_generic_by_pb_name( - protobuf_name_to_package, - fields, - file_descriptor_proto, - factory, - ) - } - - /// New empty message - pub fn new_instance(&self) -> Box<dyn Message> { - self.factory.new_instance() - } - - /// Message name as given in `.proto` file - pub fn name(&self) -> &'static str { - self.proto.get_name() - } - - /// Fully qualified protobuf message name - pub fn full_name(&self) -> &str { - &self.full_name[..] - } - - /// Message field descriptors. - pub fn fields(&self) -> &[FieldDescriptor] { - &self.fields - } - - /// Find message field by protobuf field name - /// - /// Note: protobuf field name might be different for Rust field name. - pub fn get_field_by_name<'a>(&'a self, name: &str) -> Option<&'a FieldDescriptor> { - let &index = self.index_by_name.get(name)?; - Some(&self.fields[index]) - } - - /// Find message field by field name or field JSON name - pub fn get_field_by_name_or_json_name<'a>(&'a self, name: &str) -> Option<&'a FieldDescriptor> { - let &index = self.index_by_name_or_json_name.get(name)?; - Some(&self.fields[index]) - } - - /// Find message field by field name - pub fn get_field_by_number(&self, number: u32) -> Option<&FieldDescriptor> { - let &index = self.index_by_number.get(&number)?; - Some(&self.fields[index]) - } - - /// Find field by name - // TODO: deprecate - pub fn field_by_name<'a>(&'a self, name: &str) -> &'a FieldDescriptor { - // TODO: clone is weird - let &index = self.index_by_name.get(&name.to_string()).unwrap(); - &self.fields[index] - } - - /// Find field by number - // TODO: deprecate - pub fn field_by_number<'a>(&'a self, number: u32) -> &'a FieldDescriptor { - let &index = self.index_by_number.get(&number).unwrap(); - &self.fields[index] - } -} |