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;
#[derive(PartialEq)]
pub enum ReflectFieldRef<'a> {
Optional(ReflectOptionalRef<'a>),
Repeated(ReflectRepeatedRef<'a>),
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<T: Sync>() {}
_assert_send_sync::<ReflectFieldRef<'a>>();
}
#[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,
)
}
_ => panic!("regular field"),
}
}
pub(crate) fn file_descriptor(&self) -> &FileDescriptor {
&self.file_descriptor
}
pub fn proto(&self) -> &FieldDescriptorProto {
&self.index().proto
}
pub fn name(&self) -> &str {
self.proto().name()
}
pub fn number(&self) -> i32 {
self.proto().number()
}
pub fn full_name(&self) -> String {
self.to_string()
}
pub fn containing_oneof_including_synthetic(&self) -> Option<OneofDescriptor> {
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
}
}
pub fn containing_oneof(&self) -> Option<OneofDescriptor> {
self.containing_oneof_including_synthetic()
.filter(|o| !o.is_synthetic())
}
fn _declaring_message(&self) -> Option<MessageDescriptor> {
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()?)),
}
}
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]
}
pub fn json_name(&self) -> &str {
&self.index().json_name
}
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,
}
}
pub fn is_required(&self) -> bool {
self.proto().label() == field_descriptor_proto::Label::LABEL_REQUIRED
}
pub fn is_repeated_or_map(&self) -> bool {
self.proto().label() == field_descriptor_proto::Label::LABEL_REPEATED
}
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 })
}
}
}
pub fn is_map(&self) -> bool {
match self.runtime_field_type() {
RuntimeFieldType::Map(..) => true,
_ => false,
}
}
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(),
}
}
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),
}
}
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),
}
}
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),
}
}
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,
}
}
pub fn singular_default_value(&self) -> ReflectValueRef {
self.index().default_value(self)
}
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),
}
}
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)
}
}
}
pub fn singular_runtime_type(&self) -> RuntimeType {
match self.runtime_field_type() {
RuntimeFieldType::Singular(s) => s,
_ => panic!("Not a singular field: {}", self),
}
}
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),
}
}
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();
}
}
pub(crate) fn protobuf_field_type(&self) -> ProtobufFieldType {
self.index().field_type.resolve(self.file_descriptor())
}
pub fn runtime_field_type(&self) -> RuntimeFieldType {
self.protobuf_field_type().runtime()
}
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),
}
}
pub fn get_singular<'a>(&self, m: &'a dyn MessageDyn) -> Option<ReflectValueRef<'a>> {
match self.get_reflect(m) {
ReflectFieldRef::Optional(o) => o.value(),
_ => panic!("not a singular field"),
}
}
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"),
}
}
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),
}
}
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"),
}
}
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()
);
}
}