use std::fmt; use crate::descriptor::field_descriptor_proto; use crate::descriptor::FieldDescriptorProto; use crate::message_dyn::MessageDyn; use crate::reflect::acc::v2::map::MapFieldAccessorHolder; use crate::reflect::acc::v2::repeated::RepeatedFieldAccessorHolder; use crate::reflect::acc::v2::singular::SingularFieldAccessorHolder; use crate::reflect::acc::v2::AccessorV2; use crate::reflect::acc::GeneratedFieldAccessor; use crate::reflect::dynamic::DynamicMessage; use crate::reflect::field::dynamic::DynamicFieldDescriptorRef; use crate::reflect::field::index::FieldIndex; use crate::reflect::field::index::FieldKind; use crate::reflect::field::protobuf_field_type::ProtobufFieldType; use crate::reflect::field::runtime_field_type::RuntimeFieldType; use crate::reflect::map::ReflectMapMut; use crate::reflect::map::ReflectMapRef; use crate::reflect::message::message_ref::MessageRef; use crate::reflect::message::MessageDescriptorImplRef; use crate::reflect::oneof::OneofDescriptor; use crate::reflect::protobuf_type_box::ProtobufType; use crate::reflect::reflect_eq::ReflectEq; use crate::reflect::reflect_eq::ReflectEqMode; use crate::reflect::repeated::ReflectRepeatedMut; use crate::reflect::repeated::ReflectRepeatedRef; use crate::reflect::value::value_ref::ReflectValueMut; use crate::reflect::FileDescriptor; use crate::reflect::MessageDescriptor; use crate::reflect::ReflectOptionalRef; use crate::reflect::ReflectValueBox; use crate::reflect::ReflectValueRef; use crate::reflect::RuntimeType; pub(crate) mod dynamic; pub(crate) mod index; pub(crate) mod protobuf_field_type; pub(crate) mod runtime_field_type; /// Reference to a value stored in a field, optional, repeated or map. #[derive(PartialEq)] pub enum ReflectFieldRef<'a> { /// Singular field, optional or required in proto3 and just plain field in proto3 Optional(ReflectOptionalRef<'a>), /// Repeated field Repeated(ReflectRepeatedRef<'a>), /// Map field Map(ReflectMapRef<'a>), } impl<'a> ReflectFieldRef<'a> { pub(crate) fn default_for_field(field: &FieldDescriptor) -> ReflectFieldRef<'a> { match field.runtime_field_type() { RuntimeFieldType::Singular(elem) => { ReflectFieldRef::Optional(ReflectOptionalRef::none(elem)) } RuntimeFieldType::Repeated(elem) => { ReflectFieldRef::Repeated(ReflectRepeatedRef::new_empty(elem)) } RuntimeFieldType::Map(k, v) => ReflectFieldRef::Map(ReflectMapRef::new_empty(k, v)), } } } impl<'a> ReflectEq for ReflectFieldRef<'a> { fn reflect_eq(&self, that: &Self, mode: &ReflectEqMode) -> bool { match (self, that) { (ReflectFieldRef::Optional(a), ReflectFieldRef::Optional(b)) => { match (a.value(), b.value()) { (Some(av), Some(bv)) => av.reflect_eq(&bv, mode), (None, None) => true, _ => false, } } (ReflectFieldRef::Repeated(a), ReflectFieldRef::Repeated(b)) => a.reflect_eq(b, mode), (ReflectFieldRef::Map(a), ReflectFieldRef::Map(b)) => a.reflect_eq(b, mode), _ => false, } } } fn _assert_sync<'a>() { fn _assert_send_sync() {} _assert_send_sync::>(); } /// Field descriptor. /// /// Can be used for runtime reflection. #[derive(Eq, PartialEq, Clone)] pub struct FieldDescriptor { pub(crate) file_descriptor: FileDescriptor, pub(crate) index: usize, } impl fmt::Display for FieldDescriptor { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.index().kind { FieldKind::MessageField(m) => write!( f, "{}.{}", self.file_descriptor.message_by_index(*m), self.name() ), FieldKind::Extension(Some(m), _) => write!( f, "{}.{}", self.file_descriptor.message_by_index(*m), self.name() ), FieldKind::Extension(None, _) => { if self.file_descriptor.proto().package().is_empty() { write!(f, "{}", self.name()) } else { write!( f, "{}.{}", self.file_descriptor.proto().package(), self.name() ) } } } } } impl FieldDescriptor { pub(crate) fn regular(&self) -> (MessageDescriptor, usize) { match self.index().kind { FieldKind::MessageField(_) => { let m = self.containing_message(); ( m.clone(), self.index - m.index().message_index.first_field_index, ) } // TODO: implement and remove. _ => panic!("regular field"), } } pub(crate) fn file_descriptor(&self) -> &FileDescriptor { &self.file_descriptor } /// Get `.proto` description of field pub fn proto(&self) -> &FieldDescriptorProto { &self.index().proto } /// Field name as specified in `.proto` file. pub fn name(&self) -> &str { self.proto().name() } /// Field number as specified in `.proto` file. pub fn number(&self) -> i32 { self.proto().number() } /// Fully qualified name of the field: fully qualified name of the declaring type /// followed by the field name. /// /// Declaring type is a message (for regular field or extensions) or a package /// (for top-level extensions). pub fn full_name(&self) -> String { self.to_string() } /// Oneof descriptor containing this field. Do not skip synthetic oneofs. pub fn containing_oneof_including_synthetic(&self) -> Option { if let FieldKind::MessageField(..) = self.index().kind { let proto = self.proto(); if proto.has_oneof_index() { Some(OneofDescriptor { file_descriptor: self.file_descriptor().clone(), index: self.containing_message().index().oneofs.start + proto.oneof_index() as usize, }) } else { None } } else { None } } /// Oneof containing this field. /// /// Return `None` if this field is not part of oneof or if it is synthetic oneof. pub fn containing_oneof(&self) -> Option { self.containing_oneof_including_synthetic() .filter(|o| !o.is_synthetic()) } /// Message which declares this field (for extension, **not** the message we extend). fn _declaring_message(&self) -> Option { match &self.index().kind { FieldKind::MessageField(m) => Some(self.file_descriptor.message_by_index(*m)), FieldKind::Extension(m, _) => Some(self.file_descriptor.message_by_index(*m.as_ref()?)), } } /// Message which contains this field. /// /// For extension fields, this is the message being extended. pub fn containing_message(&self) -> MessageDescriptor { match &self.index().kind { FieldKind::MessageField(m) => self.file_descriptor().message_by_index(*m), FieldKind::Extension(_, extendee) => extendee.resolve_message(self.file_descriptor()), } } fn index(&self) -> &FieldIndex { &self.file_descriptor.common().fields[self.index] } fn index_with_message_lifetime<'a>(&self, m: &'a dyn MessageDyn) -> &'a FieldIndex { let (descriptor, index) = self.regular(); let file_fields = match self.singular() { SingularFieldAccessorRef::Generated(..) => { &descriptor .file_descriptor .common_for_generated_descriptor() .fields } SingularFieldAccessorRef::Dynamic(..) => { &DynamicMessage::downcast_ref(m) .descriptor() .file_descriptor .common() .fields } }; &descriptor.index().message_index.slice_fields(file_fields)[index] } /// JSON field name. /// /// Can be different from `.proto` field name. /// /// See [JSON mapping][json] for details. /// /// [json]: https://developers.google.com/protocol-buffers/docs/proto3#json pub fn json_name(&self) -> &str { &self.index().json_name } /// If this field is optional or required. pub fn is_singular(&self) -> bool { match self.proto().label() { field_descriptor_proto::Label::LABEL_REQUIRED => true, field_descriptor_proto::Label::LABEL_OPTIONAL => true, field_descriptor_proto::Label::LABEL_REPEATED => false, } } /// Is this field required. pub fn is_required(&self) -> bool { self.proto().label() == field_descriptor_proto::Label::LABEL_REQUIRED } /// If this field repeated or map? pub fn is_repeated_or_map(&self) -> bool { self.proto().label() == field_descriptor_proto::Label::LABEL_REPEATED } /// Is this field repeated, but not map field? pub fn is_repeated(&self) -> bool { match self.runtime_field_type() { RuntimeFieldType::Repeated(..) => true, _ => false, } } fn get_impl(&self) -> FieldDescriptorImplRef { let (descriptor, index) = self.regular(); match descriptor.get_impl() { MessageDescriptorImplRef::Generated(g) => { FieldDescriptorImplRef::Generated(&g.non_map().fields[index].accessor) } MessageDescriptorImplRef::Dynamic => { FieldDescriptorImplRef::Dynamic(DynamicFieldDescriptorRef { field: self }) } } } /// If this field a map field? pub fn is_map(&self) -> bool { match self.runtime_field_type() { RuntimeFieldType::Map(..) => true, _ => false, } } /// Check if field is set in given message. /// /// For repeated field or map field return `true` if /// collection is not empty. /// /// # Panics /// /// If this field belongs to a different message type. pub fn has_field(&self, m: &dyn MessageDyn) -> bool { match self.get_reflect(m) { ReflectFieldRef::Optional(v) => v.value().is_some(), ReflectFieldRef::Repeated(r) => !r.is_empty(), ReflectFieldRef::Map(m) => !m.is_empty(), } } // accessors fn singular(&self) -> SingularFieldAccessorRef { match self.get_impl() { FieldDescriptorImplRef::Generated(GeneratedFieldAccessor::V2( AccessorV2::Singular(ref a), )) => SingularFieldAccessorRef::Generated(a), FieldDescriptorImplRef::Generated(GeneratedFieldAccessor::V2(..)) => { panic!("not a singular field: {}", self) } FieldDescriptorImplRef::Dynamic(d) => SingularFieldAccessorRef::Dynamic(d), } } fn repeated(&self) -> RepeatedFieldAccessorRef { match self.get_impl() { FieldDescriptorImplRef::Generated(GeneratedFieldAccessor::V2( AccessorV2::Repeated(ref a), )) => RepeatedFieldAccessorRef::Generated(a), FieldDescriptorImplRef::Generated(GeneratedFieldAccessor::V2(..)) => { panic!("not a repeated field: {}", self) } FieldDescriptorImplRef::Dynamic(d) => RepeatedFieldAccessorRef::Dynamic(d), } } fn map(&self) -> MapFieldAccessorRef { match self.get_impl() { FieldDescriptorImplRef::Generated(GeneratedFieldAccessor::V2(AccessorV2::Map( ref a, ))) => MapFieldAccessorRef::Generated(a), FieldDescriptorImplRef::Generated(GeneratedFieldAccessor::V2(..)) => { panic!("not a map field: {}", self) } FieldDescriptorImplRef::Dynamic(d) => MapFieldAccessorRef::Dynamic(d), } } /// Obtain type of map key and value. pub(crate) fn map_proto_type(&self) -> (ProtobufType, ProtobufType) { match self.protobuf_field_type() { ProtobufFieldType::Map(k, v) => (k, v), _ => panic!("not a map field: {}", self), } } /// Get message field or default instance if field is unset. /// /// # Panics /// If this field belongs to a different message type or /// field type is not message. pub fn get_message<'a>(&self, m: &'a dyn MessageDyn) -> MessageRef<'a> { match self.get_singular_field_or_default(m) { ReflectValueRef::Message(m) => m, _ => panic!("not message field: {}", self), } } /// Get a mutable reference to a message field. /// Initialize field with default message if unset. /// /// # Panics /// /// If this field belongs to a different message type or /// field type is not singular message. pub fn mut_message<'a>(&self, m: &'a mut dyn MessageDyn) -> &'a mut dyn MessageDyn { match self.mut_singular_field_or_default(m) { ReflectValueMut::Message(m) => m, } } /// Default value. /// /// # Panics /// /// If field is not singular. pub fn singular_default_value(&self) -> ReflectValueRef { self.index().default_value(self) } /// Get singular field value. /// /// Return field default value if field is unset. /// /// # Panics /// /// If this field belongs to a different message type or fields is not singular. pub fn get_singular_field_or_default<'a>(&self, m: &'a dyn MessageDyn) -> ReflectValueRef<'a> { match self.get_singular(m) { Some(m) => m, None => self.index_with_message_lifetime(m).default_value(self), } } // Not public because it is not implemented for all types fn mut_singular_field_or_default<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectValueMut<'a> { match self.singular() { SingularFieldAccessorRef::Generated(g) => g.accessor.mut_field_or_default(m), SingularFieldAccessorRef::Dynamic(..) => { DynamicMessage::downcast_mut(m).mut_singular_field_or_default(self) } } } /// Runtime representation of singular field. /// /// # Panics /// /// If this field belongs to a different message type or field is not singular. pub fn singular_runtime_type(&self) -> RuntimeType { match self.runtime_field_type() { RuntimeFieldType::Singular(s) => s, _ => panic!("Not a singular field: {}", self), } } /// Set singular field. /// /// # Panics /// /// If this field belongs to a different message type or /// field is not singular or value is of different type. pub fn set_singular_field(&self, m: &mut dyn MessageDyn, value: ReflectValueBox) { match self.singular() { SingularFieldAccessorRef::Generated(g) => g.accessor.set_field(m, value), SingularFieldAccessorRef::Dynamic(d) => d.set_field(m, value), } } /// Clear a field. pub fn clear_field(&self, m: &mut dyn MessageDyn) { if self.is_singular() { match self.singular() { SingularFieldAccessorRef::Generated(g) => g.accessor.clear_field(m), SingularFieldAccessorRef::Dynamic(d) => d.clear_field(m), } } else if self.is_repeated() { self.mut_repeated(m).clear(); } else if self.is_map() { self.mut_map(m).clear(); } } /// Dynamic representation of field type with wire type. pub(crate) fn protobuf_field_type(&self) -> ProtobufFieldType { self.index().field_type.resolve(self.file_descriptor()) } /// Dynamic representation of field type. pub fn runtime_field_type(&self) -> RuntimeFieldType { self.protobuf_field_type().runtime() } /// Get field of any type. /// /// # Panics /// /// If this field belongs to a different message type. pub fn get_reflect<'a>(&self, m: &'a dyn MessageDyn) -> ReflectFieldRef<'a> { match self.get_impl() { FieldDescriptorImplRef::Generated(g) => g.get_reflect(m), FieldDescriptorImplRef::Dynamic(d) => d.get_reflect(m), } } /// Get singular field value. /// /// Return `None` if field is unset. /// /// # Panics /// /// If this field belongs to a different message type or fields is not singular. pub fn get_singular<'a>(&self, m: &'a dyn MessageDyn) -> Option> { match self.get_reflect(m) { ReflectFieldRef::Optional(o) => o.value(), _ => panic!("not a singular field"), } } // repeated /// Get repeated field. /// /// # Panics /// /// If this field belongs to a different message type or field is not repeated. pub fn get_repeated<'a>(&self, m: &'a dyn MessageDyn) -> ReflectRepeatedRef<'a> { match self.get_reflect(m) { ReflectFieldRef::Repeated(r) => r, _ => panic!("not a repeated field"), } } /// Get a mutable reference to `repeated` field. /// /// # Panics /// /// If this field belongs to a different message type or field is not `repeated`. pub fn mut_repeated<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectRepeatedMut<'a> { match self.repeated() { RepeatedFieldAccessorRef::Generated(g) => g.accessor.mut_repeated(m), RepeatedFieldAccessorRef::Dynamic(d) => d.mut_repeated(m), } } // map /// Get `map` field. /// /// # Panics /// /// If this field belongs to a different message type or field is not `map`. pub fn get_map<'a>(&self, m: &'a dyn MessageDyn) -> ReflectMapRef<'a> { match self.get_reflect(m) { ReflectFieldRef::Map(m) => m, _ => panic!("not a map field"), } } /// Get a mutable reference to `map` field. /// /// # Panics /// /// If this field belongs to a different message type or field is not `map`. pub fn mut_map<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectMapMut<'a> { match self.map() { MapFieldAccessorRef::Generated(g) => g.accessor.mut_reflect(m), MapFieldAccessorRef::Dynamic(d) => d.mut_map(m), } } } enum SingularFieldAccessorRef<'a> { Generated(&'a SingularFieldAccessorHolder), Dynamic(DynamicFieldDescriptorRef<'a>), } enum RepeatedFieldAccessorRef<'a> { Generated(&'a RepeatedFieldAccessorHolder), Dynamic(DynamicFieldDescriptorRef<'a>), } enum MapFieldAccessorRef<'a> { Generated(&'a MapFieldAccessorHolder), Dynamic(DynamicFieldDescriptorRef<'a>), } pub(crate) enum FieldDescriptorImplRef<'a> { Generated(&'static GeneratedFieldAccessor), Dynamic(DynamicFieldDescriptorRef<'a>), } #[cfg(test)] mod test { use std::collections::HashMap; use crate::descriptor::DescriptorProto; use crate::reflect::ReflectValueBox; use crate::well_known_types::struct_::Struct; use crate::well_known_types::struct_::Value; use crate::MessageFull; #[test] #[cfg_attr(miri, ignore)] fn display() { let field = DescriptorProto::descriptor() .field_by_name("enum_type") .unwrap(); assert_eq!( "google.protobuf.DescriptorProto.enum_type", field.to_string() ); } }