prost_reflect/descriptor/
api.rs

1use std::{
2    borrow::Cow,
3    fmt, iter,
4    ops::{Range, RangeInclusive},
5    sync::Arc,
6};
7
8use prost::{
9    bytes::{Buf, BufMut},
10    encoding::{self, WireType},
11    DecodeError, EncodeError, Message,
12};
13use prost_types::{
14    DescriptorProto, EnumDescriptorProto, EnumValueDescriptorProto, FieldDescriptorProto,
15    FileDescriptorProto, FileDescriptorSet, MethodDescriptorProto, OneofDescriptorProto,
16    ServiceDescriptorProto,
17};
18
19use crate::{
20    descriptor::{
21        error::DescriptorErrorKind,
22        find_enum_proto, find_message_proto, tag, to_index,
23        types::{self, Options},
24        Definition, DefinitionKind, DescriptorIndex, EnumDescriptorInner, EnumValueDescriptorInner,
25        ExtensionDescriptorInner, FieldDescriptorInner, FileDescriptorInner, KindIndex,
26        MessageDescriptorInner, MethodDescriptorInner, OneofDescriptorInner,
27        ServiceDescriptorInner, MAP_ENTRY_KEY_NUMBER, MAP_ENTRY_VALUE_NUMBER,
28    },
29    Cardinality, DescriptorError, DescriptorPool, DynamicMessage, EnumDescriptor,
30    EnumValueDescriptor, ExtensionDescriptor, FieldDescriptor, FileDescriptor, Kind,
31    MessageDescriptor, MethodDescriptor, OneofDescriptor, ServiceDescriptor, Syntax, Value,
32};
33
34impl fmt::Debug for Syntax {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        match *self {
37            Syntax::Proto2 => write!(f, "proto2"),
38            Syntax::Proto3 => write!(f, "proto3"),
39        }
40    }
41}
42
43impl Kind {
44    fn new(pool: &DescriptorPool, kind: KindIndex) -> Self {
45        match kind {
46            KindIndex::Double => Kind::Double,
47            KindIndex::Float => Kind::Float,
48            KindIndex::Int64 => Kind::Int64,
49            KindIndex::Uint64 => Kind::Uint64,
50            KindIndex::Int32 => Kind::Int32,
51            KindIndex::Fixed64 => Kind::Fixed64,
52            KindIndex::Fixed32 => Kind::Fixed32,
53            KindIndex::Bool => Kind::Bool,
54            KindIndex::String => Kind::String,
55            KindIndex::Bytes => Kind::Bytes,
56            KindIndex::Uint32 => Kind::Uint32,
57            KindIndex::Sfixed32 => Kind::Sfixed32,
58            KindIndex::Sfixed64 => Kind::Sfixed64,
59            KindIndex::Sint32 => Kind::Sint32,
60            KindIndex::Sint64 => Kind::Sint64,
61            KindIndex::Message(index) | KindIndex::Group(index) => {
62                Kind::Message(MessageDescriptor {
63                    pool: pool.clone(),
64                    index,
65                })
66            }
67            KindIndex::Enum(index) => Kind::Enum(EnumDescriptor {
68                pool: pool.clone(),
69                index,
70            }),
71        }
72    }
73
74    /// Gets a reference to the [`MessageDescriptor`] if this is a message type,
75    /// or `None` otherwise.
76    pub fn as_message(&self) -> Option<&MessageDescriptor> {
77        match self {
78            Kind::Message(desc) => Some(desc),
79            _ => None,
80        }
81    }
82
83    /// Gets a reference to the [`EnumDescriptor`] if this is an enum type,
84    /// or `None` otherwise.
85    pub fn as_enum(&self) -> Option<&EnumDescriptor> {
86        match self {
87            Kind::Enum(desc) => Some(desc),
88            _ => None,
89        }
90    }
91
92    /// Returns the [`WireType`] used to encode this type.
93    ///
94    /// Note: The [`Kind::Message`] returns [` WireType::LengthDelimited`],
95    /// as [groups are deprecated](https://protobuf.dev/programming-guides/encoding/#groups).
96    pub fn wire_type(&self) -> WireType {
97        match self {
98            Kind::Double | Kind::Fixed64 | Kind::Sfixed64 => WireType::SixtyFourBit,
99            Kind::Float | Kind::Fixed32 | Kind::Sfixed32 => WireType::ThirtyTwoBit,
100            Kind::Enum(_)
101            | Kind::Int32
102            | Kind::Int64
103            | Kind::Uint32
104            | Kind::Uint64
105            | Kind::Sint32
106            | Kind::Sint64
107            | Kind::Bool => WireType::Varint,
108            Kind::String | Kind::Bytes | Kind::Message(_) => WireType::LengthDelimited,
109        }
110    }
111}
112
113impl fmt::Debug for Kind {
114    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115        match self {
116            Self::Double => write!(f, "double"),
117            Self::Float => write!(f, "float"),
118            Self::Int32 => write!(f, "int32"),
119            Self::Int64 => write!(f, "int64"),
120            Self::Uint32 => write!(f, "uint32"),
121            Self::Uint64 => write!(f, "uint64"),
122            Self::Sint32 => write!(f, "sint32"),
123            Self::Sint64 => write!(f, "sint64"),
124            Self::Fixed32 => write!(f, "fixed32"),
125            Self::Fixed64 => write!(f, "fixed64"),
126            Self::Sfixed32 => write!(f, "sfixed32"),
127            Self::Sfixed64 => write!(f, "sfixed64"),
128            Self::Bool => write!(f, "bool"),
129            Self::String => write!(f, "string"),
130            Self::Bytes => write!(f, "bytes"),
131            Self::Message(m) => write!(f, "{}", m.full_name()),
132            Self::Enum(e) => write!(f, "{}", e.full_name()),
133        }
134    }
135}
136
137impl DescriptorPool {
138    /// Creates a new, empty [`DescriptorPool`].
139    ///
140    /// For the common case of creating a `DescriptorPool` from a single [`FileDescriptorSet`], see
141    /// [`DescriptorPool::from_file_descriptor_set`] or [`DescriptorPool::decode`].
142    pub fn new() -> Self {
143        DescriptorPool::default()
144    }
145
146    /// Creates a [`DescriptorPool`] from a [`FileDescriptorSet`].
147    ///
148    /// A file descriptor set may be generated by running the protobuf compiler with the
149    /// `--descriptor_set_out` flag. If you are using [`prost-build`](https://crates.io/crates/prost-build),
150    /// then [`Config::file_descriptor_set_path`](https://docs.rs/prost-build/latest/prost_build/struct.Config.html#method..file_descriptor_set_path)
151    /// is a convenient way to generate it as part of your build.
152    pub fn from_file_descriptor_set(
153        file_descriptor_set: FileDescriptorSet,
154    ) -> Result<Self, DescriptorError> {
155        let mut pool = DescriptorPool::new();
156        pool.add_file_descriptor_set(file_descriptor_set)?;
157        Ok(pool)
158    }
159
160    /// Decodes and adds a set of file descriptors to the pool.
161    ///
162    /// A file descriptor set may be generated by running the protobuf compiler with the
163    /// `--descriptor_set_out` flag. If you are using [`prost-build`](https://crates.io/crates/prost-build),
164    /// then [`Config::file_descriptor_set_path`](https://docs.rs/prost-build/latest/prost_build/struct.Config.html#method..file_descriptor_set_path)
165    /// is a convenient way to generate it as part of your build.
166    ///
167    /// Unlike when using [`DescriptorPool::from_file_descriptor_set`], any extension options
168    /// defined in the file descriptors are preserved.
169    ///
170    /// # Errors
171    ///
172    /// Returns an error if the given bytes are not a valid protobuf-encoded file descriptor set, or if the descriptor set itself
173    /// is invalid. When using a file descriptor set generated by the protobuf compiler, this method will always succeed.
174    pub fn decode<B>(bytes: B) -> Result<Self, DescriptorError>
175    where
176        B: Buf,
177    {
178        let file_descriptor_set = types::FileDescriptorSet::decode(bytes).map_err(|err| {
179            DescriptorError::new(vec![DescriptorErrorKind::DecodeFileDescriptorSet { err }])
180        })?;
181
182        let mut pool = DescriptorPool::new();
183        pool.build_files(file_descriptor_set.file.into_iter())?;
184        Ok(pool)
185    }
186
187    /// Adds a new [`FileDescriptorSet`] to this [`DescriptorPool`].
188    ///
189    /// A file descriptor set may be generated by running the protobuf compiler with the
190    /// `--descriptor_set_out` flag. If you are using [`prost-build`](https://crates.io/crates/prost-build),
191    /// then [`Config::file_descriptor_set_path`](https://docs.rs/prost-build/latest/prost_build/struct.Config.html#method..file_descriptor_set_path)
192    /// is a convenient way to generate it as part of your build.
193    ///
194    /// Any duplicates of files already in the pool will be skipped. Note this may cause issues when trying to add two different versions of a file with the same name.
195    ///
196    /// # Errors
197    ///
198    /// Returns an error if the descriptor set is invalid, for example if it references types not yet added
199    /// to the pool. When using a file descriptor set generated by the protobuf compiler, this method will
200    /// always succeed.
201    pub fn add_file_descriptor_set(
202        &mut self,
203        file_descriptor_set: FileDescriptorSet,
204    ) -> Result<(), DescriptorError> {
205        self.add_file_descriptor_protos(file_descriptor_set.file)
206    }
207
208    /// Adds a collection of file descriptors to this pool.
209    ///
210    /// The file descriptors may be provided in any order, however all types referenced must be defined
211    /// either in one of the files provided, or in a file previously added to the pool.
212    ///
213    /// Any duplicates of files already in the pool will be skipped. Note this may cause issues when trying to add two different versions of a file with the same name.
214    ///
215    /// # Errors
216    ///
217    /// Returns an error if any of the given file descriptor is invalid, for example if they reference
218    /// types not yet added to the pool.
219    pub fn add_file_descriptor_protos<I>(&mut self, files: I) -> Result<(), DescriptorError>
220    where
221        I: IntoIterator<Item = FileDescriptorProto>,
222    {
223        self.build_files(
224            files
225                .into_iter()
226                .map(types::FileDescriptorProto::from_prost),
227        )
228    }
229
230    /// Add a single file descriptor to the pool.
231    ///
232    /// All types referenced by the file must be defined either in the file itself, or in a file
233    /// previously added to the pool.
234    ///
235    /// If the file is a duplicate of a file already in the pool, it will be skipped. Note this may cause issues when trying to add two different versions of a file with the same name.
236    ///
237    /// # Errors
238    ///
239    /// Returns an error if the given file descriptor is invalid, for example if it references types not yet added
240    /// to the pool.
241    pub fn add_file_descriptor_proto(
242        &mut self,
243        file: FileDescriptorProto,
244    ) -> Result<(), DescriptorError> {
245        self.add_file_descriptor_protos(iter::once(file))
246    }
247
248    /// Decode and add a single file descriptor to the pool.
249    ///
250    /// All types referenced by the file must be defined either in the file itself, or in a file
251    /// previously added to the pool.
252    ///
253    /// Unlike when using [`add_file_descriptor_proto()`][DescriptorPool::add_file_descriptor_proto], any extension options
254    /// defined in the file descriptor are preserved.
255    ///
256    /// If the file is a duplicate of a file already in the pool, it will be skipped. Note this may cause issues when trying to add two different versions of a file with the same name.
257    ///
258    /// # Errors
259    ///
260    /// Returns an error if the given bytes are not a valid protobuf-encoded file descriptor, or if the file descriptor itself
261    /// is invalid, for example if it references types not yet added to the pool.
262    pub fn decode_file_descriptor_proto<B>(&mut self, bytes: B) -> Result<(), DescriptorError>
263    where
264        B: Buf,
265    {
266        let file = types::FileDescriptorProto::decode(bytes).map_err(|err| {
267            DescriptorError::new(vec![DescriptorErrorKind::DecodeFileDescriptorSet { err }])
268        })?;
269
270        self.build_files(iter::once(file))
271    }
272
273    /// Decode and add a set of file descriptors to the pool.
274    ///
275    /// A file descriptor set may be generated by running the protobuf compiler with the
276    /// `--descriptor_set_out` flag. If you are using [`prost-build`](https://crates.io/crates/prost-build),
277    /// then [`Config::file_descriptor_set_path`](https://docs.rs/prost-build/latest/prost_build/struct.Config.html#method..file_descriptor_set_path)
278    /// is a convenient way to generate it as part of your build.
279    ///
280    /// Unlike when using [`add_file_descriptor_set()`][DescriptorPool::add_file_descriptor_set], any extension options
281    /// defined in the file descriptors are preserved.
282    ///
283    /// Any duplicates of files already in the pool will be skipped. Note this may cause issues when trying to add two different versions of a file with the same name.
284    ///
285    /// # Errors
286    ///
287    /// Returns an error if the given bytes are not a valid protobuf-encoded file descriptor set, or if the descriptor set itself
288    /// is invalid. When using a file descriptor set generated by the protobuf compiler, this method will always succeed.
289    pub fn decode_file_descriptor_set<B>(&mut self, bytes: B) -> Result<(), DescriptorError>
290    where
291        B: Buf,
292    {
293        let file = types::FileDescriptorSet::decode(bytes).map_err(|err| {
294            DescriptorError::new(vec![DescriptorErrorKind::DecodeFileDescriptorSet { err }])
295        })?;
296
297        self.build_files(file.file)
298    }
299
300    /// Gets an iterator over the file descriptors added to this pool.
301    pub fn files(&self) -> impl ExactSizeIterator<Item = FileDescriptor> + '_ {
302        indices(&self.inner.files).map(|index| FileDescriptor {
303            pool: self.clone(),
304            index,
305        })
306    }
307
308    /// Gets a file descriptor by its name, or `None` if no such file has been added.
309    pub fn get_file_by_name(&self, name: &str) -> Option<FileDescriptor> {
310        if let Some(&index) = self.inner.file_names.get(name) {
311            Some(FileDescriptor {
312                pool: self.clone(),
313                index,
314            })
315        } else {
316            None
317        }
318    }
319
320    /// Gets a iterator over the raw [`FileDescriptorProto`] instances wrapped by this [`DescriptorPool`].
321    pub fn file_descriptor_protos(
322        &self,
323    ) -> impl ExactSizeIterator<Item = &FileDescriptorProto> + '_ {
324        indices(&self.inner.files).map(|index| &self.inner.files[index as usize].prost)
325    }
326
327    /// Encodes the files contained within this [`DescriptorPool`] to their byte representation.
328    ///
329    /// The encoded message is equivalent to a [`FileDescriptorSet`], however also includes
330    /// any extension options that were defined.
331    pub fn encode<B>(&self, buf: B) -> Result<(), EncodeError>
332    where
333        B: BufMut,
334    {
335        use prost::encoding::{encoded_len_varint, DecodeContext};
336
337        struct FileDescriptorSet<'a> {
338            files: &'a [FileDescriptorInner],
339        }
340
341        impl fmt::Debug for FileDescriptorSet<'_> {
342            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343                f.debug_struct("FileDescriptorSet").finish_non_exhaustive()
344            }
345        }
346
347        impl Message for FileDescriptorSet<'_> {
348            fn encode_raw(&self, buf: &mut impl BufMut)
349            where
350                Self: Sized,
351            {
352                for file in self.files {
353                    encoding::message::encode(
354                        tag::file_descriptor_set::FILE as u32,
355                        &file.raw,
356                        buf,
357                    );
358                }
359            }
360
361            fn encoded_len(&self) -> usize {
362                encoding::key_len(tag::file_descriptor_set::FILE as u32) * self.files.len()
363                    + self
364                        .files
365                        .iter()
366                        .map(|f| &f.raw)
367                        .map(Message::encoded_len)
368                        .map(|len| len + encoded_len_varint(len as u64))
369                        .sum::<usize>()
370            }
371
372            fn merge_field(
373                &mut self,
374                _: u32,
375                _: WireType,
376                _: &mut impl Buf,
377                _: DecodeContext,
378            ) -> Result<(), DecodeError>
379            where
380                Self: Sized,
381            {
382                unimplemented!()
383            }
384
385            fn clear(&mut self) {
386                unimplemented!()
387            }
388        }
389
390        let mut buf = buf;
391        FileDescriptorSet {
392            files: &self.inner.files,
393        }
394        .encode(&mut buf)
395    }
396
397    /// Encodes the files contained within this [`DescriptorPool`] to a newly allocated buffer.
398    ///
399    /// The encoded message is equivalent to a [`FileDescriptorSet`], however also includes
400    /// any extension options that were defined.
401    pub fn encode_to_vec(&self) -> Vec<u8> {
402        let mut buf = Vec::new();
403        self.encode(&mut buf).expect("vec should have capacity");
404        buf
405    }
406
407    /// Gets an iterator over the services defined in these protobuf files.
408    pub fn services(&self) -> impl ExactSizeIterator<Item = ServiceDescriptor> + '_ {
409        indices(&self.inner.services).map(|index| ServiceDescriptor {
410            pool: self.clone(),
411            index,
412        })
413    }
414
415    /// Gets an iterator over all message types defined in these protobuf files.
416    ///
417    /// The iterator includes nested messages defined in another message.
418    pub fn all_messages(&self) -> impl ExactSizeIterator<Item = MessageDescriptor> + '_ {
419        indices(&self.inner.messages).map(|index| MessageDescriptor {
420            pool: self.clone(),
421            index,
422        })
423    }
424
425    /// Gets an iterator over all enum types defined in these protobuf files.
426    ///
427    /// The iterator includes nested enums defined in another message.
428    pub fn all_enums(&self) -> impl ExactSizeIterator<Item = EnumDescriptor> + '_ {
429        indices(&self.inner.enums).map(|index| EnumDescriptor {
430            pool: self.clone(),
431            index,
432        })
433    }
434
435    /// Gets an iterator over all extension fields defined in these protobuf files.
436    ///
437    /// The iterator includes nested extension fields defined in another message.
438    pub fn all_extensions(&self) -> impl ExactSizeIterator<Item = ExtensionDescriptor> + '_ {
439        indices(&self.inner.extensions).map(|index| ExtensionDescriptor {
440            pool: self.clone(),
441            index,
442        })
443    }
444
445    /// Gets a [`MessageDescriptor`] by its fully qualified name, for example `my.package.MessageName`.
446    pub fn get_message_by_name(&self, name: &str) -> Option<MessageDescriptor> {
447        match self.inner.get_by_name(name) {
448            Some(&Definition {
449                kind: DefinitionKind::Message(index),
450                ..
451            }) => Some(MessageDescriptor {
452                pool: self.clone(),
453                index,
454            }),
455            _ => None,
456        }
457    }
458
459    /// Gets an [`EnumDescriptor`] by its fully qualified name, for example `my.package.EnumName`.
460    pub fn get_enum_by_name(&self, name: &str) -> Option<EnumDescriptor> {
461        match self.inner.get_by_name(name) {
462            Some(&Definition {
463                kind: DefinitionKind::Enum(index),
464                ..
465            }) => Some(EnumDescriptor {
466                pool: self.clone(),
467                index,
468            }),
469            _ => None,
470        }
471    }
472
473    /// Gets an [`ExtensionDescriptor`] by its fully qualified name, for example `my.package.my_extension`.
474    pub fn get_extension_by_name(&self, name: &str) -> Option<ExtensionDescriptor> {
475        match self.inner.get_by_name(name) {
476            Some(&Definition {
477                kind: DefinitionKind::Extension(index),
478                ..
479            }) => Some(ExtensionDescriptor {
480                pool: self.clone(),
481                index,
482            }),
483            _ => None,
484        }
485    }
486
487    /// Gets an [`ServiceDescriptor`] by its fully qualified name, for example `my.package.MyService`.
488    pub fn get_service_by_name(&self, name: &str) -> Option<ServiceDescriptor> {
489        match self.inner.get_by_name(name) {
490            Some(&Definition {
491                kind: DefinitionKind::Service(index),
492                ..
493            }) => Some(ServiceDescriptor {
494                pool: self.clone(),
495                index,
496            }),
497            _ => None,
498        }
499    }
500}
501
502impl fmt::Debug for DescriptorPool {
503    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
504        f.debug_struct("DescriptorPool")
505            .field("files", &debug_fmt_iter(self.files()))
506            .field("services", &debug_fmt_iter(self.services()))
507            .field("all_messages", &debug_fmt_iter(self.all_messages()))
508            .field("all_enums", &debug_fmt_iter(self.all_enums()))
509            .field("all_extensions", &debug_fmt_iter(self.all_extensions()))
510            .finish()
511    }
512}
513
514impl PartialEq for DescriptorPool {
515    fn eq(&self, other: &Self) -> bool {
516        Arc::ptr_eq(&self.inner, &other.inner)
517    }
518}
519
520impl Eq for DescriptorPool {}
521
522impl FileDescriptor {
523    /// Create a new [`FileDescriptor`] referencing the file at `index` within the given [`DescriptorPool`].
524    ///
525    /// # Panics
526    ///
527    /// Panics if `index` is out-of-bounds.
528    pub fn new(descriptor_pool: DescriptorPool, index: usize) -> Self {
529        debug_assert!(index < descriptor_pool.files().len());
530        FileDescriptor {
531            pool: descriptor_pool,
532            index: to_index(index),
533        }
534    }
535
536    /// Gets a reference to the [`DescriptorPool`] this file is included in.
537    pub fn parent_pool(&self) -> &DescriptorPool {
538        &self.pool
539    }
540
541    /// Gets the unique name of this file relative to the root of the source tree,
542    /// e.g. `path/to/my_package.proto`.
543    pub fn name(&self) -> &str {
544        self.inner().prost.name()
545    }
546
547    /// Gets the name of the package specifier for a file, e.g. `my.package`.
548    ///
549    /// If no package name is set, an empty string is returned.
550    pub fn package_name(&self) -> &str {
551        self.inner().prost.package()
552    }
553
554    /// Gets the index of this file within the parent [`DescriptorPool`].
555    pub fn index(&self) -> usize {
556        self.index as usize
557    }
558
559    /// Gets the syntax of this protobuf file.
560    pub fn syntax(&self) -> Syntax {
561        self.inner().syntax
562    }
563
564    /// Gets the dependencies of this file.
565    ///
566    /// This corresponds to the [`FileDescriptorProto::dependency`] field.
567    pub fn dependencies(&self) -> impl ExactSizeIterator<Item = FileDescriptor> + '_ {
568        let pool = self.parent_pool();
569        self.file_descriptor_proto()
570            .dependency
571            .iter()
572            .map(|name| pool.get_file_by_name(name).expect("file not found"))
573    }
574
575    /// Gets the public dependencies of this file.
576    ///
577    /// This corresponds to the [`FileDescriptorProto::public_dependency`] field.
578    pub fn public_dependencies(&self) -> impl ExactSizeIterator<Item = FileDescriptor> + '_ {
579        let pool = self.parent_pool();
580        let raw = self.file_descriptor_proto();
581        raw.public_dependency.iter().map(|&index| {
582            pool.get_file_by_name(&raw.dependency[index as usize])
583                .expect("file not found")
584        })
585    }
586
587    /// Gets the top-level message types defined within this file.
588    ///
589    /// This does not include nested messages defined within another message.
590    pub fn messages(&self) -> impl ExactSizeIterator<Item = MessageDescriptor> + '_ {
591        let pool = self.parent_pool();
592        let raw_file = self.file_descriptor_proto();
593        raw_file.message_type.iter().map(move |raw_message| {
594            pool.get_message_by_name(join_name(raw_file.package(), raw_message.name()).as_ref())
595                .expect("message not found")
596        })
597    }
598
599    /// Gets the top-level enum types defined within this file.
600    ///
601    /// This does not include nested enums defined within another message.
602    pub fn enums(&self) -> impl ExactSizeIterator<Item = EnumDescriptor> + '_ {
603        let pool = self.parent_pool();
604        let raw_file = self.file_descriptor_proto();
605        raw_file.enum_type.iter().map(move |raw_enum| {
606            pool.get_enum_by_name(join_name(raw_file.package(), raw_enum.name()).as_ref())
607                .expect("enum not found")
608        })
609    }
610
611    /// Gets the top-level extension fields defined within this file.
612    ///
613    /// This does not include nested extensions defined within another message.
614    pub fn extensions(&self) -> impl ExactSizeIterator<Item = ExtensionDescriptor> + '_ {
615        let pool = self.parent_pool();
616        let raw_file = self.file_descriptor_proto();
617        raw_file.extension.iter().map(move |raw_extension| {
618            pool.get_extension_by_name(join_name(raw_file.package(), raw_extension.name()).as_ref())
619                .expect("extension not found")
620        })
621    }
622
623    /// Gets the services defined within this file.
624    pub fn services(&self) -> impl ExactSizeIterator<Item = ServiceDescriptor> + '_ {
625        let pool = self.parent_pool();
626        let raw_file = self.file_descriptor_proto();
627        raw_file.service.iter().map(move |raw_service| {
628            pool.get_service_by_name(join_name(raw_file.package(), raw_service.name()).as_ref())
629                .expect("service not found")
630        })
631    }
632
633    /// Gets a reference to the raw [`FileDescriptorProto`] wrapped by this [`FileDescriptor`].
634    pub fn file_descriptor_proto(&self) -> &FileDescriptorProto {
635        &self.inner().prost
636    }
637
638    /// Encodes this file descriptor to its byte representation.
639    ///
640    /// The encoded message is equivalent to a [`FileDescriptorProto`], however also includes
641    /// any extension options that were defined.
642    pub fn encode<B>(&self, buf: B) -> Result<(), EncodeError>
643    where
644        B: BufMut,
645    {
646        let mut buf = buf;
647        self.inner().raw.encode(&mut buf)
648    }
649
650    /// Encodes this file descriptor to a newly allocated buffer.
651    ///
652    /// The encoded message is equivalent to a [`FileDescriptorProto`], however also includes
653    /// any extension options that were defined.
654    pub fn encode_to_vec(&self) -> Vec<u8> {
655        let mut buf = Vec::new();
656        self.encode(&mut buf).expect("vec should have capacity");
657        buf
658    }
659
660    /// Decodes the options defined for this [`FileDescriptor`], including any extension options.
661    pub fn options(&self) -> DynamicMessage {
662        decode_options(
663            self.parent_pool(),
664            "google.protobuf.FileOptions",
665            &self.inner().raw.options,
666        )
667    }
668
669    fn inner(&self) -> &FileDescriptorInner {
670        &self.pool.inner.files[self.index as usize]
671    }
672}
673
674impl fmt::Debug for FileDescriptor {
675    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
676        f.debug_struct("FileDescriptor")
677            .field("name", &self.name())
678            .field("package_name", &self.package_name())
679            .finish()
680    }
681}
682
683impl MessageDescriptor {
684    /// Gets a reference to the [`DescriptorPool`] this message is defined in.
685    pub fn parent_pool(&self) -> &DescriptorPool {
686        &self.pool
687    }
688
689    /// Gets the [`FileDescriptor`] this message is defined in.
690    pub fn parent_file(&self) -> FileDescriptor {
691        FileDescriptor {
692            pool: self.pool.clone(),
693            index: self.inner().id.file,
694        }
695    }
696
697    /// Gets the parent message type if this message type is nested inside a another message, or `None` otherwise
698    pub fn parent_message(&self) -> Option<MessageDescriptor> {
699        self.inner().parent.map(|index| MessageDescriptor {
700            pool: self.pool.clone(),
701            index,
702        })
703    }
704
705    /// Gets the short name of the message type, e.g. `MyMessage`.
706    pub fn name(&self) -> &str {
707        self.inner().id.name()
708    }
709
710    /// Gets the full name of the message type, e.g. `my.package.MyMessage`.
711    pub fn full_name(&self) -> &str {
712        self.inner().id.full_name()
713    }
714
715    /// Gets the name of the package this message type is defined in, e.g. `my.package`.
716    ///
717    /// If no package name is set, an empty string is returned.
718    pub fn package_name(&self) -> &str {
719        self.raw_file().package()
720    }
721
722    /// Gets the path where this message is defined within the [`FileDescriptorProto`][FileDescriptorProto], e.g. `[4, 0]`.
723    ///
724    /// See [`path`][prost_types::source_code_info::Location::path] for more details on the structure of the path.
725    pub fn path(&self) -> &[i32] {
726        &self.inner().id.path
727    }
728
729    /// Gets a reference to the [`FileDescriptorProto`] in which this message is defined.
730    pub fn parent_file_descriptor_proto(&self) -> &FileDescriptorProto {
731        &self.pool.inner.files[self.inner().id.file as usize].prost
732    }
733
734    /// Gets a reference to the raw [`DescriptorProto`] wrapped by this [`MessageDescriptor`].
735    pub fn descriptor_proto(&self) -> &DescriptorProto {
736        find_message_proto_prost(self.parent_file_descriptor_proto(), self.path())
737    }
738
739    /// Decodes the options defined for this [`MessageDescriptor`], including any extension options.
740    pub fn options(&self) -> DynamicMessage {
741        decode_options(
742            self.parent_pool(),
743            "google.protobuf.MessageOptions",
744            &self.raw().options,
745        )
746    }
747
748    /// Gets an iterator yielding a [`FieldDescriptor`] for each field defined in this message.
749    pub fn fields(&self) -> impl ExactSizeIterator<Item = FieldDescriptor> + '_ {
750        self.inner()
751            .field_numbers
752            .values()
753            .map(|&index| FieldDescriptor {
754                message: self.clone(),
755                index,
756            })
757    }
758
759    pub(crate) fn fields_in_index_order(
760        &self,
761    ) -> impl ExactSizeIterator<Item = FieldDescriptor> + '_ {
762        self.inner()
763            .fields
764            .iter()
765            .enumerate()
766            .map(|(index, _)| FieldDescriptor {
767                message: self.clone(),
768                index: index as u32,
769            })
770    }
771
772    /// Gets an iterator yielding a [`OneofDescriptor`] for each oneof field defined in this message.
773    pub fn oneofs(&self) -> impl ExactSizeIterator<Item = OneofDescriptor> + '_ {
774        indices(&self.inner().oneofs).map(|index| OneofDescriptor {
775            message: self.clone(),
776            index,
777        })
778    }
779
780    /// Gets the nested message types defined within this message.
781    pub fn child_messages(&self) -> impl ExactSizeIterator<Item = MessageDescriptor> + '_ {
782        let pool = self.parent_pool();
783        let namespace = self.full_name();
784        let raw_message = self.descriptor_proto();
785        raw_message.nested_type.iter().map(move |raw_message| {
786            pool.get_message_by_name(join_name(namespace, raw_message.name()).as_ref())
787                .expect("message not found")
788        })
789    }
790
791    /// Gets the nested enum types defined within this message.
792    pub fn child_enums(&self) -> impl ExactSizeIterator<Item = EnumDescriptor> + '_ {
793        let pool = self.parent_pool();
794        let namespace = self.full_name();
795        let raw_message = self.descriptor_proto();
796        raw_message.enum_type.iter().map(move |raw_enum| {
797            pool.get_enum_by_name(join_name(namespace, raw_enum.name()).as_ref())
798                .expect("enum not found")
799        })
800    }
801
802    /// Gets the nested extension fields defined within this message.
803    ///
804    /// Note this only returns extensions defined nested within this message. See
805    /// [`MessageDescriptor::extensions`] to get fields defined anywhere that extend this message.
806    pub fn child_extensions(&self) -> impl ExactSizeIterator<Item = ExtensionDescriptor> + '_ {
807        let pool = self.parent_pool();
808        let namespace = self.full_name();
809        let raw_message = self.descriptor_proto();
810        raw_message.extension.iter().map(move |raw_extension| {
811            pool.get_extension_by_name(join_name(namespace, raw_extension.name()).as_ref())
812                .expect("extension not found")
813        })
814    }
815
816    /// Gets an iterator over all extensions to this message defined in the parent [`DescriptorPool`].
817    ///
818    /// Note this iterates over extension fields defined anywhere which extend this message. See
819    /// [`MessageDescriptor::child_extensions`] to just get extensions defined nested within this message.
820    pub fn extensions(&self) -> impl ExactSizeIterator<Item = ExtensionDescriptor> + '_ {
821        self.inner()
822            .extensions
823            .iter()
824            .map(|&index| ExtensionDescriptor {
825                pool: self.parent_pool().clone(),
826                index,
827            })
828    }
829
830    /// Gets a [`FieldDescriptor`] with the given number, or `None` if no such field exists.
831    pub fn get_field(&self, number: u32) -> Option<FieldDescriptor> {
832        self.inner()
833            .field_numbers
834            .get(&number)
835            .map(|&index| FieldDescriptor {
836                message: self.clone(),
837                index,
838            })
839    }
840
841    /// Gets a [`FieldDescriptor`] with the given name, or `None` if no such field exists.
842    pub fn get_field_by_name(&self, name: &str) -> Option<FieldDescriptor> {
843        self.inner()
844            .field_names
845            .get(name)
846            .map(|&index| FieldDescriptor {
847                message: self.clone(),
848                index,
849            })
850    }
851
852    /// Gets a [`FieldDescriptor`] with the given JSON name, or `None` if no such field exists.
853    pub fn get_field_by_json_name(&self, json_name: &str) -> Option<FieldDescriptor> {
854        self.inner()
855            .field_json_names
856            .get(json_name)
857            .map(|&index| FieldDescriptor {
858                message: self.clone(),
859                index,
860            })
861    }
862
863    /// Returns `true` if this is an auto-generated message type to
864    /// represent the entry type for a map field.
865    //
866    /// If this method returns `true`, [`fields`][Self::fields] is guaranteed to
867    /// yield the following two fields:
868    ///
869    /// * A "key" field with a field number of 1
870    /// * A "value" field with a field number of 2
871    ///
872    /// See [`map_entry_key_field`][MessageDescriptor::map_entry_key_field] and
873    /// [`map_entry_value_field`][MessageDescriptor::map_entry_value_field] for more a convenient way
874    /// to get these fields.
875    pub fn is_map_entry(&self) -> bool {
876        self.raw()
877            .options
878            .as_ref()
879            .map(|o| o.value.map_entry())
880            .unwrap_or(false)
881    }
882
883    /// If this is a [map entry](MessageDescriptor::is_map_entry), returns a [`FieldDescriptor`] for the key.
884    ///
885    /// # Panics
886    ///
887    /// This method may panic if [`is_map_entry`][MessageDescriptor::is_map_entry] returns `false`.
888    pub fn map_entry_key_field(&self) -> FieldDescriptor {
889        debug_assert!(self.is_map_entry());
890        self.get_field(MAP_ENTRY_KEY_NUMBER)
891            .expect("map entry should have key field")
892    }
893
894    /// If this is a [map entry](MessageDescriptor::is_map_entry), returns a [`FieldDescriptor`] for the value.
895    ///
896    /// # Panics
897    ///
898    /// This method may panic if [`is_map_entry`][MessageDescriptor::is_map_entry] returns `false`.
899    pub fn map_entry_value_field(&self) -> FieldDescriptor {
900        debug_assert!(self.is_map_entry());
901        self.get_field(MAP_ENTRY_VALUE_NUMBER)
902            .expect("map entry should have value field")
903    }
904
905    /// Gets an iterator over reserved field number ranges in this message.
906    pub fn reserved_ranges(&self) -> impl ExactSizeIterator<Item = Range<u32>> + '_ {
907        self.raw()
908            .reserved_range
909            .iter()
910            .map(|n| (n.start() as u32)..(n.end() as u32))
911    }
912
913    /// Gets an iterator over reserved field names in this message.
914    pub fn reserved_names(&self) -> impl ExactSizeIterator<Item = &str> + '_ {
915        self.raw().reserved_name.iter().map(|n| n.as_ref())
916    }
917
918    /// Gets an iterator over extension field number ranges in this message.
919    pub fn extension_ranges(&self) -> impl ExactSizeIterator<Item = Range<u32>> + '_ {
920        self.raw()
921            .extension_range
922            .iter()
923            .map(|n| (n.start() as u32)..(n.end() as u32))
924    }
925
926    /// Gets an extension to this message by its number, or `None` if no such extension exists.
927    pub fn get_extension(&self, number: u32) -> Option<ExtensionDescriptor> {
928        self.extensions().find(|ext| ext.number() == number)
929    }
930
931    /// Gets an extension to this message by its full name (e.g. `my.package.my_extension`), or `None` if no such extension exists.
932    pub fn get_extension_by_full_name(&self, name: &str) -> Option<ExtensionDescriptor> {
933        self.extensions().find(|ext| ext.full_name() == name)
934    }
935
936    /// Gets an extension to this message by its JSON name (e.g. `[my.package.my_extension]`), or `None` if no such extension exists.
937    pub fn get_extension_by_json_name(&self, name: &str) -> Option<ExtensionDescriptor> {
938        self.extensions().find(|ext| ext.json_name() == name)
939    }
940
941    fn inner(&self) -> &MessageDescriptorInner {
942        &self.pool.inner.messages[self.index as usize]
943    }
944
945    fn raw(&self) -> &types::DescriptorProto {
946        find_message_proto(self.raw_file(), self.path())
947    }
948
949    fn raw_file(&self) -> &types::FileDescriptorProto {
950        &self.pool.inner.files[self.inner().id.file as usize].raw
951    }
952}
953
954impl fmt::Debug for MessageDescriptor {
955    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
956        f.debug_struct("MessageDescriptor")
957            .field("name", &self.name())
958            .field("full_name", &self.full_name())
959            .field("is_map_entry", &self.is_map_entry())
960            .field("fields", &debug_fmt_iter(self.fields()))
961            .field("oneofs", &debug_fmt_iter(self.oneofs()))
962            .finish()
963    }
964}
965
966impl FieldDescriptor {
967    /// Gets a reference to the [`DescriptorPool`] this field is defined in.
968    pub fn parent_pool(&self) -> &DescriptorPool {
969        self.message.parent_pool()
970    }
971
972    /// Gets the [`FileDescriptor`] this field is defined in.
973    pub fn parent_file(&self) -> FileDescriptor {
974        self.message.parent_file()
975    }
976
977    /// Gets a reference to the [`MessageDescriptor`] this field is defined in.
978    pub fn parent_message(&self) -> &MessageDescriptor {
979        &self.message
980    }
981
982    /// Gets the short name of the message type, e.g. `my_field`.
983    pub fn name(&self) -> &str {
984        self.inner().id.name()
985    }
986
987    /// Gets the full name of the message field, e.g. `my.package.MyMessage.my_field`.
988    pub fn full_name(&self) -> &str {
989        self.inner().id.full_name()
990    }
991
992    /// Gets the path where this message field is defined within the [`FileDescriptorProto`][FileDescriptorProto], e.g. `[4, 0, 2, 0]`.
993    ///
994    /// See [`path`][prost_types::source_code_info::Location::path] for more details on the structure of the path.
995    pub fn path(&self) -> &[i32] {
996        &self.inner().id.path
997    }
998
999    /// Gets a reference to the raw [`FieldDescriptorProto`] wrapped by this [`FieldDescriptor`].
1000    pub fn field_descriptor_proto(&self) -> &FieldDescriptorProto {
1001        &self.parent_message().descriptor_proto().field[*self.path().last().unwrap() as usize]
1002    }
1003
1004    /// Decodes the options defined for this [`FieldDescriptor`], including any extension options.
1005    pub fn options(&self) -> DynamicMessage {
1006        decode_options(
1007            self.parent_pool(),
1008            "google.protobuf.FieldOptions",
1009            &self.raw().options,
1010        )
1011    }
1012
1013    /// Gets the unique number for this message field.
1014    pub fn number(&self) -> u32 {
1015        self.inner().number
1016    }
1017
1018    /// Gets the name used for JSON serialization.
1019    ///
1020    /// This is usually the camel-cased form of the field name, unless
1021    /// another value is set in the proto file.
1022    pub fn json_name(&self) -> &str {
1023        &self.inner().json_name
1024    }
1025
1026    /// Whether this field is encoded using the proto2 group encoding.
1027    pub fn is_group(&self) -> bool {
1028        matches!(self.inner().kind, KindIndex::Group(_))
1029    }
1030
1031    /// Whether this field is a list type.
1032    ///
1033    /// Equivalent to checking that the cardinality is `Repeated` and that
1034    /// [`is_map`][Self::is_map] returns `false`.
1035    pub fn is_list(&self) -> bool {
1036        self.cardinality() == Cardinality::Repeated && !self.is_map()
1037    }
1038
1039    /// Whether this field is a map type.
1040    ///
1041    /// Equivalent to checking that the cardinality is `Repeated` and that
1042    /// the field type is a message where [`is_map_entry`][MessageDescriptor::is_map_entry]
1043    /// returns `true`.
1044    pub fn is_map(&self) -> bool {
1045        self.cardinality() == Cardinality::Repeated
1046            && match self.kind() {
1047                Kind::Message(message) => message.is_map_entry(),
1048                _ => false,
1049            }
1050    }
1051
1052    /// Whether this field is a list encoded using [packed encoding](https://developers.google.com/protocol-buffers/docs/encoding#packed).
1053    pub fn is_packed(&self) -> bool {
1054        self.inner().is_packed
1055    }
1056
1057    /// The cardinality of this field.
1058    pub fn cardinality(&self) -> Cardinality {
1059        self.inner().cardinality
1060    }
1061
1062    /// Whether this field supports distinguishing between an unpopulated field and
1063    /// the default value.
1064    ///
1065    /// For proto2 messages this returns `true` for all non-repeated fields.
1066    /// For proto3 this returns `true` for message fields, and fields contained
1067    /// in a `oneof`.
1068    pub fn supports_presence(&self) -> bool {
1069        self.inner().supports_presence
1070    }
1071
1072    /// Gets the [`Kind`] of this field.
1073    pub fn kind(&self) -> Kind {
1074        Kind::new(self.parent_pool(), self.inner().kind)
1075    }
1076
1077    /// Gets a [`OneofDescriptor`] representing the oneof containing this field,
1078    /// or `None` if this field is not contained in a oneof.
1079    pub fn containing_oneof(&self) -> Option<OneofDescriptor> {
1080        self.inner().oneof.map(|index| OneofDescriptor {
1081            message: self.message.clone(),
1082            index,
1083        })
1084    }
1085
1086    pub(crate) fn default_value(&self) -> Option<&Value> {
1087        self.inner().default.as_ref()
1088    }
1089
1090    pub(crate) fn is_packable(&self) -> bool {
1091        self.inner().kind.is_packable()
1092    }
1093
1094    fn inner(&self) -> &FieldDescriptorInner {
1095        &self.message.inner().fields[self.index as usize]
1096    }
1097
1098    fn raw(&self) -> &types::FieldDescriptorProto {
1099        &self.message.raw().field[self.index as usize]
1100    }
1101}
1102
1103impl fmt::Debug for FieldDescriptor {
1104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1105        f.debug_struct("FieldDescriptor")
1106            .field("name", &self.name())
1107            .field("full_name", &self.full_name())
1108            .field("json_name", &self.json_name())
1109            .field("number", &self.number())
1110            .field("kind", &self.kind())
1111            .field("cardinality", &self.cardinality())
1112            .field(
1113                "containing_oneof",
1114                &self.containing_oneof().map(|o| o.name().to_owned()),
1115            )
1116            .field("default_value", &self.default_value())
1117            .field("is_group", &self.is_group())
1118            .field("is_list", &self.is_list())
1119            .field("is_map", &self.is_map())
1120            .field("is_packed", &self.is_packed())
1121            .field("supports_presence", &self.supports_presence())
1122            .finish()
1123    }
1124}
1125
1126impl ExtensionDescriptor {
1127    /// Gets a reference to the [`DescriptorPool`] this extension field is defined in.
1128    pub fn parent_pool(&self) -> &DescriptorPool {
1129        &self.pool
1130    }
1131
1132    /// Gets the [`FileDescriptor`] this extension field is defined in.
1133    pub fn parent_file(&self) -> FileDescriptor {
1134        FileDescriptor {
1135            pool: self.pool.clone(),
1136            index: self.inner().id.file,
1137        }
1138    }
1139
1140    /// Gets the parent message type if this extension is defined within another message, or `None` otherwise.
1141    ///
1142    /// Note this just corresponds to where the extension is defined in the proto file. See [`containing_message`][ExtensionDescriptor::containing_message]
1143    /// for the message this field extends.
1144    pub fn parent_message(&self) -> Option<MessageDescriptor> {
1145        self.inner().parent.map(|index| MessageDescriptor {
1146            pool: self.pool.clone(),
1147            index,
1148        })
1149    }
1150
1151    /// Gets the short name of the extension field type, e.g. `my_extension`.
1152    pub fn name(&self) -> &str {
1153        self.inner().id.name()
1154    }
1155
1156    /// Gets the full name of the extension field, e.g. `my.package.ParentMessage.my_extension`.
1157    ///
1158    /// Note this includes the name of the parent message if any, not the message this field extends.
1159    pub fn full_name(&self) -> &str {
1160        self.inner().id.full_name()
1161    }
1162
1163    /// Gets the name of the package this extension field is defined in, e.g. `my.package`.
1164    ///
1165    /// If no package name is set, an empty string is returned.
1166    pub fn package_name(&self) -> &str {
1167        self.raw_file().package()
1168    }
1169
1170    /// Gets the path where this extension field is defined within the [`FileDescriptorProto`][FileDescriptorProto], e.g. `[7, 0]`.
1171    ///
1172    /// See [`path`][prost_types::source_code_info::Location::path] for more details on the structure of the path.
1173    pub fn path(&self) -> &[i32] {
1174        &self.inner().id.path
1175    }
1176
1177    /// Gets a reference to the [`FileDescriptorProto`] in which this extension is defined.
1178    pub fn parent_file_descriptor_proto(&self) -> &FileDescriptorProto {
1179        &self.pool.inner.files[self.inner().id.file as usize].prost
1180    }
1181
1182    /// Gets a reference to the raw [`FieldDescriptorProto`] wrapped by this [`ExtensionDescriptor`].
1183    pub fn field_descriptor_proto(&self) -> &FieldDescriptorProto {
1184        let file = self.parent_file_descriptor_proto();
1185        let path = self.path();
1186        debug_assert_ne!(path.len(), 0);
1187        debug_assert_eq!(path.len() % 2, 0);
1188        if path.len() == 2 {
1189            debug_assert_eq!(path[0], tag::file::EXTENSION);
1190            &file.extension[path[1] as usize]
1191        } else {
1192            let message = find_message_proto_prost(file, &path[..path.len() - 2]);
1193            debug_assert_eq!(path[path.len() - 2], tag::message::EXTENSION);
1194            &message.extension[path[path.len() - 1] as usize]
1195        }
1196    }
1197
1198    /// Decodes the options defined for this [`ExtensionDescriptor`], including any extension options.
1199    pub fn options(&self) -> DynamicMessage {
1200        decode_options(
1201            self.parent_pool(),
1202            "google.protobuf.FieldOptions",
1203            &self.raw().options,
1204        )
1205    }
1206
1207    /// Gets the number for this extension field.
1208    pub fn number(&self) -> u32 {
1209        self.inner().number
1210    }
1211
1212    /// Gets the name used for JSON serialization of this extension field, e.g. `[my.package.ParentMessage.my_field]`.
1213    pub fn json_name(&self) -> &str {
1214        &self.inner().json_name
1215    }
1216
1217    /// Whether this field is encoded using the proto2 group encoding.
1218    pub fn is_group(&self) -> bool {
1219        matches!(self.inner().kind, KindIndex::Group(_))
1220    }
1221
1222    /// Whether this field is a list type.
1223    ///
1224    /// Equivalent to checking that the cardinality is `Repeated` and that
1225    /// [`is_map`][Self::is_map] returns `false`.
1226    pub fn is_list(&self) -> bool {
1227        self.cardinality() == Cardinality::Repeated && !self.is_map()
1228    }
1229
1230    /// Whether this field is a map type.
1231    ///
1232    /// Equivalent to checking that the cardinality is `Repeated` and that
1233    /// the field type is a message where [`is_map_entry`][MessageDescriptor::is_map_entry]
1234    /// returns `true`.
1235    pub fn is_map(&self) -> bool {
1236        self.cardinality() == Cardinality::Repeated
1237            && match self.kind() {
1238                Kind::Message(message) => message.is_map_entry(),
1239                _ => false,
1240            }
1241    }
1242
1243    /// Whether this field is a list encoded using [packed encoding](https://developers.google.com/protocol-buffers/docs/encoding#packed).
1244    pub fn is_packed(&self) -> bool {
1245        self.inner().is_packed
1246    }
1247
1248    /// The cardinality of this field.
1249    pub fn cardinality(&self) -> Cardinality {
1250        self.inner().cardinality
1251    }
1252
1253    /// Whether this extension supports distinguishing between an unpopulated field and
1254    /// the default value.
1255    ///
1256    /// This is equivalent to `cardinality() != Cardinality::Repeated`
1257    pub fn supports_presence(&self) -> bool {
1258        self.cardinality() != Cardinality::Repeated
1259    }
1260
1261    /// Gets the [`Kind`] of this field.
1262    pub fn kind(&self) -> Kind {
1263        Kind::new(&self.pool, self.inner().kind)
1264    }
1265
1266    /// Gets the containing message that this field extends.
1267    pub fn containing_message(&self) -> MessageDescriptor {
1268        MessageDescriptor {
1269            pool: self.pool.clone(),
1270            index: self.inner().extendee,
1271        }
1272    }
1273
1274    pub(crate) fn default_value(&self) -> Option<&Value> {
1275        self.inner().default.as_ref()
1276    }
1277
1278    pub(crate) fn is_packable(&self) -> bool {
1279        self.inner().kind.is_packable()
1280    }
1281
1282    fn inner(&self) -> &ExtensionDescriptorInner {
1283        &self.pool.inner.extensions[self.index as usize]
1284    }
1285
1286    fn raw(&self) -> &types::FieldDescriptorProto {
1287        let file = self.raw_file();
1288        let path = self.path();
1289        debug_assert_ne!(path.len(), 0);
1290        debug_assert_eq!(path.len() % 2, 0);
1291        if path.len() == 2 {
1292            debug_assert_eq!(path[0], tag::file::EXTENSION);
1293            &file.extension[path[1] as usize]
1294        } else {
1295            let message = find_message_proto(file, &path[..path.len() - 2]);
1296            debug_assert_eq!(path[path.len() - 2], tag::message::EXTENSION);
1297            &message.extension[path[path.len() - 1] as usize]
1298        }
1299    }
1300
1301    fn raw_file(&self) -> &types::FileDescriptorProto {
1302        &self.pool.inner.files[self.inner().id.file as usize].raw
1303    }
1304}
1305
1306impl fmt::Debug for ExtensionDescriptor {
1307    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1308        f.debug_struct("ExtensionDescriptor")
1309            .field("name", &self.name())
1310            .field("full_name", &self.full_name())
1311            .field("json_name", &self.json_name())
1312            .field("number", &self.number())
1313            .field("kind", &self.kind())
1314            .field("cardinality", &self.cardinality())
1315            .field(
1316                "containing_message",
1317                &self.containing_message().name().to_owned(),
1318            )
1319            .field("default_value", &self.default_value())
1320            .field("is_group", &self.is_group())
1321            .field("is_list", &self.is_list())
1322            .field("is_map", &self.is_map())
1323            .field("is_packed", &self.is_packed())
1324            .field("supports_presence", &self.supports_presence())
1325            .finish()
1326    }
1327}
1328
1329impl EnumDescriptor {
1330    /// Gets a reference to the [`DescriptorPool`] this enum type is defined in.
1331    pub fn parent_pool(&self) -> &DescriptorPool {
1332        &self.pool
1333    }
1334
1335    /// Gets the [`FileDescriptor`] this enum type is defined in.
1336    pub fn parent_file(&self) -> FileDescriptor {
1337        FileDescriptor {
1338            pool: self.pool.clone(),
1339            index: self.inner().id.file,
1340        }
1341    }
1342
1343    /// Gets the parent message type if this enum type is nested inside a another message, or `None` otherwise
1344    pub fn parent_message(&self) -> Option<MessageDescriptor> {
1345        self.inner().parent.map(|index| MessageDescriptor {
1346            pool: self.pool.clone(),
1347            index,
1348        })
1349    }
1350
1351    /// Gets the short name of the enum type, e.g. `MyEnum`.
1352    pub fn name(&self) -> &str {
1353        self.inner().id.name()
1354    }
1355
1356    /// Gets the full name of the enum, e.g. `my.package.MyEnum`.
1357    pub fn full_name(&self) -> &str {
1358        self.inner().id.full_name()
1359    }
1360
1361    /// Gets the name of the package this enum type is defined in, e.g. `my.package`.
1362    ///
1363    /// If no package name is set, an empty string is returned.
1364    pub fn package_name(&self) -> &str {
1365        self.raw_file().package()
1366    }
1367
1368    /// Gets the path where this enum type is defined within the [`FileDescriptorProto`][FileDescriptorProto], e.g. `[5, 0]`.
1369    ///
1370    /// See [`path`][prost_types::source_code_info::Location::path] for more details on the structure of the path.
1371    pub fn path(&self) -> &[i32] {
1372        &self.inner().id.path
1373    }
1374
1375    /// Gets a reference to the [`FileDescriptorProto`] in which this enum is defined.
1376    pub fn parent_file_descriptor_proto(&self) -> &FileDescriptorProto {
1377        &self.pool.inner.files[self.inner().id.file as usize].prost
1378    }
1379
1380    /// Gets a reference to the raw [`EnumDescriptorProto`] wrapped by this [`EnumDescriptor`].
1381    pub fn enum_descriptor_proto(&self) -> &EnumDescriptorProto {
1382        let file = self.parent_file_descriptor_proto();
1383        let path = self.path();
1384        debug_assert_ne!(path.len(), 0);
1385        debug_assert_eq!(path.len() % 2, 0);
1386        if path.len() == 2 {
1387            debug_assert_eq!(path[0], tag::file::ENUM_TYPE);
1388            &file.enum_type[path[1] as usize]
1389        } else {
1390            let message = find_message_proto_prost(file, &path[..path.len() - 2]);
1391            debug_assert_eq!(path[path.len() - 2], tag::message::ENUM_TYPE);
1392            &message.enum_type[path[path.len() - 1] as usize]
1393        }
1394    }
1395
1396    /// Decodes the options defined for this [`EnumDescriptor`], including any extension options.
1397    pub fn options(&self) -> DynamicMessage {
1398        decode_options(
1399            self.parent_pool(),
1400            "google.protobuf.EnumOptions",
1401            &self.raw().options,
1402        )
1403    }
1404
1405    /// Gets the default value for the enum type.
1406    pub fn default_value(&self) -> EnumValueDescriptor {
1407        EnumValueDescriptor {
1408            parent: self.clone(),
1409            index: 0,
1410        }
1411    }
1412
1413    /// Gets a [`EnumValueDescriptor`] for the enum value with the given name, or `None` if no such value exists.
1414    pub fn get_value_by_name(&self, name: &str) -> Option<EnumValueDescriptor> {
1415        self.inner()
1416            .value_names
1417            .get(name)
1418            .map(|&index| EnumValueDescriptor {
1419                parent: self.clone(),
1420                index,
1421            })
1422    }
1423
1424    /// Gets a [`EnumValueDescriptor`] for the enum value with the given number, or `None` if no such value exists.
1425    ///
1426    /// If the enum is defined with the `allow_alias` option and has multiple values with the given number, it is
1427    /// unspecified which one will be returned.
1428    pub fn get_value(&self, number: i32) -> Option<EnumValueDescriptor> {
1429        self.inner()
1430            .value_numbers
1431            .binary_search_by(|(l, _)| l.cmp(&number))
1432            .ok()
1433            .map(|index| EnumValueDescriptor {
1434                parent: self.clone(),
1435                index: self.inner().value_numbers[index].1,
1436            })
1437    }
1438
1439    /// Gets an iterator yielding a [`EnumValueDescriptor`] for each value in this enum.
1440    pub fn values(&self) -> impl ExactSizeIterator<Item = EnumValueDescriptor> + '_ {
1441        self.inner()
1442            .value_numbers
1443            .iter()
1444            .map(|&(_, index)| EnumValueDescriptor {
1445                parent: self.clone(),
1446                index,
1447            })
1448    }
1449
1450    /// Gets an iterator over reserved value number ranges in this enum.
1451    pub fn reserved_ranges(&self) -> impl ExactSizeIterator<Item = RangeInclusive<i32>> + '_ {
1452        self.raw()
1453            .reserved_range
1454            .iter()
1455            .map(|n| n.start()..=n.end())
1456    }
1457
1458    /// Gets an iterator over reserved value names in this enum.
1459    pub fn reserved_names(&self) -> impl ExactSizeIterator<Item = &str> + '_ {
1460        self.raw().reserved_name.iter().map(|n| n.as_ref())
1461    }
1462
1463    fn inner(&self) -> &EnumDescriptorInner {
1464        &self.pool.inner.enums[self.index as usize]
1465    }
1466
1467    fn raw(&self) -> &types::EnumDescriptorProto {
1468        find_enum_proto(self.raw_file(), self.path())
1469    }
1470
1471    fn raw_file(&self) -> &types::FileDescriptorProto {
1472        &self.pool.inner.files[self.inner().id.file as usize].raw
1473    }
1474}
1475
1476impl fmt::Debug for EnumDescriptor {
1477    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1478        f.debug_struct("EnumDescriptor")
1479            .field("name", &self.name())
1480            .field("full_name", &self.full_name())
1481            .field("default_value", &self.default_value())
1482            .field("values", &debug_fmt_iter(self.values()))
1483            .finish()
1484    }
1485}
1486
1487impl EnumValueDescriptor {
1488    /// Gets a reference to the [`DescriptorPool`] this enum value is defined in.
1489    pub fn parent_pool(&self) -> &DescriptorPool {
1490        self.parent.parent_pool()
1491    }
1492
1493    /// Gets the [`FileDescriptor`] this enum value is defined in.
1494    pub fn parent_file(&self) -> FileDescriptor {
1495        self.parent.parent_file()
1496    }
1497
1498    /// Gets a reference to the [`EnumDescriptor`] this enum value is defined in.
1499    pub fn parent_enum(&self) -> &EnumDescriptor {
1500        &self.parent
1501    }
1502
1503    /// Gets the short name of the enum value, e.g. `MY_VALUE`.
1504    pub fn name(&self) -> &str {
1505        self.inner().id.name()
1506    }
1507
1508    /// Gets the full name of the enum value, e.g. `my.package.MY_VALUE`.
1509    pub fn full_name(&self) -> &str {
1510        self.inner().id.full_name()
1511    }
1512
1513    /// Gets the path where this enum value is defined within the [`FileDescriptorProto`][FileDescriptorProto], e.g. `[5, 0, 2, 0]`.
1514    ///
1515    /// See [`path`][prost_types::source_code_info::Location::path] for more details on the structure of the path.
1516    pub fn path(&self) -> &[i32] {
1517        &self.inner().id.path
1518    }
1519
1520    /// Gets a reference to the raw [`EnumValueDescriptorProto`] wrapped by this [`EnumValueDescriptor`].
1521    pub fn enum_value_descriptor_proto(&self) -> &EnumValueDescriptorProto {
1522        &self.parent.enum_descriptor_proto().value[self.index as usize]
1523    }
1524
1525    /// Decodes the options defined for this [`EnumValueDescriptor`], including any extension options.
1526    pub fn options(&self) -> DynamicMessage {
1527        decode_options(
1528            self.parent_pool(),
1529            "google.protobuf.EnumValueOptions",
1530            &self.raw().options,
1531        )
1532    }
1533
1534    /// Gets the number representing this enum value.
1535    pub fn number(&self) -> i32 {
1536        self.inner().number
1537    }
1538
1539    fn inner(&self) -> &EnumValueDescriptorInner {
1540        &self.parent.inner().values[self.index as usize]
1541    }
1542
1543    fn raw(&self) -> &types::EnumValueDescriptorProto {
1544        &self.parent.raw().value[self.index as usize]
1545    }
1546}
1547
1548impl fmt::Debug for EnumValueDescriptor {
1549    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1550        f.debug_struct("EnumValueDescriptor")
1551            .field("name", &self.number())
1552            .field("full_name", &self.full_name())
1553            .field("number", &self.number())
1554            .finish()
1555    }
1556}
1557
1558impl OneofDescriptor {
1559    /// Gets a reference to the [`DescriptorPool`] this oneof is defined in.
1560    pub fn parent_pool(&self) -> &DescriptorPool {
1561        self.message.parent_pool()
1562    }
1563
1564    /// Gets the [`FileDescriptor`] this oneof is defined in.
1565    pub fn parent_file(&self) -> FileDescriptor {
1566        self.message.parent_file()
1567    }
1568
1569    /// Gets a reference to the [`MessageDescriptor`] this oneof is defined in.
1570    pub fn parent_message(&self) -> &MessageDescriptor {
1571        &self.message
1572    }
1573
1574    /// Gets the short name of the oneof, e.g. `my_oneof`.
1575    pub fn name(&self) -> &str {
1576        self.inner().id.name()
1577    }
1578
1579    /// Gets the full name of the oneof, e.g. `my.package.MyMessage.my_oneof`.
1580    pub fn full_name(&self) -> &str {
1581        self.inner().id.full_name()
1582    }
1583
1584    /// Gets the path where this oneof is defined within the [`FileDescriptorProto`][FileDescriptorProto], e.g. `[4, 0, 8, 0]`.
1585    ///
1586    /// See [`path`][prost_types::source_code_info::Location::path] for more details on the structure of the path.
1587    pub fn path(&self) -> &[i32] {
1588        &self.inner().id.path
1589    }
1590
1591    /// Gets a reference to the raw [`OneofDescriptorProto`] wrapped by this [`OneofDescriptor`].
1592    pub fn oneof_descriptor_proto(&self) -> &OneofDescriptorProto {
1593        &self.message.descriptor_proto().oneof_decl[self.index as usize]
1594    }
1595
1596    /// Decodes the options defined for this [`OneofDescriptorProto`], including any extension options.
1597    pub fn options(&self) -> DynamicMessage {
1598        decode_options(
1599            self.parent_pool(),
1600            "google.protobuf.OneofOptions",
1601            &self.raw().options,
1602        )
1603    }
1604
1605    /// Gets an iterator yielding a [`FieldDescriptor`] for each field of the parent message this oneof contains.
1606    pub fn fields(&self) -> impl ExactSizeIterator<Item = FieldDescriptor> + '_ {
1607        self.inner().fields.iter().map(|&index| FieldDescriptor {
1608            message: self.parent_message().clone(),
1609            index,
1610        })
1611    }
1612
1613    fn inner(&self) -> &OneofDescriptorInner {
1614        &self.message.inner().oneofs[self.index as usize]
1615    }
1616
1617    fn raw(&self) -> &types::OneofDescriptorProto {
1618        &self.message.raw().oneof_decl[self.index as usize]
1619    }
1620}
1621
1622impl fmt::Debug for OneofDescriptor {
1623    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1624        f.debug_struct("OneofDescriptor")
1625            .field("name", &self.name())
1626            .field("full_name", &self.full_name())
1627            .field("fields", &debug_fmt_iter(self.fields()))
1628            .finish()
1629    }
1630}
1631
1632impl ServiceDescriptor {
1633    /// Create a new [`ServiceDescriptor`] referencing the service at `index` within the given [`DescriptorPool`].
1634    ///
1635    /// # Panics
1636    ///
1637    /// Panics if `index` is out-of-bounds.
1638    pub fn new(pool: DescriptorPool, index: usize) -> Self {
1639        debug_assert!(index < pool.services().len());
1640        ServiceDescriptor {
1641            pool,
1642            index: to_index(index),
1643        }
1644    }
1645
1646    /// Returns the index of this [`ServiceDescriptor`] within the parent [`DescriptorPool`].
1647    pub fn index(&self) -> usize {
1648        self.index as usize
1649    }
1650
1651    /// Gets a reference to the [`DescriptorPool`] this service is defined in.
1652    pub fn parent_pool(&self) -> &DescriptorPool {
1653        &self.pool
1654    }
1655
1656    /// Gets the [`FileDescriptor`] this service is defined in.
1657    pub fn parent_file(&self) -> FileDescriptor {
1658        FileDescriptor {
1659            pool: self.pool.clone(),
1660            index: self.inner().id.file,
1661        }
1662    }
1663
1664    /// Gets the short name of the service, e.g. `MyService`.
1665    pub fn name(&self) -> &str {
1666        self.inner().id.name()
1667    }
1668
1669    /// Gets the full name of the service, e.g. `my.package.Service`.
1670    pub fn full_name(&self) -> &str {
1671        self.inner().id.full_name()
1672    }
1673
1674    /// Gets the name of the package this service is defined in, e.g. `my.package`.
1675    ///
1676    /// If no package name is set, an empty string is returned.
1677    pub fn package_name(&self) -> &str {
1678        self.raw_file().package()
1679    }
1680
1681    /// Gets the path where this service is defined within the [`FileDescriptorProto`][FileDescriptorProto], e.g. `[6, 0]`.
1682    ///
1683    /// See [`path`][prost_types::source_code_info::Location::path] for more details on the structure of the path.
1684    pub fn path(&self) -> &[i32] {
1685        &self.inner().id.path
1686    }
1687
1688    /// Gets a reference to the [`FileDescriptorProto`] in which this service is defined.
1689    pub fn parent_file_descriptor_proto(&self) -> &FileDescriptorProto {
1690        &self.pool.inner.files[self.inner().id.file as usize].prost
1691    }
1692
1693    /// Gets a reference to the raw [`ServiceDescriptorProto`] wrapped by this [`ServiceDescriptor`].
1694    pub fn service_descriptor_proto(&self) -> &ServiceDescriptorProto {
1695        let path = self.path();
1696        debug_assert!(!path.is_empty());
1697        &self.parent_file_descriptor_proto().service[*path.last().unwrap() as usize]
1698    }
1699
1700    /// Decodes the options defined for this [`ServiceDescriptorProto`], including any extension options.
1701    pub fn options(&self) -> DynamicMessage {
1702        decode_options(
1703            self.parent_pool(),
1704            "google.protobuf.ServiceOptions",
1705            &self.raw().options,
1706        )
1707    }
1708
1709    /// Gets an iterator yielding a [`MethodDescriptor`] for each method defined in this service.
1710    pub fn methods(&self) -> impl ExactSizeIterator<Item = MethodDescriptor> + '_ {
1711        indices(&self.inner().methods).map(|index| MethodDescriptor {
1712            service: self.clone(),
1713            index,
1714        })
1715    }
1716
1717    fn inner(&self) -> &ServiceDescriptorInner {
1718        &self.pool.inner.services[self.index as usize]
1719    }
1720
1721    fn raw(&self) -> &types::ServiceDescriptorProto {
1722        let path = self.path();
1723        debug_assert!(!path.is_empty());
1724        &self.raw_file().service[*path.last().unwrap() as usize]
1725    }
1726
1727    fn raw_file(&self) -> &types::FileDescriptorProto {
1728        &self.pool.inner.files[self.inner().id.file as usize].raw
1729    }
1730}
1731
1732impl fmt::Debug for ServiceDescriptor {
1733    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1734        f.debug_struct("ServiceDescriptor")
1735            .field("name", &self.name())
1736            .field("full_name", &self.full_name())
1737            .field("index", &self.index())
1738            .field("methods", &debug_fmt_iter(self.methods()))
1739            .finish()
1740    }
1741}
1742
1743impl MethodDescriptor {
1744    /// Create a new [`MethodDescriptor`] referencing the method at `index` within the [`ServiceDescriptor`].
1745    ///
1746    /// # Panics
1747    ///
1748    /// Panics if `index` is out-of-bounds.
1749    pub fn new(service: ServiceDescriptor, index: usize) -> Self {
1750        debug_assert!(index < service.methods().len());
1751        MethodDescriptor {
1752            service,
1753            index: to_index(index),
1754        }
1755    }
1756
1757    /// Gets the index of the method within the parent [`ServiceDescriptor`].
1758    pub fn index(&self) -> usize {
1759        self.index as usize
1760    }
1761
1762    /// Gets a reference to the [`ServiceDescriptor`] this method is defined in.
1763    pub fn parent_service(&self) -> &ServiceDescriptor {
1764        &self.service
1765    }
1766
1767    /// Gets a reference to the [`DescriptorPool`] this method is defined in.
1768    pub fn parent_pool(&self) -> &DescriptorPool {
1769        self.service.parent_pool()
1770    }
1771
1772    /// Gets the [`FileDescriptor`] this method is defined in.
1773    pub fn parent_file(&self) -> FileDescriptor {
1774        self.service.parent_file()
1775    }
1776
1777    /// Gets the short name of the method, e.g. `method`.
1778    pub fn name(&self) -> &str {
1779        self.inner().id.name()
1780    }
1781
1782    /// Gets the full name of the method, e.g. `my.package.MyService.my_method`.
1783    pub fn full_name(&self) -> &str {
1784        self.inner().id.full_name()
1785    }
1786
1787    /// Gets the path where this method is defined within the [`FileDescriptorProto`][FileDescriptorProto], e.g. `[6, 0, 2, 0]`.
1788    ///
1789    /// See [`path`][prost_types::source_code_info::Location::path] for more details on the structure of the path.
1790    pub fn path(&self) -> &[i32] {
1791        &self.inner().id.path
1792    }
1793
1794    /// Gets a reference to the raw [`MethodDescriptorProto`] wrapped by this [`MethodDescriptor`].
1795    pub fn method_descriptor_proto(&self) -> &MethodDescriptorProto {
1796        &self.service.service_descriptor_proto().method[self.index as usize]
1797    }
1798
1799    /// Decodes the options defined for this [`MethodDescriptorProto`], including any extension options.
1800    pub fn options(&self) -> DynamicMessage {
1801        decode_options(
1802            self.parent_pool(),
1803            "google.protobuf.MethodOptions",
1804            &self.raw().options,
1805        )
1806    }
1807
1808    /// Gets the [`MessageDescriptor`] for the input type of this method.
1809    pub fn input(&self) -> MessageDescriptor {
1810        MessageDescriptor {
1811            pool: self.parent_pool().clone(),
1812            index: self.inner().input,
1813        }
1814    }
1815
1816    /// Gets the [`MessageDescriptor`] for the output type of this method.
1817    pub fn output(&self) -> MessageDescriptor {
1818        MessageDescriptor {
1819            pool: self.parent_pool().clone(),
1820            index: self.inner().output,
1821        }
1822    }
1823
1824    /// Returns `true` if the client streams multiple messages.
1825    pub fn is_client_streaming(&self) -> bool {
1826        self.raw().client_streaming()
1827    }
1828
1829    /// Returns `true` if the server streams multiple messages.
1830    pub fn is_server_streaming(&self) -> bool {
1831        self.raw().server_streaming()
1832    }
1833
1834    fn inner(&self) -> &MethodDescriptorInner {
1835        &self.service.inner().methods[self.index as usize]
1836    }
1837
1838    fn raw(&self) -> &types::MethodDescriptorProto {
1839        &self.service.raw().method[self.index as usize]
1840    }
1841}
1842
1843impl fmt::Debug for MethodDescriptor {
1844    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1845        f.debug_struct("MethodDescriptor")
1846            .field("name", &self.name())
1847            .field("full_name", &self.full_name())
1848            .field("index", &self.index())
1849            .field("input", &self.input())
1850            .field("output", &self.output())
1851            .field("is_client_streaming", &self.is_client_streaming())
1852            .field("is_server_streaming", &self.is_server_streaming())
1853            .finish()
1854    }
1855}
1856
1857fn debug_fmt_iter<I>(i: I) -> impl fmt::Debug
1858where
1859    I: Iterator,
1860    I::Item: fmt::Debug,
1861{
1862    struct Wrapper<T>(Vec<T>);
1863
1864    impl<T> fmt::Debug for Wrapper<T>
1865    where
1866        T: fmt::Debug,
1867    {
1868        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1869            f.debug_list().entries(&self.0).finish()
1870        }
1871    }
1872
1873    Wrapper(i.collect())
1874}
1875
1876#[allow(clippy::ptr_arg)]
1877fn indices<T>(f: &Vec<T>) -> Range<DescriptorIndex> {
1878    0..to_index(f.len())
1879}
1880
1881fn join_name<'a>(namespace: &str, name: &'a str) -> Cow<'a, str> {
1882    if namespace.is_empty() {
1883        Cow::Borrowed(name)
1884    } else {
1885        Cow::Owned(format!("{}.{}", namespace, name))
1886    }
1887}
1888
1889fn decode_options<T>(
1890    pool: &DescriptorPool,
1891    name: &str,
1892    option: &Option<Options<T>>,
1893) -> DynamicMessage {
1894    let message_desc = pool
1895        .get_message_by_name(name)
1896        .unwrap_or_else(|| DescriptorPool::global().get_message_by_name(name).unwrap());
1897
1898    let bytes = option
1899        .as_ref()
1900        .map(|o| o.encoded.as_slice())
1901        .unwrap_or_default();
1902    DynamicMessage::decode(message_desc, bytes).unwrap()
1903}
1904
1905fn find_message_proto_prost<'a>(
1906    file: &'a FileDescriptorProto,
1907    path: &[i32],
1908) -> &'a DescriptorProto {
1909    debug_assert_ne!(path.len(), 0);
1910    debug_assert_eq!(path.len() % 2, 0);
1911
1912    let mut message: Option<&'a DescriptorProto> = None;
1913    for part in path.chunks(2) {
1914        match part[0] {
1915            tag::file::MESSAGE_TYPE => message = Some(&file.message_type[part[1] as usize]),
1916            tag::message::NESTED_TYPE => {
1917                message = Some(&message.unwrap().nested_type[part[1] as usize])
1918            }
1919            _ => panic!("invalid message path"),
1920        }
1921    }
1922
1923    message.unwrap()
1924}