1 use protobuf_support::json_name::json_name; 2 3 use crate::descriptor::field_descriptor_proto::Type; 4 use crate::descriptor::FieldDescriptorProto; 5 use crate::descriptor::FileDescriptorProto; 6 use crate::owning_ref::OwningRef; 7 use crate::reflect::error::ReflectError; 8 use crate::reflect::field::protobuf_field_type::ProtobufFieldType; 9 use crate::reflect::file::building::FileDescriptorBuilding; 10 use crate::reflect::protobuf_type_box::ProtobufType; 11 use crate::reflect::EnumDescriptor; 12 use crate::reflect::EnumValueDescriptor; 13 use crate::reflect::FieldDescriptor; 14 use crate::reflect::FileDescriptor; 15 use crate::reflect::MessageDescriptor; 16 use crate::reflect::ReflectValueBox; 17 use crate::reflect::ReflectValueRef; 18 use crate::reflect::RuntimeType; 19 20 #[derive(Debug)] 21 pub(crate) enum ForwardProtobufTypeBox { 22 ProtobufTypeBox(ProtobufType), 23 CurrentFileEnum(usize), 24 CurrentFileMessage(usize), 25 } 26 27 impl ForwardProtobufTypeBox { message(message: MessageDescriptor) -> ForwardProtobufTypeBox28 pub(crate) fn message(message: MessageDescriptor) -> ForwardProtobufTypeBox { 29 ForwardProtobufTypeBox::ProtobufTypeBox(ProtobufType::message(message)) 30 } 31 enumeration(enumeration: EnumDescriptor) -> ForwardProtobufTypeBox32 pub(crate) fn enumeration(enumeration: EnumDescriptor) -> ForwardProtobufTypeBox { 33 ForwardProtobufTypeBox::ProtobufTypeBox(ProtobufType::enumeration(enumeration)) 34 } 35 from_proto_type(t: Type) -> ForwardProtobufTypeBox36 pub(crate) fn from_proto_type(t: Type) -> ForwardProtobufTypeBox { 37 ForwardProtobufTypeBox::ProtobufTypeBox(ProtobufType::from_proto_type(t)) 38 } 39 resolve(&self, file: &FileDescriptor) -> ProtobufType40 pub(crate) fn resolve(&self, file: &FileDescriptor) -> ProtobufType { 41 match self { 42 ForwardProtobufTypeBox::ProtobufTypeBox(t) => t.clone(), 43 ForwardProtobufTypeBox::CurrentFileMessage(m) => { 44 ProtobufType::message(MessageDescriptor::new(file.clone(), *m)) 45 } 46 ForwardProtobufTypeBox::CurrentFileEnum(m) => { 47 ProtobufType::enumeration(EnumDescriptor::new(file.clone(), *m)) 48 } 49 } 50 } 51 resolve_message(&self, file: &FileDescriptor) -> MessageDescriptor52 pub(crate) fn resolve_message(&self, file: &FileDescriptor) -> MessageDescriptor { 53 match self.resolve(file).runtime() { 54 RuntimeType::Message(m) => m.clone(), 55 _ => panic!("not message"), 56 } 57 } 58 } 59 60 #[derive(Debug)] 61 pub(crate) enum ForwardProtobufFieldType { 62 Singular(ForwardProtobufTypeBox), 63 Repeated(ForwardProtobufTypeBox), 64 Map(ForwardProtobufTypeBox, ForwardProtobufTypeBox), 65 } 66 67 impl ForwardProtobufFieldType { resolve(&self, file: &FileDescriptor) -> ProtobufFieldType68 pub(crate) fn resolve(&self, file: &FileDescriptor) -> ProtobufFieldType { 69 match self { 70 ForwardProtobufFieldType::Singular(t) => ProtobufFieldType::Singular(t.resolve(file)), 71 ForwardProtobufFieldType::Repeated(t) => ProtobufFieldType::Repeated(t.resolve(file)), 72 ForwardProtobufFieldType::Map(k, v) => { 73 ProtobufFieldType::Map(k.resolve(file), v.resolve(file)) 74 } 75 } 76 } 77 } 78 79 #[derive(Debug)] 80 pub(crate) enum FieldDefaultValue { 81 ReflectValueBox(ReflectValueBox), 82 Enum(usize), 83 } 84 85 #[derive(Debug)] 86 pub(crate) enum FieldKind { 87 MessageField( 88 /// Message index. 89 usize, 90 ), 91 Extension( 92 /// Message index or `None` for file. 93 Option<usize>, 94 ForwardProtobufTypeBox, 95 ), 96 } 97 98 #[derive(Debug)] 99 pub(crate) struct FieldIndex { 100 pub(crate) proto: OwningRef<FileDescriptorProto, FieldDescriptorProto>, 101 pub(crate) kind: FieldKind, 102 pub(crate) json_name: String, 103 pub(crate) field_type: ForwardProtobufFieldType, 104 pub(crate) default_value: Option<FieldDefaultValue>, 105 } 106 107 impl FieldIndex { enum_default_value( field: &FieldDescriptorProto, building: &FileDescriptorBuilding, ) -> crate::Result<FieldDefaultValue>108 fn enum_default_value( 109 field: &FieldDescriptorProto, 110 building: &FileDescriptorBuilding, 111 ) -> crate::Result<FieldDefaultValue> { 112 let en = building.find_enum(field.type_name()); 113 let (n, _) = match en 114 .value 115 .iter() 116 .enumerate() 117 .find(|(_n, v)| v.name() == field.default_value()) 118 { 119 Some(v) => v, 120 None => Err(ReflectError::CouldNotParseDefaultValueForField( 121 field.name().to_owned(), 122 ))?, 123 }; 124 Ok(FieldDefaultValue::Enum(n)) 125 } 126 parse_default_value( field: &FieldDescriptorProto, building: &FileDescriptorBuilding, ) -> crate::Result<FieldDefaultValue>127 fn parse_default_value( 128 field: &FieldDescriptorProto, 129 building: &FileDescriptorBuilding, 130 ) -> crate::Result<FieldDefaultValue> { 131 Ok(FieldDefaultValue::ReflectValueBox(match field.type_() { 132 Type::TYPE_GROUP | Type::TYPE_MESSAGE => { 133 return Err(ReflectError::CouldNotParseDefaultValueForField( 134 field.name().to_owned(), 135 ) 136 .into()); 137 } 138 Type::TYPE_ENUM => { 139 return Self::enum_default_value(field, building); 140 } 141 t => RuntimeType::from_proto_type(t) 142 .parse_proto_default_value(field.default_value()) 143 .map_err(|()| { 144 ReflectError::CouldNotParseDefaultValueForField(field.name().to_owned()) 145 })?, 146 })) 147 } 148 index( containing_message: Option<usize>, field: OwningRef<FileDescriptorProto, FieldDescriptorProto>, building: &FileDescriptorBuilding, ) -> crate::Result<FieldIndex>149 pub(crate) fn index( 150 containing_message: Option<usize>, 151 field: OwningRef<FileDescriptorProto, FieldDescriptorProto>, 152 building: &FileDescriptorBuilding, 153 ) -> crate::Result<FieldIndex> { 154 let default_value = if field.has_default_value() { 155 Some(Self::parse_default_value(&field, building)?) 156 } else { 157 None 158 }; 159 160 let json_name = if !field.json_name().is_empty() { 161 field.json_name().to_owned() 162 } else { 163 json_name(field.name()) 164 }; 165 166 let extendee = if field.has_extendee() { 167 Some(building.resolve_message(field.extendee())?) 168 } else { 169 None 170 }; 171 172 let kind = match (containing_message, extendee) { 173 (Some(m), None) => FieldKind::MessageField(m), 174 (m, Some(extendee)) => FieldKind::Extension(m, extendee), 175 (None, None) => panic!("field must be in a message or an extension"), 176 }; 177 178 let field_type = building.resolve_field_type(&field)?; 179 Ok(FieldIndex { 180 proto: field, 181 kind, 182 default_value, 183 json_name, 184 field_type, 185 }) 186 } 187 default_value<'a>(&'a self, field: &FieldDescriptor) -> ReflectValueRef<'a>188 pub(crate) fn default_value<'a>(&'a self, field: &FieldDescriptor) -> ReflectValueRef<'a> { 189 match &self.default_value { 190 Some(FieldDefaultValue::ReflectValueBox(v)) => v.as_value_ref(), 191 Some(FieldDefaultValue::Enum(v)) => match field.singular_runtime_type() { 192 RuntimeType::Enum(e) => { 193 let ev = EnumValueDescriptor::new(e.clone(), *v); 194 ReflectValueRef::from(ev) 195 } 196 t => panic!("wrong type {:?} for default value enum", t), 197 }, 198 None => field.singular_runtime_type().default_value_ref(), 199 } 200 } 201 } 202