Skip to main content

pbrs/
dynamic.rs

1//! Runtime descriptors and `DynamicMessage`.
2
3use crate::error::{ParseError, SerializeError};
4use crate::internal::SealedInternal;
5use crate::message::{
6    Clear, ClearAndParse, CopyFrom, MergeFrom, Message, MessageMut, MessageType, MessageView,
7    Serialize, TakeFrom,
8};
9use crate::proxied::{AsMut, AsView, IntoMut, IntoView, MutProxied, Proxied};
10use crate::string::{ProtoBytes, ProtoString};
11use crate::wire::{
12    self, UnknownField, UnknownFields, WIRE_EGROUP, WIRE_I32, WIRE_I64, WIRE_LEN, WIRE_SGROUP,
13    WIRE_VARINT, decode_tag, decode_varint, encode_len_field, encode_tag, encode_varint,
14    encode_zigzag32, encode_zigzag64, key_len_value_len, read_fixed32, read_fixed64,
15    read_len_bytes, tag_len, varint_len,
16};
17use std::collections::{BTreeMap, BTreeSet};
18use std::fmt;
19use std::sync::Arc;
20
21/// Maximum nesting depth for binary, JSON, and text parse.
22/// A payload nested more than this many messages returns [`ParseError`].
23pub const RECURSION_LIMIT: u32 = 100;
24
25#[derive(Clone, Copy, Debug, PartialEq, Eq)]
26pub enum FieldType {
27    Double = 1,
28    Float = 2,
29    Int64 = 3,
30    Uint64 = 4,
31    Int32 = 5,
32    Fixed64 = 6,
33    Fixed32 = 7,
34    Bool = 8,
35    String = 9,
36    Group = 10,
37    Message = 11,
38    Bytes = 12,
39    Uint32 = 13,
40    Enum = 14,
41    Sfixed32 = 15,
42    Sfixed64 = 16,
43    Sint32 = 17,
44    Sint64 = 18,
45}
46
47impl FieldType {
48    fn from_i32(v: i32) -> Option<Self> {
49        Some(match v {
50            1 => Self::Double,
51            2 => Self::Float,
52            3 => Self::Int64,
53            4 => Self::Uint64,
54            5 => Self::Int32,
55            6 => Self::Fixed64,
56            7 => Self::Fixed32,
57            8 => Self::Bool,
58            9 => Self::String,
59            10 => Self::Group,
60            11 => Self::Message,
61            12 => Self::Bytes,
62            13 => Self::Uint32,
63            14 => Self::Enum,
64            15 => Self::Sfixed32,
65            16 => Self::Sfixed64,
66            17 => Self::Sint32,
67            18 => Self::Sint64,
68            _ => return None,
69        })
70    }
71
72    pub(crate) fn is_packable(self) -> bool {
73        !matches!(
74            self,
75            Self::String | Self::Bytes | Self::Message | Self::Group
76        )
77    }
78
79    fn default_wire(self) -> u32 {
80        match self {
81            Self::Fixed64 | Self::Sfixed64 | Self::Double => WIRE_I64,
82            Self::Fixed32 | Self::Sfixed32 | Self::Float => WIRE_I32,
83            Self::String | Self::Bytes | Self::Message | Self::Group => WIRE_LEN,
84            _ => WIRE_VARINT,
85        }
86    }
87}
88
89#[derive(Clone, Copy, Debug, PartialEq, Eq)]
90pub enum Cardinality {
91    Optional,
92    Required,
93    Repeated,
94}
95
96#[derive(Clone, Copy, Debug, PartialEq, Eq)]
97pub enum Presence {
98    Implicit,
99    Explicit,
100}
101
102/// Source code information for a protobuf file, containing source locations with paths, spans, and comments.
103#[derive(Clone, Debug, Default, PartialEq, Eq)]
104pub struct SourceCodeInfo {
105    /// List of source locations in the file.
106    pub locations: Vec<SourceLocation>,
107}
108
109impl SourceCodeInfo {
110    /// Find the first [`SourceLocation`] matching the given descriptor path.
111    pub fn find_location(&self, path: &[i32]) -> Option<&SourceLocation> {
112        self.locations
113            .iter()
114            .find(|loc| loc.path.as_slice() == path)
115    }
116}
117
118/// A location in a source protobuf file.
119#[derive(Clone, Debug, Default, PartialEq, Eq)]
120pub struct SourceLocation {
121    /// Path of field numbers and indexes leading from the file root to this element.
122    pub path: Vec<i32>,
123    /// Line and column span in the source file: `[start_line, start_col, end_line, end_col]` or `[start_line, start_col, end_col]`.
124    pub span: Vec<i32>,
125    /// Leading comment block directly preceding the element.
126    pub leading_comments: Option<String>,
127    /// Trailing comment on the same line after the element.
128    pub trailing_comments: Option<String>,
129    /// Detached comment blocks preceding the element.
130    pub leading_detached_comments: Vec<String>,
131}
132
133/// Comments and span associated with a descriptor element.
134#[derive(Clone, Debug, Default, PartialEq, Eq)]
135pub struct Comments {
136    /// Leading comment block directly preceding the element.
137    pub leading_comments: Option<String>,
138    /// Trailing comment on the same line after the element.
139    pub trailing_comments: Option<String>,
140    /// Detached comment blocks preceding the element.
141    pub leading_detached_comments: Vec<String>,
142    /// Leading comment (alias for [`Self::leading_comments`]).
143    pub leading: Option<String>,
144    /// Trailing comment (alias for [`Self::trailing_comments`]).
145    pub trailing: Option<String>,
146    /// Line and column span in the source file, if available.
147    pub span: Vec<i32>,
148}
149
150impl Comments {
151    /// Returns the leading comment, if any.
152    pub fn leading(&self) -> Option<&str> {
153        self.leading_comments.as_deref()
154    }
155
156    /// Returns the trailing comment, if any.
157    pub fn trailing(&self) -> Option<&str> {
158        self.trailing_comments.as_deref()
159    }
160
161    /// Returns `true` if there are no comments.
162    pub fn is_empty(&self) -> bool {
163        self.leading_comments.as_ref().is_none_or(String::is_empty)
164            && self.trailing_comments.as_ref().is_none_or(String::is_empty)
165            && self.leading_detached_comments.is_empty()
166    }
167}
168
169#[derive(Clone, Debug)]
170pub struct FieldDescriptor {
171    pub name: String,
172    pub number: u32,
173    pub field_type: FieldType,
174    pub cardinality: Cardinality,
175    pub presence: Presence,
176    pub packed: bool,
177    pub type_name: Option<String>,
178    pub json_name: String,
179    pub is_map: bool,
180    pub message: Option<Arc<MessageDescriptor>>,
181    pub enum_ty: Option<Arc<EnumDescriptor>>,
182    pub oneof_index: Option<u32>,
183    pub utf8_validate: bool,
184    pub default: Option<String>,
185    pub extendee: Option<String>,
186    pub delimited: bool,
187    pub extension_name: Option<String>,
188    /// Unrecognized `FieldOptions` tags (custom options). Payload is the option
189    /// body: length-delimited bytes, or the varint/fixed encoding.
190    pub options: Vec<DescriptorOption>,
191    /// Comments associated with this field.
192    pub comments: Comments,
193    /// Whether this field is marked deprecated in `FieldOptions`.
194    pub deprecated: bool,
195}
196
197impl FieldDescriptor {
198    pub fn new(
199        name: impl Into<String>,
200        number: u32,
201        field_type: FieldType,
202        cardinality: Cardinality,
203        presence: Presence,
204    ) -> Self {
205        let name = name.into();
206        Self {
207            json_name: name.clone(),
208            name,
209            number,
210            field_type,
211            cardinality,
212            presence,
213            packed: cardinality == Cardinality::Repeated && field_type.is_packable(),
214            type_name: None,
215            is_map: false,
216            message: None,
217            enum_ty: None,
218            oneof_index: None,
219            utf8_validate: true,
220            default: None,
221            extendee: None,
222            delimited: field_type == FieldType::Group,
223            extension_name: None,
224            options: Vec::new(),
225            comments: Comments::default(),
226            deprecated: false,
227        }
228    }
229
230    /// Custom `FieldOptions` tag payload, if present.
231    pub fn custom_option(&self, number: u32) -> Option<&[u8]> {
232        self.options
233            .iter()
234            .find(|o| o.number == number)
235            .map(|o| o.value.as_slice())
236    }
237
238    /// Leading comment, if present.
239    pub fn leading_comments(&self) -> Option<&str> {
240        self.comments.leading()
241    }
242
243    /// Trailing comment, if present.
244    pub fn trailing_comments(&self) -> Option<&str> {
245        self.comments.trailing()
246    }
247
248    /// Source span `[start_line, start_col, end_line, end_col]`, if available.
249    pub fn span(&self) -> &[i32] {
250        &self.comments.span
251    }
252
253    /// Whether this field is marked deprecated.
254    pub fn is_deprecated(&self) -> bool {
255        self.deprecated
256    }
257}
258
259#[derive(Clone, Debug)]
260pub struct MessageDescriptor {
261    pub name: String,
262    pub full_name: String,
263    pub fields: BTreeMap<u32, FieldDescriptor>,
264    pub fields_by_name: BTreeMap<String, u32>,
265    pub is_map_entry: bool,
266    pub oneofs: Vec<Vec<u32>>,
267    pub fields_by_json_name: BTreeMap<String, u32>,
268    pub extension_ranges: Vec<(u32, u32)>,
269    pub reserved_names: BTreeSet<String>,
270    pub file_name: String,
271    pub message_set_wire_format: bool,
272    /// Unrecognized `MessageOptions` tags (custom options).
273    pub options: Vec<DescriptorOption>,
274    /// Comments associated with this message.
275    pub comments: Comments,
276    /// Whether this message is marked deprecated in `MessageOptions`.
277    pub deprecated: bool,
278}
279
280impl MessageDescriptor {
281    pub fn builder(full_name: impl Into<String>) -> MessageDescriptorBuilder {
282        let full_name = full_name.into();
283        let name = full_name
284            .rsplit('.')
285            .next()
286            .unwrap_or(full_name.as_str())
287            .to_string();
288        MessageDescriptorBuilder {
289            desc: MessageDescriptor {
290                name,
291                full_name,
292                fields: BTreeMap::new(),
293                fields_by_name: BTreeMap::new(),
294                is_map_entry: false,
295                oneofs: Vec::new(),
296                fields_by_json_name: BTreeMap::new(),
297                extension_ranges: Vec::new(),
298                reserved_names: BTreeSet::new(),
299                file_name: String::new(),
300                message_set_wire_format: false,
301                options: Vec::new(),
302                comments: Comments::default(),
303                deprecated: false,
304            },
305        }
306    }
307
308    pub fn field(&self, number: u32) -> Option<&FieldDescriptor> {
309        self.fields.get(&number)
310    }
311
312    pub fn field_by_name(&self, name: &str) -> Option<&FieldDescriptor> {
313        let name = name
314            .strip_prefix('[')
315            .and_then(|s| s.strip_suffix(']'))
316            .unwrap_or(name);
317        self.fields_by_name
318            .get(name)
319            .or_else(|| self.fields_by_json_name.get(name))
320            .or_else(|| self.fields_by_name.get(&name.to_ascii_lowercase()))
321            .or_else(|| {
322                name.rsplit('.').next().and_then(|short| {
323                    self.fields_by_name
324                        .get(short)
325                        .or_else(|| self.fields_by_name.get(&short.to_ascii_lowercase()))
326                })
327            })
328            .and_then(|n| self.fields.get(n))
329    }
330
331    pub fn is_reserved_name(&self, name: &str) -> bool {
332        self.reserved_names.contains(name)
333    }
334
335    /// Custom `MessageOptions` tag payload, if present.
336    pub fn custom_option(&self, number: u32) -> Option<&[u8]> {
337        self.options
338            .iter()
339            .find(|o| o.number == number)
340            .map(|o| o.value.as_slice())
341    }
342
343    /// Leading comment, if present.
344    pub fn leading_comments(&self) -> Option<&str> {
345        self.comments.leading()
346    }
347
348    /// Trailing comment, if present.
349    pub fn trailing_comments(&self) -> Option<&str> {
350        self.comments.trailing()
351    }
352
353    /// Source span `[start_line, start_col, end_line, end_col]`, if available.
354    pub fn span(&self) -> &[i32] {
355        &self.comments.span
356    }
357
358    /// Whether this message is marked deprecated.
359    pub fn is_deprecated(&self) -> bool {
360        self.deprecated
361    }
362}
363
364/// One custom option on a file, message, field, enum, or method descriptor.
365#[derive(Clone, Debug, PartialEq, Eq)]
366pub struct DescriptorOption {
367    pub number: u32,
368    pub value: Vec<u8>,
369}
370
371#[derive(Clone, Debug, Default)]
372pub struct EnumDescriptor {
373    pub name: String,
374    pub full_name: String,
375    pub file_name: String,
376    pub values: BTreeMap<i32, String>,
377    pub names: BTreeMap<String, i32>,
378    /// Proto-order (number, original name). First entry is the default.
379    pub listed: Vec<(i32, String)>,
380    pub closed: bool,
381    /// Unrecognized `EnumOptions` tags (custom options).
382    pub options: Vec<DescriptorOption>,
383    /// Comments associated with this enum.
384    pub comments: Comments,
385    /// Comments on individual enum values by number.
386    pub value_comments: BTreeMap<i32, Comments>,
387    /// Comments on individual enum values by name.
388    pub value_comments_by_name: BTreeMap<String, Comments>,
389    /// Whether this enum is marked deprecated in `EnumOptions`.
390    pub deprecated: bool,
391    /// Enum values marked deprecated.
392    pub deprecated_values: BTreeSet<i32>,
393}
394
395impl EnumDescriptor {
396    /// Custom `EnumOptions` tag payload, if present.
397    pub fn custom_option(&self, number: u32) -> Option<&[u8]> {
398        self.options
399            .iter()
400            .find(|o| o.number == number)
401            .map(|o| o.value.as_slice())
402    }
403
404    /// Leading comment, if present.
405    pub fn leading_comments(&self) -> Option<&str> {
406        self.comments.leading()
407    }
408
409    /// Trailing comment, if present.
410    pub fn trailing_comments(&self) -> Option<&str> {
411        self.comments.trailing()
412    }
413
414    /// Source span `[start_line, start_col, end_line, end_col]`, if available.
415    pub fn span(&self) -> &[i32] {
416        &self.comments.span
417    }
418
419    /// Comments for an enum value by number.
420    pub fn value_comments(&self, number: i32) -> Option<&Comments> {
421        self.value_comments.get(&number)
422    }
423
424    /// Comments for an enum value by name.
425    pub fn value_comments_by_name(&self, name: &str) -> Option<&Comments> {
426        self.value_comments_by_name.get(name)
427    }
428
429    /// Whether this enum is marked deprecated.
430    pub fn is_deprecated(&self) -> bool {
431        self.deprecated
432    }
433
434    /// Whether an enum value is marked deprecated.
435    pub fn is_value_deprecated(&self, number: i32) -> bool {
436        self.deprecated_values.contains(&number)
437    }
438}
439
440pub struct MessageDescriptorBuilder {
441    desc: MessageDescriptor,
442}
443
444impl MessageDescriptorBuilder {
445    pub fn field(mut self, field: FieldDescriptor) -> Self {
446        self.desc
447            .fields_by_name
448            .insert(field.name.clone(), field.number);
449        self.desc
450            .fields_by_json_name
451            .insert(field.json_name.clone(), field.number);
452        self.desc.fields.insert(field.number, field);
453        self
454    }
455
456    pub fn map_entry(mut self, yes: bool) -> Self {
457        self.desc.is_map_entry = yes;
458        self
459    }
460
461    /// Set comments on the message being built.
462    pub fn comments(mut self, comments: Comments) -> Self {
463        self.desc.comments = comments;
464        self
465    }
466
467    /// Set whether the message being built is deprecated.
468    pub fn deprecated(mut self, deprecated: bool) -> Self {
469        self.desc.deprecated = deprecated;
470        self
471    }
472
473    pub fn build(self) -> MessageDescriptor {
474        self.desc
475    }
476}
477
478#[derive(Clone, Debug, Default)]
479pub struct MethodDescriptor {
480    pub name: String,
481    pub input_type: String,
482    pub output_type: String,
483    pub client_streaming: bool,
484    pub server_streaming: bool,
485    /// Unrecognized `MethodOptions` tags (custom options).
486    pub options: Vec<DescriptorOption>,
487    /// Comments associated with this method.
488    pub comments: Comments,
489    /// Whether this method is marked deprecated in `MethodOptions`.
490    pub deprecated: bool,
491}
492
493impl MethodDescriptor {
494    /// Custom `MethodOptions` tag payload, if present.
495    pub fn custom_option(&self, number: u32) -> Option<&[u8]> {
496        self.options
497            .iter()
498            .find(|o| o.number == number)
499            .map(|o| o.value.as_slice())
500    }
501
502    /// Leading comment, if present.
503    pub fn leading_comments(&self) -> Option<&str> {
504        self.comments.leading()
505    }
506
507    /// Trailing comment, if present.
508    pub fn trailing_comments(&self) -> Option<&str> {
509        self.comments.trailing()
510    }
511
512    /// Source span `[start_line, start_col, end_line, end_col]`, if available.
513    pub fn span(&self) -> &[i32] {
514        &self.comments.span
515    }
516
517    /// Whether this method is marked deprecated.
518    pub fn is_deprecated(&self) -> bool {
519        self.deprecated
520    }
521}
522
523#[derive(Clone, Debug, Default)]
524pub struct ServiceDescriptor {
525    pub name: String,
526    pub full_name: String,
527    pub file_name: String,
528    pub methods: Vec<MethodDescriptor>,
529    /// Comments associated with this service.
530    pub comments: Comments,
531    /// Whether this service is marked deprecated in `ServiceOptions`.
532    pub deprecated: bool,
533    /// Unrecognized `ServiceOptions` tags (custom options).
534    pub options: Vec<DescriptorOption>,
535}
536
537impl ServiceDescriptor {
538    /// Custom `ServiceOptions` tag payload, if present.
539    pub fn custom_option(&self, number: u32) -> Option<&[u8]> {
540        self.options
541            .iter()
542            .find(|o| o.number == number)
543            .map(|o| o.value.as_slice())
544    }
545
546    /// Leading comment, if present.
547    pub fn leading_comments(&self) -> Option<&str> {
548        self.comments.leading()
549    }
550
551    /// Trailing comment, if present.
552    pub fn trailing_comments(&self) -> Option<&str> {
553        self.comments.trailing()
554    }
555
556    /// Source span `[start_line, start_col, end_line, end_col]`, if available.
557    pub fn span(&self) -> &[i32] {
558        &self.comments.span
559    }
560
561    /// Whether this service is marked deprecated.
562    pub fn is_deprecated(&self) -> bool {
563        self.deprecated
564    }
565}
566
567#[derive(Clone, Debug, Default)]
568pub struct FileDescriptor {
569    pub name: String,
570    pub package: String,
571    /// Unrecognized `FileOptions` tags (custom options).
572    pub options: Vec<DescriptorOption>,
573    /// Source code information, if available.
574    pub source_code_info: Option<SourceCodeInfo>,
575    /// Comments associated with the file.
576    pub comments: Comments,
577    /// Whether this file is marked deprecated in `FileOptions`.
578    pub deprecated: bool,
579}
580
581impl FileDescriptor {
582    /// Custom `FileOptions` tag payload, if present.
583    pub fn custom_option(&self, number: u32) -> Option<&[u8]> {
584        self.options
585            .iter()
586            .find(|o| o.number == number)
587            .map(|o| o.value.as_slice())
588    }
589
590    /// Source code information, if present.
591    pub fn source_code_info(&self) -> Option<&SourceCodeInfo> {
592        self.source_code_info.as_ref()
593    }
594
595    /// Leading comment, if present.
596    pub fn leading_comments(&self) -> Option<&str> {
597        self.comments.leading()
598    }
599
600    /// Trailing comment, if present.
601    pub fn trailing_comments(&self) -> Option<&str> {
602        self.comments.trailing()
603    }
604
605    /// Whether this file is marked deprecated.
606    pub fn is_deprecated(&self) -> bool {
607        self.deprecated
608    }
609}
610
611#[derive(Clone, Copy, Debug)]
612struct FileMetadata {
613    edition: i32,
614    features: RawFeatures,
615}
616
617#[derive(Clone, Copy, Debug)]
618struct SymbolMetadata {
619    features: RawFeatures,
620    declared_visibility: u32,
621    effective_visibility: u32,
622}
623
624#[derive(Clone, Debug, Default)]
625pub struct DescriptorPool {
626    messages: BTreeMap<String, Arc<MessageDescriptor>>,
627    enums: BTreeMap<String, Arc<EnumDescriptor>>,
628    extensions_by_name: BTreeMap<String, (String, u32, String)>,
629    services: BTreeMap<String, Arc<ServiceDescriptor>>,
630    files: BTreeMap<String, Arc<FileDescriptor>>,
631    /// file name -> public import file names
632    public_imports: BTreeMap<String, Vec<String>>,
633    file_metadata: BTreeMap<String, FileMetadata>,
634    symbol_metadata: BTreeMap<String, SymbolMetadata>,
635}
636
637impl DescriptorPool {
638    pub fn new() -> Self {
639        Self::default()
640    }
641
642    /// Fully-qualified names of every message in the pool.
643    pub fn collect_names(&self) -> Vec<String> {
644        self.messages.keys().cloned().collect()
645    }
646
647    pub fn get_message(&self, full_name: &str) -> Option<Arc<MessageDescriptor>> {
648        self.messages
649            .get(full_name.trim_start_matches('.'))
650            .cloned()
651    }
652
653    pub fn get_enum(&self, full_name: &str) -> Option<Arc<EnumDescriptor>> {
654        self.enums.get(full_name.trim_start_matches('.')).cloned()
655    }
656
657    fn lookup_file_metadata(&self, file_name: &str) -> Option<&FileMetadata> {
658        let file = self.get_file(file_name)?;
659        self.file_metadata.get(&file.name)
660    }
661
662    /// Edition number for a file loaded from a descriptor set.
663    pub fn file_edition(&self, file_name: &str) -> Option<i32> {
664        self.lookup_file_metadata(file_name).map(|m| m.edition)
665    }
666
667    /// Resolved file JSON format (`ALLOW = 1`, `LEGACY_BEST_EFFORT = 2`).
668    pub fn file_json_format(&self, file_name: &str) -> Option<u32> {
669        self.lookup_file_metadata(file_name)
670            .map(|m| m.features.json_format)
671    }
672
673    /// Resolved file naming style (`STYLE2024 = 1`, `STYLE_LEGACY = 2`).
674    pub fn file_naming_style(&self, file_name: &str) -> Option<u32> {
675        self.lookup_file_metadata(file_name)
676            .map(|m| m.features.naming_style)
677    }
678
679    /// Resolved file default visibility (`EXPORT_ALL = 1`, `EXPORT_TOP_LEVEL = 2`, `LOCAL_ALL = 3`).
680    pub fn file_default_symbol_visibility(&self, file_name: &str) -> Option<u32> {
681        self.lookup_file_metadata(file_name)
682            .map(|m| m.features.default_symbol_visibility)
683    }
684
685    /// Resolved JSON format of a message or enum loaded from a descriptor set.
686    pub fn symbol_json_format(&self, full_name: &str) -> Option<u32> {
687        self.symbol_metadata
688            .get(full_name.trim_start_matches('.'))
689            .map(|m| m.features.json_format)
690    }
691
692    /// Resolved naming style of a message or enum loaded from a descriptor set.
693    pub fn symbol_naming_style(&self, full_name: &str) -> Option<u32> {
694        self.symbol_metadata
695            .get(full_name.trim_start_matches('.'))
696            .map(|m| m.features.naming_style)
697    }
698
699    /// Declared visibility (`UNSET = 0`, `LOCAL = 1`, `EXPORT = 2`) of a message or enum.
700    pub fn declared_symbol_visibility(&self, full_name: &str) -> Option<u32> {
701        self.symbol_metadata
702            .get(full_name.trim_start_matches('.'))
703            .map(|m| m.declared_visibility)
704    }
705
706    /// Effective visibility (`LOCAL = 1`, `EXPORT = 2`) of a message or enum.
707    pub fn effective_symbol_visibility(&self, full_name: &str) -> Option<u32> {
708        self.symbol_metadata
709            .get(full_name.trim_start_matches('.'))
710            .map(|m| m.effective_visibility)
711    }
712
713    /// Fully-qualified names of every enum in the pool.
714    pub fn collect_enum_names(&self) -> Vec<String> {
715        self.enums.keys().cloned().collect()
716    }
717
718    pub(crate) fn public_import_files(&self, targets: &[String]) -> Vec<String> {
719        let mut out = Vec::new();
720        for t in targets {
721            for (file, pubs) in &self.public_imports {
722                if file_name_matches(t, file) {
723                    for p in pubs {
724                        if !out.contains(p) {
725                            out.push(p.clone());
726                        }
727                    }
728                }
729            }
730        }
731        out
732    }
733
734    /// Look up an extension by its full name (`package.field`).
735    pub fn get_extension(
736        &self,
737        full_name: &str,
738    ) -> Option<(Arc<MessageDescriptor>, FieldDescriptor)> {
739        let key = full_name.trim_start_matches('.');
740        let (extendee, number, _) = self.extensions_by_name.get(key)?;
741        let desc = self.get_message(extendee)?;
742        let field = desc.field(*number)?.clone();
743        Some((desc, field))
744    }
745
746    /// File that declares the extension of `containing_type` numbered `number`.
747    pub fn file_for_extension(&self, containing_type: &str, number: u32) -> Option<&str> {
748        let ty = containing_type.trim_start_matches('.');
749        self.extensions_by_name
750            .values()
751            .find(|(extendee, n, _)| extendee == ty && *n == number)
752            .map(|(_, _, file)| file.as_str())
753            .filter(|file| !file.is_empty())
754    }
755
756    /// Field numbers of known extensions of `containing_type`, sorted.
757    pub fn extension_numbers_of(&self, containing_type: &str) -> Vec<u32> {
758        let ty = containing_type.trim_start_matches('.');
759        let mut nums: Vec<u32> = self
760            .extensions_by_name
761            .values()
762            .filter(|(extendee, _, _)| extendee == ty)
763            .map(|(_, n, _)| *n)
764            .collect();
765        nums.sort_unstable();
766        nums.dedup();
767        nums
768    }
769
770    pub fn register_message(&mut self, desc: MessageDescriptor) -> Arc<MessageDescriptor> {
771        let key = desc.full_name.clone();
772        let _ = self.symbol_metadata.remove(&key);
773        let arc = Arc::new(desc);
774        self.messages.insert(key, arc.clone());
775        arc
776    }
777
778    pub fn get_service(&self, full_name: &str) -> Option<Arc<ServiceDescriptor>> {
779        self.services
780            .get(full_name.trim_start_matches('.'))
781            .cloned()
782    }
783
784    pub fn get_file(&self, name: &str) -> Option<Arc<FileDescriptor>> {
785        self.files.get(name).cloned().or_else(|| {
786            self.files
787                .values()
788                .find(|f| file_name_matches(name, &f.name))
789                .cloned()
790        })
791    }
792
793    pub fn collect_services(&self) -> Vec<Arc<ServiceDescriptor>> {
794        self.services.values().cloned().collect()
795    }
796
797    pub fn register_enum(&mut self, desc: EnumDescriptor) -> Arc<EnumDescriptor> {
798        let key = desc.full_name.clone();
799        let _ = self.symbol_metadata.remove(&key);
800        let arc = Arc::new(desc);
801        self.enums.insert(key, arc.clone());
802        arc
803    }
804
805    /// Parse a serialized `google.protobuf.FileDescriptorSet`.
806    pub fn from_file_descriptor_set(bytes: &[u8]) -> Result<Self, ParseError> {
807        let files = parse_file_descriptor_set(bytes)?;
808        let mut raw: BTreeMap<String, RawMessage> = BTreeMap::new();
809        let mut raw_enums: BTreeMap<String, RawEnum> = BTreeMap::new();
810        let mut extensions = Vec::new();
811        for file in &files {
812            collect_raw(file, &mut raw, &mut raw_enums, &mut extensions);
813        }
814        let edition2024_files: BTreeSet<String> = files
815            .iter()
816            .filter(|file| file.edition == 1001)
817            .map(|file| file.name.clone())
818            .collect();
819        let mut pool = resolve_pool(raw, raw_enums, extensions, &edition2024_files)?;
820        for file in &files {
821            pool.file_metadata.insert(
822                file.name.clone(),
823                FileMetadata {
824                    edition: file.edition,
825                    features: file.features,
826                },
827            );
828            pool.files.insert(
829                file.name.clone(),
830                Arc::new(FileDescriptor {
831                    name: file.name.clone(),
832                    package: file.package.clone(),
833                    options: file.options.clone(),
834                    source_code_info: file.source_code_info.clone(),
835                    comments: file.comments.clone(),
836                    deprecated: file.deprecated,
837                }),
838            );
839            let pubs: Vec<String> = file
840                .public_dependency
841                .iter()
842                .filter_map(|&i| file.dependencies.get(i as usize).cloned())
843                .collect();
844            if !pubs.is_empty() {
845                pool.public_imports.insert(file.name.clone(), pubs);
846            }
847            for svc in &file.services {
848                for method in &svc.methods {
849                    for name in [&method.input_type, &method.output_type] {
850                        if let Some(target) = pool.get_message(name.trim_start_matches('.')) {
851                            check_symbol_visible_from_file(
852                                &file.name,
853                                &target.file_name,
854                                name.trim_start_matches('.'),
855                                &pool.symbol_metadata,
856                            )?;
857                        }
858                    }
859                }
860                let desc = Arc::new(ServiceDescriptor {
861                    name: svc.name.clone(),
862                    full_name: svc.full_name.clone(),
863                    file_name: file.name.clone(),
864                    methods: svc.methods.clone(),
865                    comments: svc.comments.clone(),
866                    deprecated: svc.deprecated,
867                    options: svc.options.clone(),
868                });
869                pool.services.insert(desc.full_name.clone(), desc);
870            }
871        }
872        validate_edition2024_references(&files, &pool)?;
873        Ok(pool)
874    }
875}
876
877#[derive(Clone, Debug)]
878pub enum Value {
879    Double(f64),
880    Float(f32),
881    Int32(i32),
882    Int64(i64),
883    Uint32(u32),
884    Uint64(u64),
885    Bool(bool),
886    String(ProtoString),
887    Bytes(ProtoBytes),
888    Enum(i32),
889    Message(DynamicMessage),
890}
891
892impl PartialEq for Value {
893    fn eq(&self, other: &Self) -> bool {
894        match (self, other) {
895            (Self::Double(a), Self::Double(b)) => a.to_bits() == b.to_bits(),
896            (Self::Float(a), Self::Float(b)) => a.to_bits() == b.to_bits(),
897            (Self::Int32(a), Self::Int32(b)) => a == b,
898            (Self::Int64(a), Self::Int64(b)) => a == b,
899            (Self::Uint32(a), Self::Uint32(b)) => a == b,
900            (Self::Uint64(a), Self::Uint64(b)) => a == b,
901            (Self::Bool(a), Self::Bool(b)) => a == b,
902            (Self::String(a), Self::String(b)) => a == b,
903            (Self::Bytes(a), Self::Bytes(b)) => a == b,
904            (Self::Enum(a), Self::Enum(b)) => a == b,
905            (Self::Message(a), Self::Message(b)) => a == b,
906            _ => false,
907        }
908    }
909}
910
911impl Value {
912    pub(crate) fn is_implicit_default(&self) -> bool {
913        match self {
914            Self::Double(v) => v.to_bits() == 0f64.to_bits(),
915            Self::Float(v) => v.to_bits() == 0f32.to_bits(),
916            Self::Int32(v) | Self::Enum(v) => *v == 0,
917            Self::Int64(v) => *v == 0,
918            Self::Uint32(v) => *v == 0,
919            Self::Uint64(v) => *v == 0,
920            Self::Bool(v) => !*v,
921            Self::String(v) => v.is_empty(),
922            Self::Bytes(v) => v.is_empty(),
923            Self::Message(_) => false,
924        }
925    }
926}
927
928#[derive(Clone, Debug, PartialEq)]
929pub(crate) enum FieldValue {
930    Singular(Value),
931    Repeated(Vec<Value>),
932    Map(BTreeMap<MapKeyValue, Value>),
933}
934
935#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
936pub enum MapKeyValue {
937    I32(i32),
938    I64(i64),
939    U32(u32),
940    U64(u64),
941    Bool(bool),
942    String(ProtoString),
943}
944
945#[derive(Clone)]
946pub struct DynamicMessage {
947    desc: Arc<MessageDescriptor>,
948    pool: Option<Arc<DescriptorPool>>,
949    fields: BTreeMap<u32, FieldValue>,
950    unknown: UnknownFields,
951}
952
953impl PartialEq for DynamicMessage {
954    fn eq(&self, other: &Self) -> bool {
955        self.desc.full_name == other.desc.full_name
956            && self.fields == other.fields
957            && self.unknown == other.unknown
958    }
959}
960
961impl fmt::Debug for DynamicMessage {
962    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
963        f.debug_struct("DynamicMessage")
964            .field("type", &self.desc.full_name)
965            .field("fields", &self.fields)
966            .finish()
967    }
968}
969
970impl DynamicMessage {
971    pub fn new(desc: Arc<MessageDescriptor>) -> Self {
972        Self {
973            desc,
974            pool: None,
975            fields: BTreeMap::new(),
976            unknown: UnknownFields::default(),
977        }
978    }
979
980    pub fn set_pool(&mut self, pool: Arc<DescriptorPool>) {
981        self.pool = Some(pool);
982    }
983
984    pub fn pool(&self) -> Option<&Arc<DescriptorPool>> {
985        self.pool.as_ref()
986    }
987
988    pub fn descriptor(&self) -> &Arc<MessageDescriptor> {
989        &self.desc
990    }
991
992    pub(crate) fn raw_fields(&self) -> &BTreeMap<u32, FieldValue> {
993        &self.fields
994    }
995
996    pub fn parse_with(desc: Arc<MessageDescriptor>, data: &[u8]) -> Result<Self, ParseError> {
997        Self::parse_with_pool(desc, None, data)
998    }
999
1000    pub fn parse_with_pool(
1001        desc: Arc<MessageDescriptor>,
1002        pool: Option<Arc<DescriptorPool>>,
1003        data: &[u8],
1004    ) -> Result<Self, ParseError> {
1005        Self::parse_with_pool_depth(desc, pool, data, 0, true)
1006    }
1007
1008    pub(crate) fn parse_with_pool_depth(
1009        desc: Arc<MessageDescriptor>,
1010        pool: Option<Arc<DescriptorPool>>,
1011        data: &[u8],
1012        depth: u32,
1013        enforce_required: bool,
1014    ) -> Result<Self, ParseError> {
1015        let mut msg = Self::new(desc);
1016        msg.pool = pool;
1017        msg.merge_bytes(data, enforce_required, depth)?;
1018        Ok(msg)
1019    }
1020
1021    pub fn unknown_fields(&self) -> &UnknownFields {
1022        &self.unknown
1023    }
1024
1025    pub fn has(&self, number: u32) -> bool {
1026        self.fields.contains_key(&number)
1027    }
1028
1029    pub fn get_singular(&self, number: u32) -> Option<&Value> {
1030        match self.fields.get(&number) {
1031            Some(FieldValue::Singular(v)) => Some(v),
1032            _ => None,
1033        }
1034    }
1035
1036    pub fn get_repeated(&self, number: u32) -> Option<&[Value]> {
1037        match self.fields.get(&number) {
1038            Some(FieldValue::Repeated(v)) => Some(v),
1039            _ => None,
1040        }
1041    }
1042
1043    pub fn get_map(&self, number: u32) -> Option<&BTreeMap<MapKeyValue, Value>> {
1044        match self.fields.get(&number) {
1045            Some(FieldValue::Map(v)) => Some(v),
1046            _ => None,
1047        }
1048    }
1049
1050    pub fn set(&mut self, number: u32, value: Value) {
1051        if let Some(field) = self.desc.field(number) {
1052            if let Some(idx) = field.oneof_index {
1053                if let Some(members) = self.desc.oneofs.get(idx as usize) {
1054                    for n in members.clone() {
1055                        if n != number {
1056                            self.fields.remove(&n);
1057                        }
1058                    }
1059                }
1060            }
1061        }
1062        self.fields.insert(number, FieldValue::Singular(value));
1063    }
1064
1065    pub fn set_extension(&mut self, number: u32, value: Value) {
1066        self.set(number, value);
1067    }
1068
1069    pub fn get_extension(&self, number: u32) -> Option<&Value> {
1070        self.get_singular(number)
1071    }
1072
1073    pub fn has_extension(&self, number: u32) -> bool {
1074        self.has(number)
1075    }
1076
1077    pub fn clear_extension(&mut self, number: u32) {
1078        self.clear_field(number);
1079    }
1080
1081    pub fn to_json(&self) -> Result<String, SerializeError> {
1082        crate::json::encode(self)
1083    }
1084
1085    pub fn from_json(desc: Arc<MessageDescriptor>, json: &str) -> Result<Self, ParseError> {
1086        crate::json::decode(desc, json, false, None)
1087    }
1088
1089    pub fn from_json_ignore_unknown(
1090        desc: Arc<MessageDescriptor>,
1091        json: &str,
1092    ) -> Result<Self, ParseError> {
1093        crate::json::decode(desc, json, true, None)
1094    }
1095
1096    pub fn from_json_with_pool(
1097        desc: Arc<MessageDescriptor>,
1098        pool: Option<Arc<DescriptorPool>>,
1099        json: &str,
1100        ignore_unknown: bool,
1101    ) -> Result<Self, ParseError> {
1102        crate::json::decode(desc, json, ignore_unknown, pool)
1103    }
1104
1105    pub fn to_text(&self) -> Result<String, SerializeError> {
1106        crate::text::encode(self)
1107    }
1108
1109    pub fn to_text_with_unknown(&self) -> Result<String, SerializeError> {
1110        crate::text::encode_with_unknown(self)
1111    }
1112
1113    pub fn from_text(desc: Arc<MessageDescriptor>, text: &str) -> Result<Self, ParseError> {
1114        crate::text::decode(desc, text)
1115    }
1116
1117    pub fn from_text_with_pool(
1118        desc: Arc<MessageDescriptor>,
1119        pool: Option<Arc<DescriptorPool>>,
1120        text: &str,
1121    ) -> Result<Self, ParseError> {
1122        crate::text::decode_with_pool(desc, text, pool)
1123    }
1124
1125    pub fn push(&mut self, number: u32, value: Value) {
1126        match self.fields.entry(number) {
1127            std::collections::btree_map::Entry::Occupied(mut e) => match e.get_mut() {
1128                FieldValue::Repeated(v) => v.push(value),
1129                other => *other = FieldValue::Repeated(vec![value]),
1130            },
1131            std::collections::btree_map::Entry::Vacant(e) => {
1132                e.insert(FieldValue::Repeated(vec![value]));
1133            }
1134        }
1135    }
1136
1137    pub fn insert_map(&mut self, number: u32, key: MapKeyValue, value: Value) {
1138        match self.fields.entry(number) {
1139            std::collections::btree_map::Entry::Occupied(mut e) => match e.get_mut() {
1140                FieldValue::Map(m) => {
1141                    m.insert(key, value);
1142                }
1143                other => {
1144                    let mut m = BTreeMap::new();
1145                    m.insert(key, value);
1146                    *other = FieldValue::Map(m);
1147                }
1148            },
1149            std::collections::btree_map::Entry::Vacant(e) => {
1150                let mut m = BTreeMap::new();
1151                m.insert(key, value);
1152                e.insert(FieldValue::Map(m));
1153            }
1154        }
1155    }
1156
1157    pub fn clear_field(&mut self, number: u32) {
1158        self.fields.remove(&number);
1159    }
1160
1161    fn merge_bytes(
1162        &mut self,
1163        data: &[u8],
1164        enforce_required: bool,
1165        depth: u32,
1166    ) -> Result<(), ParseError> {
1167        if depth > RECURSION_LIMIT {
1168            return Err(ParseError::new("recursion limit exceeded"));
1169        }
1170        let mut pos = 0;
1171        while pos < data.len() {
1172            let (number, wire) = decode_tag(data, &mut pos)?;
1173            if self.desc.message_set_wire_format && number == 1 {
1174                self.merge_message_set_item(data, &mut pos, wire, depth)?;
1175                continue;
1176            }
1177            match self.desc.field(number).cloned() {
1178                None => {
1179                    self.unknown
1180                        .fields
1181                        .push(wire::capture_unknown(data, &mut pos, number, wire)?);
1182                }
1183                Some(field) => self.merge_field(&field, data, &mut pos, wire, depth)?,
1184            }
1185        }
1186        if enforce_required {
1187            for f in self.desc.fields.values() {
1188                if f.cardinality == Cardinality::Required && !self.fields.contains_key(&f.number) {
1189                    return Err(ParseError::new("missing required field"));
1190                }
1191            }
1192        }
1193        Ok(())
1194    }
1195
1196    fn merge_field(
1197        &mut self,
1198        field: &FieldDescriptor,
1199        data: &[u8],
1200        pos: &mut usize,
1201        wire: u32,
1202        depth: u32,
1203    ) -> Result<(), ParseError> {
1204        let expected = if field.delimited {
1205            WIRE_SGROUP
1206        } else {
1207            field.field_type.default_wire()
1208        };
1209        let packed_ok = field.cardinality == Cardinality::Repeated
1210            && field.field_type.is_packable()
1211            && wire == WIRE_LEN;
1212        if wire != expected && !packed_ok && !(field.is_map && wire == WIRE_LEN) {
1213            self.unknown
1214                .fields
1215                .push(wire::capture_unknown(data, pos, field.number, wire)?);
1216            return Ok(());
1217        }
1218        if field.is_map {
1219            let payload = read_len_bytes(data, pos)?;
1220            let entry = field_message_desc(field, self.pool.as_ref())?;
1221            let (k, v) = decode_map_entry(&entry, payload, self.pool.clone(), depth)?;
1222            self.insert_map(field.number, k, v);
1223            return Ok(());
1224        }
1225        if field.cardinality == Cardinality::Repeated {
1226            if packed_ok {
1227                let payload = read_len_bytes(data, pos)?;
1228                let mut p = 0;
1229                let leaf_wire = field.field_type.default_wire();
1230                while p < payload.len() {
1231                    let v =
1232                        decode_leaf(field, payload, &mut p, leaf_wire, self.pool.clone(), depth)?;
1233                    match v {
1234                        Value::Enum(n) if is_closed_unknown(field, n) => {
1235                            self.unknown.fields.push(UnknownField::Varint {
1236                                number: field.number,
1237                                value: n as u64,
1238                            });
1239                        }
1240                        value => self.push(field.number, value),
1241                    }
1242                }
1243                return Ok(());
1244            }
1245            let v = decode_leaf(field, data, pos, wire, self.pool.clone(), depth)?;
1246            if let Value::Enum(n) = v {
1247                if is_closed_unknown(field, n) {
1248                    self.unknown.fields.push(UnknownField::Varint {
1249                        number: field.number,
1250                        value: n as u64,
1251                    });
1252                    return Ok(());
1253                }
1254            }
1255            self.push(field.number, v);
1256            return Ok(());
1257        }
1258        let v = decode_leaf(field, data, pos, wire, self.pool.clone(), depth)?;
1259        if let Value::Enum(n) = &v {
1260            if is_closed_unknown(field, *n) {
1261                self.unknown.fields.push(UnknownField::Varint {
1262                    number: field.number,
1263                    value: *n as u64,
1264                });
1265                return Ok(());
1266            }
1267        }
1268        if let Value::Message(incoming) = v {
1269            match self.fields.get_mut(&field.number) {
1270                Some(FieldValue::Singular(Value::Message(existing))) => {
1271                    existing.merge_from_dyn(&incoming);
1272                }
1273                _ => {
1274                    self.set(field.number, Value::Message(incoming));
1275                }
1276            }
1277            return Ok(());
1278        }
1279        self.set(field.number, v);
1280        Ok(())
1281    }
1282
1283    pub(crate) fn merge_from_dyn(&mut self, src: &DynamicMessage) {
1284        for (n, val) in &src.fields {
1285            match val {
1286                FieldValue::Singular(Value::Message(child)) => match self.fields.get_mut(n) {
1287                    Some(FieldValue::Singular(Value::Message(dst))) => dst.merge_from_dyn(child),
1288                    _ => {
1289                        self.fields
1290                            .insert(*n, FieldValue::Singular(Value::Message(child.clone())));
1291                    }
1292                },
1293                FieldValue::Repeated(items) => match self.fields.get_mut(n) {
1294                    Some(FieldValue::Repeated(dst)) => dst.extend(items.iter().cloned()),
1295                    _ => {
1296                        self.fields.insert(*n, FieldValue::Repeated(items.clone()));
1297                    }
1298                },
1299                FieldValue::Map(items) => match self.fields.get_mut(n) {
1300                    Some(FieldValue::Map(dst)) => {
1301                        dst.extend(items.iter().map(|(k, v)| (k.clone(), v.clone())));
1302                    }
1303                    _ => {
1304                        self.fields.insert(*n, FieldValue::Map(items.clone()));
1305                    }
1306                },
1307                other => {
1308                    self.fields.insert(*n, other.clone());
1309                }
1310            }
1311        }
1312        self.unknown
1313            .fields
1314            .extend(src.unknown.fields.iter().cloned());
1315    }
1316
1317    fn compute_size(&self) -> u64 {
1318        let mut n = 0u64;
1319        for (number, val) in &self.fields {
1320            if let Some(field) = self.desc.field(*number) {
1321                n += field_value_size(field, val);
1322            } else {
1323                n += untyped_size(*number, val);
1324            }
1325        }
1326        n + self.unknown.encoded_len()
1327    }
1328
1329    fn write_to(&self, out: &mut impl crate::wire::WireOut) {
1330        if self.desc.message_set_wire_format {
1331            self.write_message_set(out);
1332            self.unknown.encode(out);
1333            return;
1334        }
1335        for (number, val) in &self.fields {
1336            if let Some(field) = self.desc.field(*number) {
1337                write_field_value(field, val, out);
1338            } else {
1339                write_untyped(*number, val, out);
1340            }
1341        }
1342        self.unknown.encode(out);
1343    }
1344
1345    fn merge_message_set_item(
1346        &mut self,
1347        data: &[u8],
1348        pos: &mut usize,
1349        wire: u32,
1350        depth: u32,
1351    ) -> Result<(), ParseError> {
1352        let mut type_id = 0u32;
1353        let mut payload = Vec::new();
1354        if wire == WIRE_LEN {
1355            let inner = read_len_bytes(data, pos)?;
1356            let mut p = 0;
1357            while p < inner.len() {
1358                let (n, w) = decode_tag(inner, &mut p)?;
1359                match (n, w) {
1360                    (2, WIRE_VARINT) => type_id = decode_varint(inner, &mut p)? as u32,
1361                    (3, WIRE_LEN) => payload = read_len_bytes(inner, &mut p)?.to_vec(),
1362                    _ => wire::skip_field(inner, &mut p, w)?,
1363                }
1364            }
1365        } else if wire == WIRE_SGROUP {
1366            loop {
1367                if *pos >= data.len() {
1368                    return Err(ParseError::new("truncated message set"));
1369                }
1370                let (n, w) = decode_tag(data, pos)?;
1371                if w == WIRE_EGROUP && n == 1 {
1372                    break;
1373                }
1374                match (n, w) {
1375                    (2, WIRE_VARINT) => type_id = decode_varint(data, pos)? as u32,
1376                    (3, WIRE_LEN) => payload = read_len_bytes(data, pos)?.to_vec(),
1377                    _ => self
1378                        .unknown
1379                        .fields
1380                        .push(wire::capture_unknown(data, pos, n, w)?),
1381                }
1382            }
1383        } else {
1384            self.unknown
1385                .fields
1386                .push(wire::capture_unknown(data, pos, 1, wire)?);
1387            return Ok(());
1388        }
1389        if type_id == 0 {
1390            return Ok(());
1391        }
1392        if let Some(field) = self.desc.field(type_id).cloned() {
1393            let mut inner = DynamicMessage::new(field_message_desc(&field, self.pool.as_ref())?);
1394            if let Some(p) = self.pool.clone() {
1395                inner.set_pool(p);
1396            }
1397            inner.merge_bytes(&payload, false, depth + 1)?;
1398            self.set(type_id, Value::Message(inner));
1399        } else {
1400            self.unknown.fields.push(UnknownField::Group {
1401                number: 1,
1402                fields: {
1403                    let mut u = UnknownFields::default();
1404                    u.fields.push(UnknownField::Varint {
1405                        number: 2,
1406                        value: u64::from(type_id),
1407                    });
1408                    u.fields.push(UnknownField::LengthDelimited {
1409                        number: 3,
1410                        value: payload,
1411                    });
1412                    u
1413                },
1414            });
1415        }
1416        Ok(())
1417    }
1418
1419    fn write_message_set(&self, out: &mut impl crate::wire::WireOut) {
1420        for (number, val) in &self.fields {
1421            let FieldValue::Singular(Value::Message(m)) = val else {
1422                continue;
1423            };
1424            let mut inner = Vec::new();
1425            m.write_to(&mut inner);
1426            encode_tag(out, 1, WIRE_SGROUP);
1427            encode_tag(out, 2, WIRE_VARINT);
1428            encode_varint(out, u64::from(*number));
1429            encode_len_field(out, 3, &inner);
1430            encode_tag(out, 1, WIRE_EGROUP);
1431        }
1432    }
1433}
1434
1435fn is_closed_unknown(field: &FieldDescriptor, n: i32) -> bool {
1436    field
1437        .enum_ty
1438        .as_ref()
1439        .is_some_and(|e| e.closed && !e.values.contains_key(&n))
1440}
1441
1442fn field_message_desc(
1443    field: &FieldDescriptor,
1444    pool: Option<&Arc<DescriptorPool>>,
1445) -> Result<Arc<MessageDescriptor>, ParseError> {
1446    if let (Some(tn), Some(pool)) = (field.type_name.as_deref(), pool) {
1447        if let Some(m) = pool.get_message(tn.trim_start_matches('.')) {
1448            return Ok(m);
1449        }
1450    }
1451    if let Some(m) = &field.message {
1452        return Ok(m.clone());
1453    }
1454    Err(ParseError::new("unresolved message type"))
1455}
1456
1457fn decode_leaf(
1458    field: &FieldDescriptor,
1459    data: &[u8],
1460    pos: &mut usize,
1461    wire: u32,
1462    pool: Option<Arc<DescriptorPool>>,
1463    depth: u32,
1464) -> Result<Value, ParseError> {
1465    if field.delimited || field.field_type == FieldType::Group {
1466        return decode_group(field, data, pos, pool, depth);
1467    }
1468    match field.field_type {
1469        FieldType::Message => {
1470            if wire != WIRE_LEN {
1471                return Err(ParseError::new("bad wire type for message"));
1472            }
1473            let payload = read_len_bytes(data, pos)?;
1474            let desc = field_message_desc(field, pool.as_ref())?;
1475            Ok(Value::Message(DynamicMessage::parse_with_pool_depth(
1476                desc,
1477                pool,
1478                payload,
1479                depth + 1,
1480                true,
1481            )?))
1482        }
1483        FieldType::Group => decode_group(field, data, pos, pool, depth),
1484        FieldType::String => {
1485            if wire != WIRE_LEN {
1486                return Err(ParseError::new("bad wire type for string"));
1487            }
1488            let bytes = read_len_bytes(data, pos)?;
1489            if field.utf8_validate {
1490                std::str::from_utf8(bytes).map_err(|_| ParseError::new("invalid utf-8"))?;
1491            }
1492            Ok(Value::String(ProtoString::from_bytes(bytes)))
1493        }
1494        FieldType::Bytes => {
1495            if wire != WIRE_LEN {
1496                return Err(ParseError::new("bad wire type for bytes"));
1497            }
1498            Ok(Value::Bytes(ProtoBytes::from(read_len_bytes(data, pos)?)))
1499        }
1500        FieldType::Double => Ok(Value::Double(f64::from_bits(read_fixed64(data, pos)?))),
1501        FieldType::Float => Ok(Value::Float(f32::from_bits(read_fixed32(data, pos)?))),
1502        FieldType::Fixed64 => Ok(Value::Uint64(read_fixed64(data, pos)?)),
1503        FieldType::Sfixed64 => Ok(Value::Int64(read_fixed64(data, pos)? as i64)),
1504        FieldType::Fixed32 => Ok(Value::Uint32(read_fixed32(data, pos)?)),
1505        FieldType::Sfixed32 => Ok(Value::Int32(read_fixed32(data, pos)? as i32)),
1506        FieldType::Bool => Ok(Value::Bool(decode_varint(data, pos)? != 0)),
1507        FieldType::Int32 => Ok(Value::Int32(decode_varint(data, pos)? as i32)),
1508        FieldType::Int64 => Ok(Value::Int64(decode_varint(data, pos)? as i64)),
1509        FieldType::Uint32 => Ok(Value::Uint32(decode_varint(data, pos)? as u32)),
1510        FieldType::Uint64 => Ok(Value::Uint64(decode_varint(data, pos)?)),
1511        FieldType::Sint32 => Ok(Value::Int32(wire::decode_zigzag32(decode_varint(
1512            data, pos,
1513        )?))),
1514        FieldType::Sint64 => Ok(Value::Int64(wire::decode_zigzag64(decode_varint(
1515            data, pos,
1516        )?))),
1517        FieldType::Enum => Ok(Value::Enum(decode_varint(data, pos)? as i32)),
1518    }
1519}
1520
1521fn decode_group(
1522    field: &FieldDescriptor,
1523    data: &[u8],
1524    pos: &mut usize,
1525    pool: Option<Arc<DescriptorPool>>,
1526    depth: u32,
1527) -> Result<Value, ParseError> {
1528    if depth + 1 > RECURSION_LIMIT {
1529        return Err(ParseError::new("recursion limit exceeded"));
1530    }
1531    let desc = field_message_desc(field, pool.as_ref())?;
1532    let mut msg = DynamicMessage::new(desc);
1533    msg.pool = pool;
1534    loop {
1535        if *pos >= data.len() {
1536            return Err(ParseError::new("truncated group"));
1537        }
1538        let (n, w) = decode_tag(data, pos)?;
1539        if w == WIRE_EGROUP {
1540            if n != field.number {
1541                return Err(ParseError::new("mismatched end-group"));
1542            }
1543            break;
1544        }
1545        match msg.desc.field(n).cloned() {
1546            None => msg
1547                .unknown
1548                .fields
1549                .push(wire::capture_unknown(data, pos, n, w)?),
1550            Some(f) => msg.merge_field(&f, data, pos, w, depth + 1)?,
1551        }
1552    }
1553    Ok(Value::Message(msg))
1554}
1555
1556fn decode_map_entry(
1557    entry: &MessageDescriptor,
1558    payload: &[u8],
1559    pool: Option<Arc<DescriptorPool>>,
1560    depth: u32,
1561) -> Result<(MapKeyValue, Value), ParseError> {
1562    let msg = DynamicMessage::parse_with_pool_depth(
1563        Arc::new(entry.clone()),
1564        pool.clone(),
1565        payload,
1566        depth + 1,
1567        false,
1568    )?;
1569    let key_field = entry
1570        .field(1)
1571        .ok_or_else(|| ParseError::new("map entry missing key"))?;
1572    let val_field = entry
1573        .field(2)
1574        .ok_or_else(|| ParseError::new("map entry missing value"))?;
1575    let key = match msg.get_singular(1) {
1576        Some(v) => value_to_map_key(v)?,
1577        None => default_map_key(key_field.field_type)?,
1578    };
1579    let value = match msg.get_singular(2) {
1580        Some(v) => v.clone(),
1581        None => default_value(val_field, pool.as_ref())?,
1582    };
1583    Ok((key, value))
1584}
1585
1586fn value_to_map_key(v: &Value) -> Result<MapKeyValue, ParseError> {
1587    Ok(match v {
1588        Value::Int32(n) => MapKeyValue::I32(*n),
1589        Value::Int64(n) => MapKeyValue::I64(*n),
1590        Value::Uint32(n) => MapKeyValue::U32(*n),
1591        Value::Uint64(n) => MapKeyValue::U64(*n),
1592        Value::Bool(n) => MapKeyValue::Bool(*n),
1593        Value::String(s) => MapKeyValue::String(s.clone()),
1594        _ => return Err(ParseError::new("invalid map key type")),
1595    })
1596}
1597
1598pub(crate) fn default_map_key(ty: FieldType) -> Result<MapKeyValue, ParseError> {
1599    Ok(match ty {
1600        FieldType::Int32 | FieldType::Sint32 | FieldType::Sfixed32 => MapKeyValue::I32(0),
1601        FieldType::Int64 | FieldType::Sint64 | FieldType::Sfixed64 => MapKeyValue::I64(0),
1602        FieldType::Uint32 | FieldType::Fixed32 => MapKeyValue::U32(0),
1603        FieldType::Uint64 | FieldType::Fixed64 => MapKeyValue::U64(0),
1604        FieldType::Bool => MapKeyValue::Bool(false),
1605        FieldType::String => MapKeyValue::String(ProtoString::new()),
1606        _ => return Err(ParseError::new("invalid map key type")),
1607    })
1608}
1609
1610pub(crate) fn default_value(
1611    field: &FieldDescriptor,
1612    pool: Option<&Arc<DescriptorPool>>,
1613) -> Result<Value, ParseError> {
1614    Ok(match field.field_type {
1615        FieldType::Double => Value::Double(0.0),
1616        FieldType::Float => Value::Float(0.0),
1617        FieldType::Int32 | FieldType::Sint32 | FieldType::Sfixed32 => Value::Int32(0),
1618        FieldType::Int64 | FieldType::Sint64 | FieldType::Sfixed64 => Value::Int64(0),
1619        FieldType::Uint32 | FieldType::Fixed32 => Value::Uint32(0),
1620        FieldType::Uint64 | FieldType::Fixed64 => Value::Uint64(0),
1621        FieldType::Bool => Value::Bool(false),
1622        FieldType::String => Value::String(ProtoString::new()),
1623        FieldType::Bytes => Value::Bytes(ProtoBytes::new()),
1624        FieldType::Enum => Value::Enum(0),
1625        FieldType::Message | FieldType::Group => {
1626            let desc = field_message_desc(field, pool)?;
1627            Value::Message(DynamicMessage::new(desc))
1628        }
1629    })
1630}
1631
1632fn synthetic(number: u32, v: &Value) -> FieldDescriptor {
1633    let ty = match v {
1634        Value::Double(_) => FieldType::Double,
1635        Value::Float(_) => FieldType::Float,
1636        Value::Int32(_) => FieldType::Int32,
1637        Value::Int64(_) => FieldType::Int64,
1638        Value::Uint32(_) => FieldType::Uint32,
1639        Value::Uint64(_) => FieldType::Uint64,
1640        Value::Bool(_) => FieldType::Bool,
1641        Value::String(_) => FieldType::String,
1642        Value::Bytes(_) => FieldType::Bytes,
1643        Value::Enum(_) => FieldType::Enum,
1644        Value::Message(_) => FieldType::Message,
1645    };
1646    let mut f = FieldDescriptor::new("ext", number, ty, Cardinality::Optional, Presence::Explicit);
1647    if let Value::Message(m) = v {
1648        f.message = Some(m.descriptor().clone());
1649    }
1650    f
1651}
1652
1653fn untyped_size(number: u32, val: &FieldValue) -> u64 {
1654    match val {
1655        FieldValue::Singular(v) => field_value_size(&synthetic(number, v), val),
1656        FieldValue::Repeated(items) => items
1657            .iter()
1658            .map(|v| field_value_size(&synthetic(number, v), &FieldValue::Singular(v.clone())))
1659            .sum(),
1660        FieldValue::Map(_) => 0,
1661    }
1662}
1663
1664fn write_untyped(number: u32, val: &FieldValue, out: &mut impl crate::wire::WireOut) {
1665    match val {
1666        FieldValue::Singular(v) => write_field_value(&synthetic(number, v), val, out),
1667        FieldValue::Repeated(items) => {
1668            for v in items {
1669                write_field_value(&synthetic(number, v), &FieldValue::Singular(v.clone()), out);
1670            }
1671        }
1672        FieldValue::Map(_) => {}
1673    }
1674}
1675
1676fn field_value_size(field: &FieldDescriptor, val: &FieldValue) -> u64 {
1677    match val {
1678        FieldValue::Singular(v) => {
1679            if field.presence == Presence::Implicit && v.is_implicit_default() {
1680                0
1681            } else {
1682                scalar_size(field, v)
1683            }
1684        }
1685        FieldValue::Repeated(items) => {
1686            if field.packed && field.field_type.is_packable() {
1687                let payload: u64 = items
1688                    .iter()
1689                    .map(|v| packed_scalar_len(field.field_type, v))
1690                    .sum();
1691                if payload == 0 {
1692                    0
1693                } else {
1694                    key_len_value_len(field.number, payload)
1695                }
1696            } else {
1697                items.iter().map(|v| scalar_size(field, v)).sum()
1698            }
1699        }
1700        FieldValue::Map(items) => items
1701            .iter()
1702            .map(|(k, v)| key_len_value_len(field.number, map_entry_len(field, k, v)))
1703            .sum(),
1704    }
1705}
1706
1707fn write_field_value(
1708    field: &FieldDescriptor,
1709    val: &FieldValue,
1710    out: &mut impl crate::wire::WireOut,
1711) {
1712    match val {
1713        FieldValue::Singular(v) => {
1714            if field.presence == Presence::Implicit && v.is_implicit_default() {
1715                return;
1716            }
1717            write_scalar(field, v, out);
1718        }
1719        FieldValue::Repeated(items) => {
1720            if field.packed && field.field_type.is_packable() {
1721                let mut payload = Vec::new();
1722                for v in items {
1723                    write_packed_scalar(field.field_type, v, &mut payload);
1724                }
1725                if !payload.is_empty() {
1726                    encode_len_field(out, field.number, &payload);
1727                }
1728            } else {
1729                for v in items {
1730                    write_scalar(field, v, out);
1731                }
1732            }
1733        }
1734        FieldValue::Map(items) => {
1735            for (k, v) in items {
1736                let mut payload = Vec::new();
1737                write_map_entry(field, k, v, &mut payload);
1738                encode_len_field(out, field.number, &payload);
1739            }
1740        }
1741    }
1742}
1743
1744fn map_entry_len(field: &FieldDescriptor, key: &MapKeyValue, value: &Value) -> u64 {
1745    let entry = match field.message.as_ref() {
1746        Some(e) => e,
1747        None => return 0,
1748    };
1749    let mut n = 0u64;
1750    if let Some(kf) = entry.field(1) {
1751        n += scalar_size(kf, &map_key_to_value(key));
1752    }
1753    if let Some(vf) = entry.field(2) {
1754        n += scalar_size(vf, value);
1755    }
1756    n
1757}
1758
1759fn write_map_entry(
1760    field: &FieldDescriptor,
1761    key: &MapKeyValue,
1762    value: &Value,
1763    out: &mut impl crate::wire::WireOut,
1764) {
1765    let kv = map_key_to_value(key);
1766    let mut kf = field
1767        .message
1768        .as_ref()
1769        .and_then(|e| e.field(1).cloned())
1770        .unwrap_or_else(|| synthetic(1, &kv));
1771    kf.delimited = false;
1772    write_scalar(&kf, &kv, out);
1773    let mut vf = field
1774        .message
1775        .as_ref()
1776        .and_then(|e| e.field(2).cloned())
1777        .unwrap_or_else(|| synthetic(2, value));
1778    vf.delimited = false;
1779    write_scalar(&vf, value, out);
1780}
1781
1782fn map_key_to_value(key: &MapKeyValue) -> Value {
1783    match key {
1784        MapKeyValue::I32(n) => Value::Int32(*n),
1785        MapKeyValue::I64(n) => Value::Int64(*n),
1786        MapKeyValue::U32(n) => Value::Uint32(*n),
1787        MapKeyValue::U64(n) => Value::Uint64(*n),
1788        MapKeyValue::Bool(n) => Value::Bool(*n),
1789        MapKeyValue::String(s) => Value::String(s.clone()),
1790    }
1791}
1792
1793fn scalar_size(field: &FieldDescriptor, v: &Value) -> u64 {
1794    match v {
1795        Value::Message(m) if field.delimited || field.field_type == FieldType::Group => {
1796            tag_len(field.number, WIRE_SGROUP)
1797                + m.compute_size()
1798                + tag_len(field.number, WIRE_EGROUP)
1799        }
1800        Value::Message(m) => key_len_value_len(field.number, m.compute_size()),
1801        Value::String(s) => key_len_value_len(field.number, s.as_bytes().len() as u64),
1802        Value::Bytes(b) => key_len_value_len(field.number, b.as_bytes().len() as u64),
1803        other => {
1804            tag_len(field.number, field.field_type.default_wire())
1805                + packed_scalar_len(field.field_type, other)
1806        }
1807    }
1808}
1809
1810fn packed_scalar_len(ty: FieldType, v: &Value) -> u64 {
1811    match (ty, v) {
1812        (FieldType::Double | FieldType::Fixed64 | FieldType::Sfixed64, _) => 8,
1813        (FieldType::Float | FieldType::Fixed32 | FieldType::Sfixed32, _) => 4,
1814        (FieldType::Bool, Value::Bool(b)) => varint_len(u64::from(*b)),
1815        (FieldType::Int32, Value::Int32(n)) => varint_len(*n as u64),
1816        (FieldType::Int64, Value::Int64(n)) => varint_len(*n as u64),
1817        (FieldType::Uint32, Value::Uint32(n)) => varint_len(u64::from(*n)),
1818        (FieldType::Uint64, Value::Uint64(n)) => varint_len(*n),
1819        (FieldType::Sint32, Value::Int32(n)) => varint_len(encode_zigzag32(*n)),
1820        (FieldType::Sint64, Value::Int64(n)) => varint_len(encode_zigzag64(*n)),
1821        (FieldType::Enum, Value::Enum(n)) => varint_len(*n as u64),
1822        (FieldType::String, Value::String(s)) => {
1823            varint_len(s.as_bytes().len() as u64) + s.as_bytes().len() as u64
1824        }
1825        (FieldType::Bytes, Value::Bytes(b)) => {
1826            varint_len(b.as_bytes().len() as u64) + b.as_bytes().len() as u64
1827        }
1828        _ => 0,
1829    }
1830}
1831
1832fn write_scalar(field: &FieldDescriptor, v: &Value, out: &mut impl crate::wire::WireOut) {
1833    match v {
1834        Value::Message(m) if field.delimited || field.field_type == FieldType::Group => {
1835            encode_tag(out, field.number, WIRE_SGROUP);
1836            m.write_to(out);
1837            encode_tag(out, field.number, WIRE_EGROUP);
1838        }
1839        Value::Message(m) => {
1840            let mut inner = Vec::new();
1841            m.write_to(&mut inner);
1842            encode_len_field(out, field.number, &inner);
1843        }
1844        Value::String(s) => encode_len_field(out, field.number, s.as_bytes()),
1845        Value::Bytes(b) => encode_len_field(out, field.number, b.as_bytes()),
1846        _ => {
1847            encode_tag(out, field.number, field.field_type.default_wire());
1848            write_packed_scalar(field.field_type, v, out);
1849        }
1850    }
1851}
1852
1853fn write_packed_scalar(ty: FieldType, v: &Value, out: &mut impl crate::wire::WireOut) {
1854    match (ty, v) {
1855        (FieldType::Double, Value::Double(n)) => out.extend_from_slice(&n.to_bits().to_le_bytes()),
1856        (FieldType::Float, Value::Float(n)) => out.extend_from_slice(&n.to_bits().to_le_bytes()),
1857        (FieldType::Fixed64, Value::Uint64(n)) => out.extend_from_slice(&n.to_le_bytes()),
1858        (FieldType::Sfixed64, Value::Int64(n)) => out.extend_from_slice(&(*n as u64).to_le_bytes()),
1859        (FieldType::Fixed32, Value::Uint32(n)) => out.extend_from_slice(&n.to_le_bytes()),
1860        (FieldType::Sfixed32, Value::Int32(n)) => out.extend_from_slice(&(*n as u32).to_le_bytes()),
1861        (FieldType::Bool, Value::Bool(b)) => encode_varint(out, u64::from(*b)),
1862        (FieldType::Int32, Value::Int32(n)) => encode_varint(out, *n as u64),
1863        (FieldType::Int64, Value::Int64(n)) => encode_varint(out, *n as u64),
1864        (FieldType::Uint32, Value::Uint32(n)) => encode_varint(out, u64::from(*n)),
1865        (FieldType::Uint64, Value::Uint64(n)) => encode_varint(out, *n),
1866        (FieldType::Sint32, Value::Int32(n)) => encode_varint(out, encode_zigzag32(*n)),
1867        (FieldType::Sint64, Value::Int64(n)) => encode_varint(out, encode_zigzag64(*n)),
1868        (FieldType::Enum, Value::Enum(n)) => encode_varint(out, *n as u64),
1869        (FieldType::String, Value::String(s)) => {
1870            encode_varint(out, s.as_bytes().len() as u64);
1871            out.extend_from_slice(s.as_bytes());
1872        }
1873        (FieldType::Bytes, Value::Bytes(b)) => {
1874            encode_varint(out, b.as_bytes().len() as u64);
1875            out.extend_from_slice(b.as_bytes());
1876        }
1877        _ => {}
1878    }
1879}
1880
1881// --- Message trait impls ----------------------------------------------------
1882
1883#[derive(Clone, Copy, Debug)]
1884pub struct DynamicMessageView<'msg> {
1885    inner: &'msg DynamicMessage,
1886}
1887
1888impl Default for DynamicMessageView<'_> {
1889    fn default() -> Self {
1890        Self {
1891            inner: crate::gen_support::default_instance_of::<DynamicMessage>(),
1892        }
1893    }
1894}
1895
1896pub struct DynamicMessageMut<'msg> {
1897    inner: &'msg mut DynamicMessage,
1898}
1899
1900impl SealedInternal for DynamicMessage {}
1901impl MessageType for DynamicMessage {}
1902impl Proxied for DynamicMessage {
1903    type View<'msg> = DynamicMessageView<'msg>;
1904}
1905impl MutProxied for DynamicMessage {
1906    type Mut<'msg> = DynamicMessageMut<'msg>;
1907}
1908impl AsView for DynamicMessage {
1909    type Proxied = Self;
1910    fn as_view(&self) -> DynamicMessageView<'_> {
1911        DynamicMessageView { inner: self }
1912    }
1913}
1914impl AsMut for DynamicMessage {
1915    type MutProxied = Self;
1916    fn as_mut(&mut self) -> DynamicMessageMut<'_> {
1917        DynamicMessageMut { inner: self }
1918    }
1919}
1920
1921impl SealedInternal for DynamicMessageView<'_> {}
1922impl AsView for DynamicMessageView<'_> {
1923    type Proxied = DynamicMessage;
1924    fn as_view(&self) -> DynamicMessageView<'_> {
1925        *self
1926    }
1927}
1928impl<'msg> IntoView<'msg> for DynamicMessageView<'msg> {
1929    fn into_view<'shorter>(self) -> DynamicMessageView<'shorter>
1930    where
1931        'msg: 'shorter,
1932    {
1933        DynamicMessageView { inner: self.inner }
1934    }
1935}
1936
1937impl SealedInternal for DynamicMessageMut<'_> {}
1938impl AsView for DynamicMessageMut<'_> {
1939    type Proxied = DynamicMessage;
1940    fn as_view(&self) -> DynamicMessageView<'_> {
1941        DynamicMessageView { inner: self.inner }
1942    }
1943}
1944impl AsMut for DynamicMessageMut<'_> {
1945    type MutProxied = DynamicMessage;
1946    fn as_mut(&mut self) -> DynamicMessageMut<'_> {
1947        DynamicMessageMut { inner: self.inner }
1948    }
1949}
1950impl<'msg> IntoView<'msg> for DynamicMessageMut<'msg> {
1951    fn into_view<'shorter>(self) -> DynamicMessageView<'shorter>
1952    where
1953        'msg: 'shorter,
1954    {
1955        DynamicMessageView { inner: self.inner }
1956    }
1957}
1958impl<'msg> IntoMut<'msg> for DynamicMessageMut<'msg> {
1959    fn into_mut<'shorter>(self) -> DynamicMessageMut<'shorter>
1960    where
1961        'msg: 'shorter,
1962    {
1963        DynamicMessageMut { inner: self.inner }
1964    }
1965}
1966
1967impl Serialize for DynamicMessage {
1968    fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
1969        let mut out = Vec::new();
1970        self.write_to(&mut out);
1971        wire::check_size(out.len() as u64)?;
1972        Ok(out)
1973    }
1974    fn serialized_len(&self) -> usize {
1975        self.compute_size() as usize
1976    }
1977    fn encode(&self, out: &mut impl crate::wire::WireOut) -> Result<(), SerializeError> {
1978        wire::check_size(self.compute_size())?;
1979        self.write_to(out);
1980        Ok(())
1981    }
1982}
1983
1984impl Serialize for DynamicMessageView<'_> {
1985    fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
1986        self.inner.serialize()
1987    }
1988    fn serialized_len(&self) -> usize {
1989        self.inner.serialized_len()
1990    }
1991    fn encode(&self, out: &mut impl crate::wire::WireOut) -> Result<(), SerializeError> {
1992        self.inner.encode(out)
1993    }
1994}
1995
1996impl Serialize for DynamicMessageMut<'_> {
1997    fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
1998        self.inner.serialize()
1999    }
2000    fn serialized_len(&self) -> usize {
2001        self.inner.serialized_len()
2002    }
2003    fn encode(&self, out: &mut impl crate::wire::WireOut) -> Result<(), SerializeError> {
2004        self.inner.encode(out)
2005    }
2006}
2007
2008impl Clear for DynamicMessage {
2009    fn clear(&mut self) {
2010        self.fields.clear();
2011        self.unknown.clear();
2012    }
2013}
2014impl Clear for DynamicMessageMut<'_> {
2015    fn clear(&mut self) {
2016        self.inner.clear();
2017    }
2018}
2019
2020impl ClearAndParse for DynamicMessage {
2021    fn clear_and_parse(&mut self, data: &[u8]) -> Result<(), ParseError> {
2022        self.clear();
2023        self.merge_bytes(data, true, 0)
2024    }
2025    fn clear_and_parse_dont_enforce_required(&mut self, data: &[u8]) -> Result<(), ParseError> {
2026        self.clear();
2027        self.merge_bytes(data, false, 0)
2028    }
2029    fn merge_from_bytes(&mut self, data: &[u8]) -> Result<(), ParseError> {
2030        self.merge_bytes(data, true, 0)
2031    }
2032    fn merge_from_bytes_dont_enforce_required(&mut self, data: &[u8]) -> Result<(), ParseError> {
2033        self.merge_bytes(data, false, 0)
2034    }
2035}
2036impl ClearAndParse for DynamicMessageMut<'_> {
2037    fn clear_and_parse(&mut self, data: &[u8]) -> Result<(), ParseError> {
2038        self.inner.clear_and_parse(data)
2039    }
2040    fn clear_and_parse_dont_enforce_required(&mut self, data: &[u8]) -> Result<(), ParseError> {
2041        self.inner.clear_and_parse_dont_enforce_required(data)
2042    }
2043    fn merge_from_bytes(&mut self, data: &[u8]) -> Result<(), ParseError> {
2044        self.inner.merge_from_bytes(data)
2045    }
2046}
2047
2048impl CopyFrom for DynamicMessage {
2049    fn copy_from(&mut self, src: impl AsView<Proxied = Self>) {
2050        let src = src.as_view();
2051        *self = src.inner.clone();
2052    }
2053}
2054impl CopyFrom for DynamicMessageMut<'_> {
2055    fn copy_from(&mut self, src: impl AsView<Proxied = DynamicMessage>) {
2056        let src = src.as_view();
2057        *self.inner = src.inner.clone();
2058    }
2059}
2060
2061impl TakeFrom for DynamicMessage {
2062    fn take_from(&mut self, mut src: impl AsMut<MutProxied = Self>) {
2063        let src = src.as_mut();
2064        *self = std::mem::take(src.inner);
2065        // std::mem::take needs Default. Provide it.
2066    }
2067}
2068
2069impl Default for DynamicMessage {
2070    fn default() -> Self {
2071        let desc = Arc::new(MessageDescriptor::builder("_Unset").build());
2072        Self::new(desc)
2073    }
2074}
2075
2076impl TakeFrom for DynamicMessageMut<'_> {
2077    fn take_from(&mut self, mut src: impl AsMut<MutProxied = DynamicMessage>) {
2078        let src = src.as_mut();
2079        *self.inner = std::mem::take(src.inner);
2080    }
2081}
2082
2083impl MergeFrom for DynamicMessage {
2084    fn merge_from(&mut self, src: impl AsView<Proxied = Self>) {
2085        let src = src.as_view();
2086        self.merge_from_dyn(src.inner);
2087    }
2088}
2089impl MergeFrom for DynamicMessageMut<'_> {
2090    fn merge_from(&mut self, src: impl AsView<Proxied = DynamicMessage>) {
2091        let src = src.as_view();
2092        self.inner.merge_from_dyn(src.inner);
2093    }
2094}
2095
2096impl Message for DynamicMessage {
2097    type MessageView<'msg> = DynamicMessageView<'msg>;
2098    type MessageMut<'msg> = DynamicMessageMut<'msg>;
2099}
2100impl<'msg> MessageView<'msg> for DynamicMessageView<'msg> {
2101    type Message = DynamicMessage;
2102}
2103impl<'msg> MessageMut<'msg> for DynamicMessageMut<'msg> {
2104    type Message = DynamicMessage;
2105}
2106
2107impl fmt::Debug for DynamicMessageMut<'_> {
2108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2109        fmt::Debug::fmt(self.inner, f)
2110    }
2111}
2112
2113// --- FileDescriptorSet bootstrap -------------------------------------------
2114
2115#[derive(Clone, Copy, Debug, Default)]
2116struct RawFeatures {
2117    presence: u32,
2118    enum_type: u32,
2119    repeated_encoding: u32,
2120    utf8: u32,
2121    message_encoding: u32,
2122    json_format: u32,
2123    naming_style: u32,
2124    default_symbol_visibility: u32,
2125}
2126
2127const VISIBILITY_LOCAL: u32 = 1;
2128const VISIBILITY_EXPORT: u32 = 2;
2129
2130fn parse_declared_visibility(bytes: &[u8], pos: &mut usize) -> Result<u32, ParseError> {
2131    match decode_varint(bytes, pos)? {
2132        0 => Ok(0),
2133        1 => Ok(VISIBILITY_LOCAL),
2134        2 => Ok(VISIBILITY_EXPORT),
2135        _ => Err(ParseError::new("unknown symbol visibility")),
2136    }
2137}
2138
2139fn resolve_visibility(declared: u32, default: u32, nested: bool) -> Result<u32, ParseError> {
2140    match declared {
2141        VISIBILITY_LOCAL | VISIBILITY_EXPORT => Ok(declared),
2142        0 => match default {
2143            1 => Ok(VISIBILITY_EXPORT),
2144            2 if nested => Ok(VISIBILITY_LOCAL),
2145            2 => Ok(VISIBILITY_EXPORT),
2146            3 => Ok(VISIBILITY_LOCAL),
2147            _ => Err(ParseError::new("unresolved default symbol visibility")),
2148        },
2149        _ => Err(ParseError::new("unknown symbol visibility")),
2150    }
2151}
2152
2153impl RawFeatures {
2154    fn merge(self, over: Self) -> Self {
2155        Self {
2156            presence: if over.presence != 0 {
2157                over.presence
2158            } else {
2159                self.presence
2160            },
2161            enum_type: if over.enum_type != 0 {
2162                over.enum_type
2163            } else {
2164                self.enum_type
2165            },
2166            repeated_encoding: if over.repeated_encoding != 0 {
2167                over.repeated_encoding
2168            } else {
2169                self.repeated_encoding
2170            },
2171            utf8: if over.utf8 != 0 { over.utf8 } else { self.utf8 },
2172            message_encoding: if over.message_encoding != 0 {
2173                over.message_encoding
2174            } else {
2175                self.message_encoding
2176            },
2177            json_format: if over.json_format != 0 {
2178                over.json_format
2179            } else {
2180                self.json_format
2181            },
2182            naming_style: if over.naming_style != 0 {
2183                over.naming_style
2184            } else {
2185                self.naming_style
2186            },
2187            default_symbol_visibility: if over.default_symbol_visibility != 0 {
2188                over.default_symbol_visibility
2189            } else {
2190                self.default_symbol_visibility
2191            },
2192        }
2193    }
2194}
2195
2196fn edition_defaults(syntax: &str, edition: i32) -> RawFeatures {
2197    if syntax == "proto3" || edition == 999 {
2198        RawFeatures {
2199            presence: 2,
2200            enum_type: 1,
2201            repeated_encoding: 1,
2202            utf8: 2,
2203            message_encoding: 1,
2204            json_format: 1,
2205            naming_style: 2,
2206            default_symbol_visibility: 1,
2207        }
2208    } else if edition == 1001 {
2209        RawFeatures {
2210            presence: 1,
2211            enum_type: 1,
2212            repeated_encoding: 1,
2213            utf8: 2,
2214            message_encoding: 1,
2215            json_format: 1,
2216            naming_style: 1,
2217            default_symbol_visibility: 2,
2218        }
2219    } else if syntax == "editions" || edition == 1000 {
2220        RawFeatures {
2221            presence: 1,
2222            enum_type: 1,
2223            repeated_encoding: 1,
2224            utf8: 2,
2225            message_encoding: 1,
2226            json_format: 1,
2227            naming_style: 2,
2228            default_symbol_visibility: 1,
2229        }
2230    } else {
2231        RawFeatures {
2232            presence: 1,
2233            enum_type: 2,
2234            repeated_encoding: 2,
2235            utf8: 3,
2236            message_encoding: 1,
2237            json_format: 2,
2238            naming_style: 2,
2239            default_symbol_visibility: 1,
2240        }
2241    }
2242}
2243
2244#[derive(Default)]
2245struct RawFile {
2246    name: String,
2247    package: String,
2248    syntax: String,
2249    edition: i32,
2250    features: RawFeatures,
2251    messages: Vec<RawMessage>,
2252    enums: Vec<RawEnum>,
2253    extensions: Vec<RawField>,
2254    services: Vec<RawService>,
2255    dependencies: Vec<String>,
2256    public_dependency: Vec<i32>,
2257    weak_dependency: Vec<i32>,
2258    options: Vec<DescriptorOption>,
2259    source_code_info: Option<SourceCodeInfo>,
2260    comments: Comments,
2261    deprecated: bool,
2262}
2263
2264#[derive(Default, Clone)]
2265struct RawService {
2266    name: String,
2267    full_name: String,
2268    methods: Vec<MethodDescriptor>,
2269    method_features: Vec<RawFeatures>,
2270    features: RawFeatures,
2271    comments: Comments,
2272    deprecated: bool,
2273    options: Vec<DescriptorOption>,
2274}
2275
2276#[derive(Default, Clone)]
2277struct RawField {
2278    name: String,
2279    number: u32,
2280    label: i32,
2281    ty: i32,
2282    type_name: String,
2283    json_name: String,
2284    proto3_optional: bool,
2285    packed: Option<bool>,
2286    oneof_index: Option<u32>,
2287    default_value: Option<String>,
2288    extendee: String,
2289    features: RawFeatures,
2290    full_ext_name: String,
2291    file_name: String,
2292    options: Vec<DescriptorOption>,
2293    comments: Comments,
2294    deprecated: bool,
2295}
2296
2297#[derive(Default, Clone)]
2298struct RawMessage {
2299    name: String,
2300    full_name: String,
2301    fields: Vec<RawField>,
2302    nested: Vec<RawMessage>,
2303    is_map_entry: bool,
2304    syntax_proto3: bool,
2305    oneofs: Vec<RawOneof>,
2306    enums: Vec<RawEnum>,
2307    features: RawFeatures,
2308    declared_visibility: u32,
2309    effective_visibility: u32,
2310    extensions: Vec<RawField>,
2311    extension_ranges: Vec<(u32, u32)>,
2312    reserved_names: Vec<String>,
2313    file_name: String,
2314    message_set_wire_format: bool,
2315    options: Vec<DescriptorOption>,
2316    comments: Comments,
2317    deprecated: bool,
2318}
2319
2320#[derive(Default, Clone)]
2321struct RawOneof {
2322    name: String,
2323    features: RawFeatures,
2324}
2325
2326#[derive(Default, Clone)]
2327struct RawEnum {
2328    name: String,
2329    full_name: String,
2330    file_name: String,
2331    values: Vec<(i32, String)>,
2332    value_features: Vec<RawFeatures>,
2333    closed: bool,
2334    features: RawFeatures,
2335    declared_visibility: u32,
2336    effective_visibility: u32,
2337    options: Vec<DescriptorOption>,
2338    comments: Comments,
2339    value_comments: BTreeMap<i32, Comments>,
2340    value_comments_by_name: BTreeMap<String, Comments>,
2341    deprecated: bool,
2342    deprecated_values: BTreeSet<i32>,
2343}
2344
2345fn file_name_matches(wanted: &str, file_name: &str) -> bool {
2346    if wanted == file_name {
2347        return true;
2348    }
2349    let w = std::path::Path::new(wanted);
2350    let f = std::path::Path::new(file_name);
2351    w.file_name() == f.file_name() || wanted.ends_with(file_name) || file_name.ends_with(wanted)
2352}
2353
2354fn parse_file_descriptor_set(bytes: &[u8]) -> Result<Vec<RawFile>, ParseError> {
2355    let mut files = Vec::new();
2356    let mut pos = 0;
2357    while pos < bytes.len() {
2358        let (n, w) = decode_tag(bytes, &mut pos)?;
2359        if n == 1 && w == WIRE_LEN {
2360            let payload = read_len_bytes(bytes, &mut pos)?;
2361            files.push(parse_file(payload)?);
2362        } else {
2363            wire::skip_field(bytes, &mut pos, w)?;
2364        }
2365    }
2366    Ok(files)
2367}
2368
2369fn parse_file(bytes: &[u8]) -> Result<RawFile, ParseError> {
2370    let mut file = RawFile::default();
2371    let mut pos = 0;
2372    while pos < bytes.len() {
2373        let (n, w) = decode_tag(bytes, &mut pos)?;
2374        match (n, w) {
2375            (1, WIRE_LEN) => file.name = read_string(bytes, &mut pos)?,
2376            (2, WIRE_LEN) => file.package = read_string(bytes, &mut pos)?,
2377            (3, WIRE_LEN) => file.dependencies.push(read_string(bytes, &mut pos)?),
2378            (10, WIRE_VARINT) => file
2379                .public_dependency
2380                .push(decode_varint(bytes, &mut pos)? as i32),
2381            (11, WIRE_VARINT) => file
2382                .weak_dependency
2383                .push(decode_varint(bytes, &mut pos)? as i32),
2384            (4, WIRE_LEN) => {
2385                let payload = read_len_bytes(bytes, &mut pos)?;
2386                file.messages.push(parse_descriptor(payload, "")?);
2387            }
2388            (5, WIRE_LEN) => {
2389                let payload = read_len_bytes(bytes, &mut pos)?;
2390                file.enums.push(parse_enum(payload, false)?);
2391            }
2392            (6, WIRE_LEN) => {
2393                let payload = read_len_bytes(bytes, &mut pos)?;
2394                file.services.push(parse_service(payload)?);
2395            }
2396            (7, WIRE_LEN) => {
2397                let payload = read_len_bytes(bytes, &mut pos)?;
2398                file.extensions.push(parse_field(payload)?);
2399            }
2400            (8, WIRE_LEN) => {
2401                let payload = read_len_bytes(bytes, &mut pos)?;
2402                let (features, deprecated, options) = parse_file_options(payload)?;
2403                file.features = features;
2404                file.deprecated = deprecated;
2405                file.options = options;
2406            }
2407            (9, WIRE_LEN) => {
2408                let payload = read_len_bytes(bytes, &mut pos)?;
2409                file.source_code_info = Some(parse_source_code_info(payload)?);
2410            }
2411            (12, WIRE_LEN) => file.syntax = read_string(bytes, &mut pos)?,
2412            (14, WIRE_VARINT) => {
2413                file.edition = i32::try_from(decode_varint(bytes, &mut pos)?)
2414                    .map_err(|_| ParseError::new("protobuf edition out of range"))?;
2415            }
2416            _ => wire::skip_field(bytes, &mut pos, w)?,
2417        }
2418    }
2419    // Edition 9999 is the known unstable conformance sentinel, not a future release.
2420    if (file.edition > 1001 && file.edition != 9999)
2421        || (file.syntax == "editions" && !matches!(file.edition, 1000 | 1001 | 9999))
2422        || (file.edition == 1001 && file.syntax != "editions")
2423    {
2424        return Err(ParseError::new("unsupported or missing protobuf edition"));
2425    }
2426    if file.source_code_info.is_some() {
2427        attach_source_code_info(&mut file);
2428    }
2429    let defaults = edition_defaults(&file.syntax, file.edition);
2430    file.features = defaults.merge(file.features);
2431    let proto3 = file.syntax == "proto3" || file.edition == 999;
2432    mark_syntax(&mut file.messages, proto3, file.features, false)?;
2433    prefix_names(&mut file.messages, &file.package);
2434    for e in &mut file.enums {
2435        e.features = file.features.merge(e.features);
2436        e.closed = e.features.enum_type == 2;
2437        e.effective_visibility = resolve_visibility(
2438            e.declared_visibility,
2439            e.features.default_symbol_visibility,
2440            false,
2441        )?;
2442        e.file_name = file.name.clone();
2443        e.full_name = if file.package.is_empty() {
2444            e.name.clone()
2445        } else {
2446            format!("{}.{}", file.package, e.name)
2447        };
2448    }
2449    prefix_enums_in_messages(&mut file.messages)?;
2450    for ext in &mut file.extensions {
2451        if ext.extendee.starts_with('.') {
2452            ext.extendee = ext.extendee.trim_start_matches('.').to_string();
2453        } else if !file.package.is_empty() && !ext.extendee.contains('.') {
2454            ext.extendee = format!("{}.{}", file.package, ext.extendee);
2455        }
2456        ext.full_ext_name = if file.package.is_empty() {
2457            ext.name.clone()
2458        } else {
2459            format!("{}.{}", file.package, ext.name)
2460        };
2461        ext.file_name = file.name.clone();
2462    }
2463    stamp_file(&mut file.messages, &file.name);
2464    for svc in &mut file.services {
2465        svc.full_name = if file.package.is_empty() {
2466            svc.name.clone()
2467        } else {
2468            format!("{}.{}", file.package, svc.name)
2469        };
2470        for m in &mut svc.methods {
2471            m.input_type = m.input_type.trim_start_matches('.').to_string();
2472            m.output_type = m.output_type.trim_start_matches('.').to_string();
2473        }
2474    }
2475    if file.edition == 1001 {
2476        validate_edition2024_file(&file)?;
2477    }
2478    Ok(file)
2479}
2480
2481#[derive(Clone, Copy)]
2482enum Edition2024NameCase {
2483    Title,
2484    LowerSnake,
2485    UpperSnake,
2486}
2487
2488fn validate_edition2024_name(
2489    name: &str,
2490    naming_style: u32,
2491    case: Edition2024NameCase,
2492) -> Result<(), ParseError> {
2493    if naming_style == 2 {
2494        return Ok(());
2495    }
2496    if naming_style != 1 {
2497        return Err(ParseError::new("unresolved Edition 2024 naming style"));
2498    }
2499    let valid = match case {
2500        Edition2024NameCase::Title => {
2501            let mut bytes = name.bytes();
2502            bytes.next().is_some_and(|c| c.is_ascii_uppercase())
2503                && bytes.all(|c| c.is_ascii_alphanumeric())
2504        }
2505        Edition2024NameCase::LowerSnake => edition2024_snake_case(name, false),
2506        Edition2024NameCase::UpperSnake => edition2024_snake_case(name, true),
2507    };
2508    if valid {
2509        Ok(())
2510    } else {
2511        Err(ParseError::new("invalid Edition 2024 identifier"))
2512    }
2513}
2514
2515fn edition2024_snake_case(name: &str, upper: bool) -> bool {
2516    let is_letter = |c: u8| {
2517        if upper {
2518            c.is_ascii_uppercase()
2519        } else {
2520            c.is_ascii_lowercase()
2521        }
2522    };
2523    let mut bytes = name.bytes();
2524    if !bytes.next().is_some_and(is_letter) {
2525        return false;
2526    }
2527    let mut underscore = false;
2528    for c in bytes {
2529        if c == b'_' {
2530            if underscore {
2531                return false;
2532            }
2533            underscore = true;
2534        } else if is_letter(c) {
2535            underscore = false;
2536        } else if c.is_ascii_digit() && !underscore {
2537            // Digits may follow a word, but not an underscore.
2538        } else {
2539            return false;
2540        }
2541    }
2542    !underscore
2543}
2544
2545fn validate_edition2024_field(f: &RawField, parent: RawFeatures) -> Result<(), ParseError> {
2546    if !matches!(f.label, 1 | 3)
2547        || f.number == 0
2548        || f.number > 536_870_911
2549        || (19_000..=19_999).contains(&f.number)
2550        || matches!(FieldType::from_i32(f.ty), None | Some(FieldType::Group))
2551        || f.proto3_optional
2552        || f.packed.is_some()
2553        || f.options.iter().any(|option| option.number == 1)
2554    {
2555        return Err(ParseError::new("unsupported Edition 2024 field"));
2556    }
2557    validate_edition2024_name(
2558        &f.name,
2559        parent.merge(f.features).naming_style,
2560        Edition2024NameCase::LowerSnake,
2561    )
2562}
2563
2564fn validate_edition2024_enum(en: &RawEnum) -> Result<(), ParseError> {
2565    validate_edition2024_name(
2566        &en.name,
2567        en.features.naming_style,
2568        Edition2024NameCase::Title,
2569    )?;
2570    for ((_, name), features) in en.values.iter().zip(&en.value_features) {
2571        validate_edition2024_name(
2572            name,
2573            en.features.merge(*features).naming_style,
2574            Edition2024NameCase::UpperSnake,
2575        )?;
2576    }
2577    Ok(())
2578}
2579
2580fn validate_edition2024_message(msg: &RawMessage) -> Result<(), ParseError> {
2581    validate_edition2024_name(
2582        &msg.name,
2583        msg.features.naming_style,
2584        Edition2024NameCase::Title,
2585    )?;
2586    for field in msg.fields.iter().chain(&msg.extensions) {
2587        validate_edition2024_field(field, msg.features)?;
2588        if field
2589            .oneof_index
2590            .is_some_and(|index| index as usize >= msg.oneofs.len())
2591        {
2592            return Err(ParseError::new("unresolved Edition 2024 oneof"));
2593        }
2594    }
2595    for oneof in &msg.oneofs {
2596        validate_edition2024_name(
2597            &oneof.name,
2598            msg.features.merge(oneof.features).naming_style,
2599            Edition2024NameCase::LowerSnake,
2600        )?;
2601    }
2602    for en in &msg.enums {
2603        validate_edition2024_enum(en)?;
2604    }
2605    for nested in &msg.nested {
2606        validate_edition2024_message(nested)?;
2607    }
2608    Ok(())
2609}
2610
2611fn validate_edition2024_file(file: &RawFile) -> Result<(), ParseError> {
2612    if !file.weak_dependency.is_empty() || file.options.iter().any(|option| option.number == 10) {
2613        return Err(ParseError::new("unsupported Edition 2024 file option"));
2614    }
2615    for msg in &file.messages {
2616        validate_edition2024_message(msg)?;
2617    }
2618    for en in &file.enums {
2619        validate_edition2024_enum(en)?;
2620    }
2621    for ext in &file.extensions {
2622        validate_edition2024_field(ext, file.features)?;
2623    }
2624    for svc in &file.services {
2625        let features = file.features.merge(svc.features);
2626        validate_edition2024_name(&svc.name, features.naming_style, Edition2024NameCase::Title)?;
2627        // protoc uses TitleCase for RPC methods under STYLE2024.
2628        for (method, method_features) in svc.methods.iter().zip(&svc.method_features) {
2629            validate_edition2024_name(
2630                &method.name,
2631                features.merge(*method_features).naming_style,
2632                Edition2024NameCase::Title,
2633            )?;
2634        }
2635    }
2636    Ok(())
2637}
2638
2639fn attach_source_code_info(file: &mut RawFile) {
2640    let Some(sci) = file.source_code_info.clone() else {
2641        return;
2642    };
2643    let mut path_map: BTreeMap<Vec<i32>, Comments> = BTreeMap::new();
2644    for loc in &sci.locations {
2645        let comments = Comments {
2646            leading_comments: loc.leading_comments.clone(),
2647            trailing_comments: loc.trailing_comments.clone(),
2648            leading_detached_comments: loc.leading_detached_comments.clone(),
2649            leading: loc.leading_comments.clone(),
2650            trailing: loc.trailing_comments.clone(),
2651            span: loc.span.clone(),
2652        };
2653        match path_map.entry(loc.path.clone()) {
2654            std::collections::btree_map::Entry::Vacant(e) => {
2655                e.insert(comments);
2656            }
2657            std::collections::btree_map::Entry::Occupied(mut e) => {
2658                let existing = e.get_mut();
2659                if existing.span.is_empty() && !comments.span.is_empty() {
2660                    existing.span = comments.span;
2661                }
2662                if existing.leading_comments.is_none() && comments.leading_comments.is_some() {
2663                    existing.leading_comments = comments.leading_comments;
2664                    existing.leading = comments.leading;
2665                }
2666                if existing.trailing_comments.is_none() && comments.trailing_comments.is_some() {
2667                    existing.trailing_comments = comments.trailing_comments;
2668                    existing.trailing = comments.trailing;
2669                }
2670                if existing.leading_detached_comments.is_empty()
2671                    && !comments.leading_detached_comments.is_empty()
2672                {
2673                    existing.leading_detached_comments = comments.leading_detached_comments;
2674                }
2675            }
2676        }
2677    }
2678
2679    let file_c = lookup_comments(&path_map, &[]);
2680    if !file_c.is_empty() {
2681        file.comments = file_c;
2682    } else {
2683        let syntax_c = lookup_comments(&path_map, &[12]);
2684        if !syntax_c.is_empty() {
2685            file.comments = syntax_c;
2686        } else {
2687            let pkg_c = lookup_comments(&path_map, &[2]);
2688            if !pkg_c.is_empty() {
2689                file.comments = pkg_c;
2690            }
2691        }
2692    }
2693
2694    for (i, msg) in file.messages.iter_mut().enumerate() {
2695        let path = [4, i as i32];
2696        attach_message_comments(msg, &path, &path_map);
2697    }
2698
2699    for (i, e) in file.enums.iter_mut().enumerate() {
2700        let path = [5, i as i32];
2701        attach_enum_comments(e, &path, &path_map);
2702    }
2703
2704    for (i, svc) in file.services.iter_mut().enumerate() {
2705        let path = [6, i as i32];
2706        attach_service_comments(svc, &path, &path_map);
2707    }
2708
2709    for (i, ext) in file.extensions.iter_mut().enumerate() {
2710        let path = [7, i as i32];
2711        ext.comments = lookup_comments(&path_map, &path);
2712    }
2713}
2714
2715fn attach_message_comments(
2716    msg: &mut RawMessage,
2717    path: &[i32],
2718    path_map: &BTreeMap<Vec<i32>, Comments>,
2719) {
2720    msg.comments = lookup_comments(path_map, path);
2721
2722    for (j, field) in msg.fields.iter_mut().enumerate() {
2723        let mut field_path = path.to_vec();
2724        field_path.push(2);
2725        field_path.push(j as i32);
2726        field.comments = lookup_comments(path_map, &field_path);
2727    }
2728
2729    for (j, nested) in msg.nested.iter_mut().enumerate() {
2730        let mut nested_path = path.to_vec();
2731        nested_path.push(3);
2732        nested_path.push(j as i32);
2733        attach_message_comments(nested, &nested_path, path_map);
2734    }
2735
2736    for (j, e) in msg.enums.iter_mut().enumerate() {
2737        let mut enum_path = path.to_vec();
2738        enum_path.push(4);
2739        enum_path.push(j as i32);
2740        attach_enum_comments(e, &enum_path, path_map);
2741    }
2742
2743    for (j, ext) in msg.extensions.iter_mut().enumerate() {
2744        let mut ext_path = path.to_vec();
2745        ext_path.push(6);
2746        ext_path.push(j as i32);
2747        ext.comments = lookup_comments(path_map, &ext_path);
2748    }
2749}
2750
2751fn attach_enum_comments(e: &mut RawEnum, path: &[i32], path_map: &BTreeMap<Vec<i32>, Comments>) {
2752    e.comments = lookup_comments(path_map, path);
2753
2754    for (j, val) in e.values.iter().enumerate() {
2755        let mut val_path = path.to_vec();
2756        val_path.push(2);
2757        val_path.push(j as i32);
2758        let comments = lookup_comments(path_map, &val_path);
2759        e.value_comments.insert(val.0, comments.clone());
2760        e.value_comments_by_name.insert(val.1.clone(), comments);
2761    }
2762}
2763
2764fn attach_service_comments(
2765    svc: &mut RawService,
2766    path: &[i32],
2767    path_map: &BTreeMap<Vec<i32>, Comments>,
2768) {
2769    svc.comments = lookup_comments(path_map, path);
2770
2771    for (j, method) in svc.methods.iter_mut().enumerate() {
2772        let mut method_path = path.to_vec();
2773        method_path.push(2);
2774        method_path.push(j as i32);
2775        method.comments = lookup_comments(path_map, &method_path);
2776    }
2777}
2778
2779fn lookup_comments(path_map: &BTreeMap<Vec<i32>, Comments>, path: &[i32]) -> Comments {
2780    if let Some(c) = path_map.get(path) {
2781        if !c.is_empty() || !c.span.is_empty() {
2782            let mut res = c.clone();
2783            if res.is_empty() {
2784                let mut name_path = path.to_vec();
2785                name_path.push(1);
2786                if let Some(nc) = path_map.get(&name_path) {
2787                    if !nc.is_empty() {
2788                        res.leading_comments = nc.leading_comments.clone();
2789                        res.trailing_comments = nc.trailing_comments.clone();
2790                        res.leading_detached_comments = nc.leading_detached_comments.clone();
2791                        res.leading = nc.leading.clone();
2792                        res.trailing = nc.trailing.clone();
2793                    }
2794                }
2795            }
2796            return res;
2797        }
2798    }
2799    let mut name_path = path.to_vec();
2800    name_path.push(1);
2801    if let Some(c) = path_map.get(&name_path) {
2802        return c.clone();
2803    }
2804    Comments::default()
2805}
2806
2807fn parse_source_code_info(bytes: &[u8]) -> Result<SourceCodeInfo, ParseError> {
2808    let mut info = SourceCodeInfo::default();
2809    let mut pos = 0;
2810    while pos < bytes.len() {
2811        let (n, w) = decode_tag(bytes, &mut pos)?;
2812        match (n, w) {
2813            (1, WIRE_LEN) => {
2814                let payload = read_len_bytes(bytes, &mut pos)?;
2815                info.locations.push(parse_source_location(payload)?);
2816            }
2817            _ => wire::skip_field(bytes, &mut pos, w)?,
2818        }
2819    }
2820    Ok(info)
2821}
2822
2823fn parse_source_location(bytes: &[u8]) -> Result<SourceLocation, ParseError> {
2824    let mut loc = SourceLocation::default();
2825    let mut pos = 0;
2826    while pos < bytes.len() {
2827        let (n, w) = decode_tag(bytes, &mut pos)?;
2828        match (n, w) {
2829            (1, WIRE_LEN) => {
2830                let payload = read_len_bytes(bytes, &mut pos)?;
2831                let mut p_pos = 0;
2832                while p_pos < payload.len() {
2833                    let v = decode_varint(payload, &mut p_pos)? as i32;
2834                    loc.path.push(v);
2835                }
2836            }
2837            (1, WIRE_VARINT) => {
2838                let v = decode_varint(bytes, &mut pos)? as i32;
2839                loc.path.push(v);
2840            }
2841            (2, WIRE_LEN) => {
2842                let payload = read_len_bytes(bytes, &mut pos)?;
2843                let mut p_pos = 0;
2844                while p_pos < payload.len() {
2845                    let v = decode_varint(payload, &mut p_pos)? as i32;
2846                    loc.span.push(v);
2847                }
2848            }
2849            (2, WIRE_VARINT) => {
2850                let v = decode_varint(bytes, &mut pos)? as i32;
2851                loc.span.push(v);
2852            }
2853            (3, WIRE_LEN) => {
2854                loc.leading_comments = Some(read_string(bytes, &mut pos)?);
2855            }
2856            (4, WIRE_LEN) => {
2857                loc.trailing_comments = Some(read_string(bytes, &mut pos)?);
2858            }
2859            (6, WIRE_LEN) => {
2860                loc.leading_detached_comments
2861                    .push(read_string(bytes, &mut pos)?);
2862            }
2863            _ => wire::skip_field(bytes, &mut pos, w)?,
2864        }
2865    }
2866    Ok(loc)
2867}
2868
2869fn parse_service(bytes: &[u8]) -> Result<RawService, ParseError> {
2870    let mut svc = RawService::default();
2871    let mut pos = 0;
2872    while pos < bytes.len() {
2873        let (n, w) = decode_tag(bytes, &mut pos)?;
2874        match (n, w) {
2875            (1, WIRE_LEN) => svc.name = read_string(bytes, &mut pos)?,
2876            (2, WIRE_LEN) => {
2877                let payload = read_len_bytes(bytes, &mut pos)?;
2878                let (method, features) = parse_method(payload)?;
2879                svc.methods.push(method);
2880                svc.method_features.push(features);
2881            }
2882            (3, WIRE_LEN) => {
2883                let payload = read_len_bytes(bytes, &mut pos)?;
2884                let (deprecated, features, options) = parse_service_options(payload)?;
2885                svc.deprecated = deprecated;
2886                svc.features = features;
2887                svc.options = options;
2888            }
2889            _ => wire::skip_field(bytes, &mut pos, w)?,
2890        }
2891    }
2892    Ok(svc)
2893}
2894
2895fn parse_method(bytes: &[u8]) -> Result<(MethodDescriptor, RawFeatures), ParseError> {
2896    let mut m = MethodDescriptor::default();
2897    let mut features = RawFeatures::default();
2898    let mut pos = 0;
2899    while pos < bytes.len() {
2900        let (n, w) = decode_tag(bytes, &mut pos)?;
2901        match (n, w) {
2902            (1, WIRE_LEN) => m.name = read_string(bytes, &mut pos)?,
2903            (2, WIRE_LEN) => m.input_type = read_string(bytes, &mut pos)?,
2904            (3, WIRE_LEN) => m.output_type = read_string(bytes, &mut pos)?,
2905            (5, WIRE_VARINT) => m.client_streaming = decode_varint(bytes, &mut pos)? != 0,
2906            (6, WIRE_VARINT) => m.server_streaming = decode_varint(bytes, &mut pos)? != 0,
2907            (4, WIRE_LEN) => {
2908                let payload = read_len_bytes(bytes, &mut pos)?;
2909                let (deprecated, method_features, options) = parse_method_options(payload)?;
2910                m.deprecated = deprecated;
2911                features = method_features;
2912                m.options = options;
2913            }
2914            _ => wire::skip_field(bytes, &mut pos, w)?,
2915        }
2916    }
2917    Ok((m, features))
2918}
2919
2920fn stamp_file(msgs: &mut [RawMessage], file_name: &str) {
2921    for m in msgs {
2922        m.file_name = file_name.to_string();
2923        stamp_file(&mut m.nested, file_name);
2924        for e in &mut m.enums {
2925            e.file_name = file_name.to_string();
2926        }
2927        for ext in &mut m.extensions {
2928            ext.full_ext_name = format!("{}.{}", m.full_name, ext.name);
2929            ext.file_name = file_name.to_string();
2930        }
2931    }
2932}
2933
2934fn prefix_enums_in_messages(msgs: &mut [RawMessage]) -> Result<(), ParseError> {
2935    for m in msgs {
2936        for e in &mut m.enums {
2937            e.features = m.features.merge(e.features);
2938            e.closed = e.features.enum_type == 2;
2939            e.effective_visibility = resolve_visibility(
2940                e.declared_visibility,
2941                e.features.default_symbol_visibility,
2942                true,
2943            )?;
2944            e.full_name = format!("{}.{}", m.full_name, e.name);
2945        }
2946        prefix_enums_in_messages(&mut m.nested)?;
2947    }
2948    Ok(())
2949}
2950
2951fn parse_descriptor(bytes: &[u8], _parent: &str) -> Result<RawMessage, ParseError> {
2952    let mut msg = RawMessage::default();
2953    let mut pos = 0;
2954    while pos < bytes.len() {
2955        let (n, w) = decode_tag(bytes, &mut pos)?;
2956        match (n, w) {
2957            (1, WIRE_LEN) => msg.name = read_string(bytes, &mut pos)?,
2958            (2, WIRE_LEN) => {
2959                let payload = read_len_bytes(bytes, &mut pos)?;
2960                msg.fields.push(parse_field(payload)?);
2961            }
2962            (3, WIRE_LEN) => {
2963                let payload = read_len_bytes(bytes, &mut pos)?;
2964                msg.nested.push(parse_descriptor(payload, "")?);
2965            }
2966            (4, WIRE_LEN) => {
2967                let payload = read_len_bytes(bytes, &mut pos)?;
2968                msg.enums.push(parse_enum(payload, false)?);
2969            }
2970            (5, WIRE_LEN) => {
2971                let payload = read_len_bytes(bytes, &mut pos)?;
2972                if let Some(range) = parse_extension_range(payload)? {
2973                    msg.extension_ranges.push(range);
2974                }
2975            }
2976            (6, WIRE_LEN) => {
2977                let payload = read_len_bytes(bytes, &mut pos)?;
2978                msg.extensions.push(parse_field(payload)?);
2979            }
2980            (8, WIRE_LEN) => {
2981                msg.oneofs
2982                    .push(parse_oneof(read_len_bytes(bytes, &mut pos)?)?);
2983            }
2984            (7, WIRE_LEN) => {
2985                let payload = read_len_bytes(bytes, &mut pos)?;
2986                let (map_entry, message_set, deprecated, features, options) =
2987                    parse_message_options(payload)?;
2988                msg.is_map_entry = map_entry;
2989                msg.message_set_wire_format = message_set;
2990                msg.deprecated = deprecated;
2991                msg.features = features;
2992                msg.options = options;
2993            }
2994            (10, WIRE_LEN) => msg.reserved_names.push(read_string(bytes, &mut pos)?),
2995            (11, WIRE_VARINT) => {
2996                msg.declared_visibility = parse_declared_visibility(bytes, &mut pos)?;
2997            }
2998            (11, _) => return Err(ParseError::new("invalid message visibility wire type")),
2999            _ => wire::skip_field(bytes, &mut pos, w)?,
3000        }
3001    }
3002    Ok(msg)
3003}
3004
3005fn parse_oneof(bytes: &[u8]) -> Result<RawOneof, ParseError> {
3006    let mut oneof = RawOneof::default();
3007    let mut pos = 0;
3008    while pos < bytes.len() {
3009        let (n, w) = decode_tag(bytes, &mut pos)?;
3010        match (n, w) {
3011            (1, WIRE_LEN) => oneof.name = read_string(bytes, &mut pos)?,
3012            (2, WIRE_LEN) => {
3013                let options = read_len_bytes(bytes, &mut pos)?;
3014                let mut options_pos = 0;
3015                while options_pos < options.len() {
3016                    let (n, w) = decode_tag(options, &mut options_pos)?;
3017                    if n == 1 && w == WIRE_LEN {
3018                        oneof.features = oneof.features.merge(parse_features(
3019                            read_len_bytes(options, &mut options_pos)?,
3020                            FeatureTarget::Oneof,
3021                        )?);
3022                    } else if n == 1 {
3023                        return Err(ParseError::new("invalid OneofOptions.features wire type"));
3024                    } else {
3025                        wire::skip_field(options, &mut options_pos, w)?;
3026                    }
3027                }
3028            }
3029            (2, _) => return Err(ParseError::new("invalid oneof options wire type")),
3030            _ => wire::skip_field(bytes, &mut pos, w)?,
3031        }
3032    }
3033    Ok(oneof)
3034}
3035
3036fn parse_field(bytes: &[u8]) -> Result<RawField, ParseError> {
3037    let mut f = RawField::default();
3038    let mut pos = 0;
3039    while pos < bytes.len() {
3040        let (n, w) = decode_tag(bytes, &mut pos)?;
3041        match (n, w) {
3042            (1, WIRE_LEN) => f.name = read_string(bytes, &mut pos)?,
3043            (2, WIRE_LEN) => f.extendee = read_string(bytes, &mut pos)?,
3044            (3, WIRE_VARINT) => {
3045                f.number = u32::try_from(decode_varint(bytes, &mut pos)?)
3046                    .map_err(|_| ParseError::new("field number out of range"))?;
3047            }
3048            (4, WIRE_VARINT) => {
3049                f.label = i32::try_from(decode_varint(bytes, &mut pos)?)
3050                    .map_err(|_| ParseError::new("field label out of range"))?;
3051            }
3052            (5, WIRE_VARINT) => {
3053                f.ty = i32::try_from(decode_varint(bytes, &mut pos)?)
3054                    .map_err(|_| ParseError::new("field type out of range"))?;
3055            }
3056            (6, WIRE_LEN) => f.type_name = read_string(bytes, &mut pos)?,
3057            (7, WIRE_LEN) => f.default_value = Some(read_string(bytes, &mut pos)?),
3058            (9, WIRE_VARINT) => {
3059                f.oneof_index = Some(
3060                    u32::try_from(decode_varint(bytes, &mut pos)?)
3061                        .map_err(|_| ParseError::new("oneof index out of range"))?,
3062                );
3063            }
3064            (10, WIRE_LEN) => f.json_name = read_string(bytes, &mut pos)?,
3065            (8, WIRE_LEN) => {
3066                let payload = read_len_bytes(bytes, &mut pos)?;
3067                let (packed, deprecated, features, options) = parse_field_options(payload)?;
3068                f.packed = packed;
3069                f.deprecated = deprecated;
3070                f.features = features;
3071                f.options = options;
3072            }
3073            (17, WIRE_VARINT) => f.proto3_optional = decode_varint(bytes, &mut pos)? != 0,
3074            _ => wire::skip_field(bytes, &mut pos, w)?,
3075        }
3076    }
3077    Ok(f)
3078}
3079
3080fn parse_message_options(
3081    bytes: &[u8],
3082) -> Result<(bool, bool, bool, RawFeatures, Vec<DescriptorOption>), ParseError> {
3083    let mut map_entry = false;
3084    let mut message_set = false;
3085    let mut deprecated = false;
3086    let mut features = RawFeatures::default();
3087    let mut options = Vec::new();
3088    let mut pos = 0;
3089    while pos < bytes.len() {
3090        let (n, w) = decode_tag(bytes, &mut pos)?;
3091        match (n, w) {
3092            (1, WIRE_VARINT) => message_set = decode_varint(bytes, &mut pos)? != 0,
3093            (3, WIRE_VARINT) => deprecated = decode_varint(bytes, &mut pos)? != 0,
3094            (7, WIRE_VARINT) => map_entry = decode_varint(bytes, &mut pos)? != 0,
3095            (12, WIRE_LEN) => {
3096                let payload = read_len_bytes(bytes, &mut pos)?;
3097                features = features.merge(parse_features(payload, FeatureTarget::Message)?);
3098            }
3099            (12, _) => return Err(ParseError::new("invalid MessageOptions.features wire type")),
3100            _ => options.push(DescriptorOption {
3101                number: n,
3102                value: capture_option_value(bytes, &mut pos, w)?,
3103            }),
3104        }
3105    }
3106    Ok((map_entry, message_set, deprecated, features, options))
3107}
3108
3109fn parse_field_options(
3110    bytes: &[u8],
3111) -> Result<(Option<bool>, bool, RawFeatures, Vec<DescriptorOption>), ParseError> {
3112    let mut packed = None;
3113    let mut deprecated = false;
3114    let mut features = RawFeatures::default();
3115    let mut options = Vec::new();
3116    let mut pos = 0;
3117    while pos < bytes.len() {
3118        let (n, w) = decode_tag(bytes, &mut pos)?;
3119        match (n, w) {
3120            (2, WIRE_VARINT) => packed = Some(decode_varint(bytes, &mut pos)? != 0),
3121            (3, WIRE_VARINT) => deprecated = decode_varint(bytes, &mut pos)? != 0,
3122            (21, WIRE_LEN) => {
3123                let payload = read_len_bytes(bytes, &mut pos)?;
3124                features = features.merge(parse_features(payload, FeatureTarget::Field)?);
3125            }
3126            (21, _) => return Err(ParseError::new("invalid FieldOptions.features wire type")),
3127            _ => options.push(DescriptorOption {
3128                number: n,
3129                value: capture_option_value(bytes, &mut pos, w)?,
3130            }),
3131        }
3132    }
3133    Ok((packed, deprecated, features, options))
3134}
3135
3136fn capture_option_value(bytes: &[u8], pos: &mut usize, w: u32) -> Result<Vec<u8>, ParseError> {
3137    match w {
3138        WIRE_VARINT => {
3139            let v = decode_varint(bytes, pos)?;
3140            let mut out = Vec::new();
3141            encode_varint(&mut out, v);
3142            Ok(out)
3143        }
3144        WIRE_LEN => Ok(read_len_bytes(bytes, pos)?.to_vec()),
3145        WIRE_I32 => {
3146            let v = read_fixed32(bytes, pos)?;
3147            Ok(v.to_le_bytes().to_vec())
3148        }
3149        WIRE_I64 => {
3150            let v = read_fixed64(bytes, pos)?;
3151            Ok(v.to_le_bytes().to_vec())
3152        }
3153        _ => {
3154            wire::skip_field(bytes, pos, w)?;
3155            Ok(Vec::new())
3156        }
3157    }
3158}
3159
3160fn parse_file_options(
3161    bytes: &[u8],
3162) -> Result<(RawFeatures, bool, Vec<DescriptorOption>), ParseError> {
3163    let mut features = RawFeatures::default();
3164    let mut deprecated = false;
3165    let mut options = Vec::new();
3166    let mut pos = 0;
3167    while pos < bytes.len() {
3168        let (n, w) = decode_tag(bytes, &mut pos)?;
3169        if n == 50 {
3170            if w != WIRE_LEN {
3171                return Err(ParseError::new("invalid FileOptions.features wire type"));
3172            }
3173            let payload = read_len_bytes(bytes, &mut pos)?;
3174            features = features.merge(parse_features(payload, FeatureTarget::File)?);
3175        } else if n == 23 && w == WIRE_VARINT {
3176            deprecated = decode_varint(bytes, &mut pos)? != 0;
3177        } else {
3178            options.push(DescriptorOption {
3179                number: n,
3180                value: capture_option_value(bytes, &mut pos, w)?,
3181            });
3182        }
3183    }
3184    Ok((features, deprecated, options))
3185}
3186
3187fn parse_enum_options(
3188    bytes: &[u8],
3189) -> Result<(bool, RawFeatures, Vec<DescriptorOption>), ParseError> {
3190    let mut deprecated = false;
3191    let mut features = RawFeatures::default();
3192    let mut options = Vec::new();
3193    let mut pos = 0;
3194    while pos < bytes.len() {
3195        let (n, w) = decode_tag(bytes, &mut pos)?;
3196        if n == 7 {
3197            if w != WIRE_LEN {
3198                return Err(ParseError::new("invalid EnumOptions.features wire type"));
3199            }
3200            features = features.merge(parse_features(
3201                read_len_bytes(bytes, &mut pos)?,
3202                FeatureTarget::Enum,
3203            )?);
3204        } else if n == 2 && w == WIRE_VARINT {
3205            deprecated = decode_varint(bytes, &mut pos)? != 0;
3206        } else {
3207            options.push(DescriptorOption {
3208                number: n,
3209                value: capture_option_value(bytes, &mut pos, w)?,
3210            });
3211        }
3212    }
3213    Ok((deprecated, features, options))
3214}
3215
3216fn parse_method_options(
3217    bytes: &[u8],
3218) -> Result<(bool, RawFeatures, Vec<DescriptorOption>), ParseError> {
3219    let mut deprecated = false;
3220    let mut features = RawFeatures::default();
3221    let mut options = Vec::new();
3222    let mut pos = 0;
3223    while pos < bytes.len() {
3224        let (n, w) = decode_tag(bytes, &mut pos)?;
3225        if n == 35 {
3226            if w != WIRE_LEN {
3227                return Err(ParseError::new("invalid MethodOptions.features wire type"));
3228            }
3229            features = features.merge(parse_features(
3230                read_len_bytes(bytes, &mut pos)?,
3231                FeatureTarget::Method,
3232            )?);
3233        } else if n == 33 && w == WIRE_VARINT {
3234            deprecated = decode_varint(bytes, &mut pos)? != 0;
3235        } else {
3236            options.push(DescriptorOption {
3237                number: n,
3238                value: capture_option_value(bytes, &mut pos, w)?,
3239            });
3240        }
3241    }
3242    Ok((deprecated, features, options))
3243}
3244
3245fn parse_service_options(
3246    bytes: &[u8],
3247) -> Result<(bool, RawFeatures, Vec<DescriptorOption>), ParseError> {
3248    let mut deprecated = false;
3249    let mut features = RawFeatures::default();
3250    let mut options = Vec::new();
3251    let mut pos = 0;
3252    while pos < bytes.len() {
3253        let (n, w) = decode_tag(bytes, &mut pos)?;
3254        if n == 34 && w == WIRE_LEN {
3255            features = features.merge(parse_features(
3256                read_len_bytes(bytes, &mut pos)?,
3257                FeatureTarget::Service,
3258            )?);
3259        } else if n == 34 {
3260            return Err(ParseError::new("invalid ServiceOptions.features wire type"));
3261        } else if n == 33 && w == WIRE_VARINT {
3262            deprecated = decode_varint(bytes, &mut pos)? != 0;
3263        } else {
3264            options.push(DescriptorOption {
3265                number: n,
3266                value: capture_option_value(bytes, &mut pos, w)?,
3267            });
3268        }
3269    }
3270    Ok((deprecated, features, options))
3271}
3272
3273#[derive(Clone, Copy)]
3274enum FeatureTarget {
3275    File,
3276    Message,
3277    Field,
3278    Enum,
3279    EnumValue,
3280    Oneof,
3281    ExtensionRange,
3282    Service,
3283    Method,
3284}
3285
3286fn parse_features(bytes: &[u8], target: FeatureTarget) -> Result<RawFeatures, ParseError> {
3287    let mut f = RawFeatures::default();
3288    let mut pos = 0;
3289    while pos < bytes.len() {
3290        let (n, w) = decode_tag(bytes, &mut pos)?;
3291        if (1000..=1004).contains(&n) && w == WIRE_LEN {
3292            // Language-specific feature extensions do not affect Rust wire semantics.
3293            wire::skip_field(bytes, &mut pos, w)?;
3294            continue;
3295        }
3296        let allowed = match n {
3297            1 | 3..=5 => matches!(target, FeatureTarget::File | FeatureTarget::Field),
3298            2 => matches!(target, FeatureTarget::File | FeatureTarget::Enum),
3299            6 => matches!(
3300                target,
3301                FeatureTarget::File | FeatureTarget::Message | FeatureTarget::Enum
3302            ),
3303            7 => true,
3304            8 => matches!(target, FeatureTarget::File),
3305            _ => return Err(ParseError::new("unrecognized protobuf feature")),
3306        };
3307        if !allowed || w != WIRE_VARINT {
3308            return Err(ParseError::new(
3309                "invalid protobuf feature target or wire type",
3310            ));
3311        }
3312        let v = u32::try_from(decode_varint(bytes, &mut pos)?)
3313            .map_err(|_| ParseError::new("protobuf feature value out of range"))?;
3314        let valid = match n {
3315            1 => matches!(v, 1..=3),
3316            2 | 3 | 5 | 6 | 7 => matches!(v, 1 | 2),
3317            4 => matches!(v, 2 | 3),
3318            8 => matches!(v, 1..=3),
3319            _ => false,
3320        };
3321        if !valid {
3322            return Err(ParseError::new("unsupported protobuf feature value"));
3323        }
3324        match n {
3325            1 => f.presence = v,
3326            2 => f.enum_type = v,
3327            3 => f.repeated_encoding = v,
3328            4 => f.utf8 = v,
3329            5 => f.message_encoding = v,
3330            6 => f.json_format = v,
3331            7 => f.naming_style = v,
3332            8 => f.default_symbol_visibility = v,
3333            _ => return Err(ParseError::new("unrecognized protobuf feature")),
3334        }
3335    }
3336    Ok(f)
3337}
3338
3339fn parse_extension_range(bytes: &[u8]) -> Result<Option<(u32, u32)>, ParseError> {
3340    let mut start = 0u32;
3341    let mut end = 0u32;
3342    let mut pos = 0;
3343    while pos < bytes.len() {
3344        let (n, w) = decode_tag(bytes, &mut pos)?;
3345        match (n, w) {
3346            (1, WIRE_VARINT) => start = decode_varint(bytes, &mut pos)? as u32,
3347            (2, WIRE_VARINT) => end = decode_varint(bytes, &mut pos)? as u32,
3348            (3, WIRE_LEN) => {
3349                let options = read_len_bytes(bytes, &mut pos)?;
3350                let mut options_pos = 0;
3351                while options_pos < options.len() {
3352                    let (n, w) = decode_tag(options, &mut options_pos)?;
3353                    if n == 50 && w == WIRE_LEN {
3354                        let _ = parse_features(
3355                            read_len_bytes(options, &mut options_pos)?,
3356                            FeatureTarget::ExtensionRange,
3357                        )?;
3358                    } else if n == 50 {
3359                        return Err(ParseError::new("invalid ExtensionRangeOptions.features"));
3360                    } else {
3361                        wire::skip_field(options, &mut options_pos, w)?;
3362                    }
3363                }
3364            }
3365            (3, _) => return Err(ParseError::new("invalid extension range options wire type")),
3366            _ => wire::skip_field(bytes, &mut pos, w)?,
3367        }
3368    }
3369    Ok(if end > start {
3370        Some((start, end))
3371    } else {
3372        None
3373    })
3374}
3375
3376fn parse_enum(bytes: &[u8], closed: bool) -> Result<RawEnum, ParseError> {
3377    let mut e = RawEnum {
3378        closed,
3379        ..RawEnum::default()
3380    };
3381    let mut pos = 0;
3382    while pos < bytes.len() {
3383        let (n, w) = decode_tag(bytes, &mut pos)?;
3384        match (n, w) {
3385            (1, WIRE_LEN) => e.name = read_string(bytes, &mut pos)?,
3386            (2, WIRE_LEN) => {
3387                let payload = read_len_bytes(bytes, &mut pos)?;
3388                let (num, name, dep, features) = parse_enum_value(payload)?;
3389                e.values.push((num, name));
3390                e.value_features.push(features);
3391                if dep {
3392                    e.deprecated_values.insert(num);
3393                }
3394            }
3395            (3, WIRE_LEN) => {
3396                let payload = read_len_bytes(bytes, &mut pos)?;
3397                let (deprecated, features, options) = parse_enum_options(payload)?;
3398                e.deprecated = deprecated;
3399                e.features = features;
3400                e.options = options;
3401            }
3402            (6, WIRE_VARINT) => {
3403                e.declared_visibility = parse_declared_visibility(bytes, &mut pos)?;
3404            }
3405            (6, _) => return Err(ParseError::new("invalid enum visibility wire type")),
3406            _ => wire::skip_field(bytes, &mut pos, w)?,
3407        }
3408    }
3409    Ok(e)
3410}
3411
3412fn parse_enum_value(bytes: &[u8]) -> Result<(i32, String, bool, RawFeatures), ParseError> {
3413    let mut name = String::new();
3414    let mut number = 0i32;
3415    let mut deprecated = false;
3416    let mut features = RawFeatures::default();
3417    let mut pos = 0;
3418    while pos < bytes.len() {
3419        let (n, w) = decode_tag(bytes, &mut pos)?;
3420        match (n, w) {
3421            (1, WIRE_LEN) => name = read_string(bytes, &mut pos)?,
3422            (2, WIRE_VARINT) => number = decode_varint(bytes, &mut pos)? as i32,
3423            (3, WIRE_LEN) => {
3424                let payload = read_len_bytes(bytes, &mut pos)?;
3425                (deprecated, features) = parse_enum_value_options(payload)?;
3426            }
3427            _ => wire::skip_field(bytes, &mut pos, w)?,
3428        }
3429    }
3430    Ok((number, name, deprecated, features))
3431}
3432
3433fn parse_enum_value_options(bytes: &[u8]) -> Result<(bool, RawFeatures), ParseError> {
3434    let mut deprecated = false;
3435    let mut features = RawFeatures::default();
3436    let mut pos = 0;
3437    while pos < bytes.len() {
3438        let (n, w) = decode_tag(bytes, &mut pos)?;
3439        if n == 2 && w == WIRE_LEN {
3440            features = features.merge(parse_features(
3441                read_len_bytes(bytes, &mut pos)?,
3442                FeatureTarget::EnumValue,
3443            )?);
3444        } else if n == 2 {
3445            return Err(ParseError::new(
3446                "invalid EnumValueOptions.features wire type",
3447            ));
3448        } else if n == 1 && w == WIRE_VARINT {
3449            deprecated = decode_varint(bytes, &mut pos)? != 0;
3450        } else {
3451            wire::skip_field(bytes, &mut pos, w)?;
3452        }
3453    }
3454    Ok((deprecated, features))
3455}
3456
3457fn read_string(bytes: &[u8], pos: &mut usize) -> Result<String, ParseError> {
3458    let b = read_len_bytes(bytes, pos)?;
3459    Ok(String::from_utf8_lossy(b).into_owned())
3460}
3461
3462fn mark_syntax(
3463    msgs: &mut [RawMessage],
3464    proto3: bool,
3465    features: RawFeatures,
3466    nested: bool,
3467) -> Result<(), ParseError> {
3468    for m in msgs {
3469        m.syntax_proto3 = proto3;
3470        m.features = features.merge(m.features);
3471        m.effective_visibility = resolve_visibility(
3472            m.declared_visibility,
3473            m.features.default_symbol_visibility,
3474            nested,
3475        )?;
3476        mark_syntax(&mut m.nested, proto3, m.features, true)?;
3477    }
3478    Ok(())
3479}
3480
3481fn prefix_names(msgs: &mut [RawMessage], package: &str) {
3482    for m in msgs {
3483        m.full_name = if package.is_empty() {
3484            m.name.clone()
3485        } else {
3486            format!("{package}.{}", m.name)
3487        };
3488        prefix_names(&mut m.nested, &m.full_name);
3489    }
3490}
3491
3492fn collect_raw(
3493    file: &RawFile,
3494    out: &mut BTreeMap<String, RawMessage>,
3495    enums: &mut BTreeMap<String, RawEnum>,
3496    extensions: &mut Vec<(RawFeatures, RawField)>,
3497) {
3498    fn walk(
3499        m: &RawMessage,
3500        out: &mut BTreeMap<String, RawMessage>,
3501        enums: &mut BTreeMap<String, RawEnum>,
3502        extensions: &mut Vec<(RawFeatures, RawField)>,
3503    ) {
3504        out.insert(m.full_name.clone(), m.clone());
3505        for e in &m.enums {
3506            enums.insert(e.full_name.clone(), e.clone());
3507        }
3508        for ext in &m.extensions {
3509            extensions.push((m.features, ext.clone()));
3510        }
3511        for n in &m.nested {
3512            walk(n, out, enums, extensions);
3513        }
3514    }
3515    for e in &file.enums {
3516        enums.insert(e.full_name.clone(), e.clone());
3517    }
3518    for ext in &file.extensions {
3519        extensions.push((file.features, ext.clone()));
3520    }
3521    for m in &file.messages {
3522        walk(m, out, enums, extensions);
3523    }
3524}
3525
3526fn check_visible_from_file(
3527    source_file: &str,
3528    target_file: &str,
3529    target_visibility: u32,
3530) -> Result<(), ParseError> {
3531    if source_file != target_file && target_visibility == VISIBILITY_LOCAL {
3532        Err(ParseError::new("cross-file reference to local symbol"))
3533    } else {
3534        Ok(())
3535    }
3536}
3537
3538fn check_symbol_visible_from_file(
3539    source_file: &str,
3540    target_file: &str,
3541    full_name: &str,
3542    metadata: &BTreeMap<String, SymbolMetadata>,
3543) -> Result<(), ParseError> {
3544    let visibility = metadata
3545        .get(full_name)
3546        .ok_or_else(|| ParseError::new("unresolved symbol visibility"))?;
3547    check_visible_from_file(source_file, target_file, visibility.effective_visibility)
3548}
3549
3550fn check_edition2024_reference(
3551    pool: &DescriptorPool,
3552    source_file: &str,
3553    imports: &BTreeSet<String>,
3554    name: &str,
3555    expected_type: FieldType,
3556) -> Result<(), ParseError> {
3557    let name = name.trim_start_matches('.');
3558    let target_file = match expected_type {
3559        FieldType::Message => pool.messages.get(name).map(|desc| desc.file_name.as_str()),
3560        FieldType::Enum => pool.enums.get(name).map(|desc| desc.file_name.as_str()),
3561        _ => return Err(ParseError::new("unsupported Edition 2024 reference type")),
3562    }
3563    .ok_or_else(|| ParseError::new("unresolved Edition 2024 type reference"))?;
3564    if source_file != target_file {
3565        if !imports.contains(target_file) {
3566            return Err(ParseError::new("Edition 2024 type is not imported"));
3567        }
3568        check_symbol_visible_from_file(source_file, target_file, name, &pool.symbol_metadata)?;
3569    }
3570    Ok(())
3571}
3572
3573fn check_edition2024_field_references(
3574    field: &RawField,
3575    source_file: &str,
3576    imports: &BTreeSet<String>,
3577    pool: &DescriptorPool,
3578) -> Result<(), ParseError> {
3579    match FieldType::from_i32(field.ty) {
3580        Some(ty @ (FieldType::Message | FieldType::Enum)) => {
3581            check_edition2024_reference(pool, source_file, imports, &field.type_name, ty)?;
3582        }
3583        Some(_) if field.type_name.is_empty() => {}
3584        _ => return Err(ParseError::new("invalid Edition 2024 field type reference")),
3585    }
3586    if !field.extendee.is_empty() {
3587        check_edition2024_reference(
3588            pool,
3589            source_file,
3590            imports,
3591            &field.extendee,
3592            FieldType::Message,
3593        )?;
3594    }
3595    Ok(())
3596}
3597
3598fn check_edition2024_message_references(
3599    msg: &RawMessage,
3600    source_file: &str,
3601    imports: &BTreeSet<String>,
3602    pool: &DescriptorPool,
3603) -> Result<(), ParseError> {
3604    for field in msg.fields.iter().chain(&msg.extensions) {
3605        check_edition2024_field_references(field, source_file, imports, pool)?;
3606    }
3607    for nested in &msg.nested {
3608        check_edition2024_message_references(nested, source_file, imports, pool)?;
3609    }
3610    Ok(())
3611}
3612
3613fn validate_edition2024_references(
3614    files: &[RawFile],
3615    pool: &DescriptorPool,
3616) -> Result<(), ParseError> {
3617    let by_name: BTreeMap<&str, &RawFile> = files
3618        .iter()
3619        .map(|file| (file.name.as_str(), file))
3620        .collect();
3621    for file in files.iter().filter(|file| file.edition == 1001) {
3622        let mut imports = BTreeSet::new();
3623        let mut pending = file.dependencies.clone();
3624        while let Some(name) = pending.pop() {
3625            if !imports.insert(name.clone()) {
3626                continue;
3627            }
3628            if let Some(imported) = by_name.get(name.as_str()) {
3629                for index in &imported.public_dependency {
3630                    if let Some(dependency) = usize::try_from(*index)
3631                        .ok()
3632                        .and_then(|index| imported.dependencies.get(index))
3633                    {
3634                        pending.push(dependency.clone());
3635                    }
3636                }
3637            }
3638        }
3639        for msg in &file.messages {
3640            check_edition2024_message_references(msg, &file.name, &imports, pool)?;
3641        }
3642        for field in &file.extensions {
3643            check_edition2024_field_references(field, &file.name, &imports, pool)?;
3644        }
3645        for service in &file.services {
3646            for method in &service.methods {
3647                for name in [&method.input_type, &method.output_type] {
3648                    check_edition2024_reference(
3649                        pool,
3650                        &file.name,
3651                        &imports,
3652                        name,
3653                        FieldType::Message,
3654                    )?;
3655                }
3656            }
3657        }
3658    }
3659    Ok(())
3660}
3661
3662fn resolve_pool(
3663    raw: BTreeMap<String, RawMessage>,
3664    raw_enums: BTreeMap<String, RawEnum>,
3665    extensions: Vec<(RawFeatures, RawField)>,
3666    edition2024_files: &BTreeSet<String>,
3667) -> Result<DescriptorPool, ParseError> {
3668    // First pass: skeleton descriptors (no nested message arcs).
3669    let mut skeletons: BTreeMap<String, MessageDescriptor> = BTreeMap::new();
3670    let mut symbol_metadata = BTreeMap::new();
3671    for (name, raw_msg) in &raw {
3672        symbol_metadata.insert(
3673            name.clone(),
3674            SymbolMetadata {
3675                features: raw_msg.features,
3676                declared_visibility: raw_msg.declared_visibility,
3677                effective_visibility: raw_msg.effective_visibility,
3678            },
3679        );
3680        let mut b = MessageDescriptor::builder(name.clone()).map_entry(raw_msg.is_map_entry);
3681        let mut oneofs: Vec<Vec<u32>> = vec![Vec::new(); raw_msg.oneofs.len()];
3682        for f in &raw_msg.fields {
3683            let fd = raw_field_to_desc(
3684                f,
3685                raw_msg.features,
3686                edition2024_files.contains(&raw_msg.file_name),
3687            );
3688            if let Some(idx) = fd.oneof_index {
3689                if let Some(slot) = oneofs.get_mut(idx as usize) {
3690                    slot.push(fd.number);
3691                }
3692            }
3693            b = b.field(fd);
3694        }
3695        let mut built = b.build();
3696        built.oneofs = oneofs;
3697        built.extension_ranges = raw_msg.extension_ranges.clone();
3698        built.reserved_names = raw_msg.reserved_names.iter().cloned().collect();
3699        built.message_set_wire_format = raw_msg.message_set_wire_format;
3700        built.file_name = raw_msg.file_name.clone();
3701        built.options = raw_msg.options.clone();
3702        built.comments = raw_msg.comments.clone();
3703        built.deprecated = raw_msg.deprecated;
3704        skeletons.insert(name.clone(), built);
3705    }
3706    let mut enum_arcs: BTreeMap<String, Arc<EnumDescriptor>> = BTreeMap::new();
3707    for (name, raw_e) in &raw_enums {
3708        symbol_metadata.insert(
3709            name.clone(),
3710            SymbolMetadata {
3711                features: raw_e.features,
3712                declared_visibility: raw_e.declared_visibility,
3713                effective_visibility: raw_e.effective_visibility,
3714            },
3715        );
3716        let mut ed = EnumDescriptor {
3717            name: raw_e.name.clone(),
3718            full_name: name.clone(),
3719            file_name: raw_e.file_name.clone(),
3720            values: BTreeMap::new(),
3721            names: BTreeMap::new(),
3722            listed: raw_e.values.clone(),
3723            closed: raw_e.closed,
3724            options: raw_e.options.clone(),
3725            comments: raw_e.comments.clone(),
3726            value_comments: raw_e.value_comments.clone(),
3727            value_comments_by_name: raw_e.value_comments_by_name.clone(),
3728            deprecated: raw_e.deprecated,
3729            deprecated_values: raw_e.deprecated_values.clone(),
3730        };
3731        for (num, n) in &raw_e.values {
3732            ed.values.entry(*num).or_insert_with(|| n.clone());
3733            ed.names.insert(n.clone(), *num);
3734        }
3735        enum_arcs.insert(name.clone(), Arc::new(ed));
3736    }
3737    let mut ext_index: BTreeMap<String, (String, u32, String)> = BTreeMap::new();
3738    for (parent_feat, ext) in &extensions {
3739        let fd = raw_field_to_desc(
3740            ext,
3741            *parent_feat,
3742            edition2024_files.contains(&ext.file_name),
3743        );
3744        let extendee = fd
3745            .extendee
3746            .as_deref()
3747            .unwrap_or("")
3748            .trim_start_matches('.')
3749            .to_string();
3750        if let Some(type_name) = fd.type_name.as_deref() {
3751            let key = type_name.trim_start_matches('.');
3752            if let Some(target) = skeletons.get(key) {
3753                check_symbol_visible_from_file(
3754                    &ext.file_name,
3755                    &target.file_name,
3756                    key,
3757                    &symbol_metadata,
3758                )?;
3759            }
3760            if let Some(target) = enum_arcs.get(key) {
3761                check_symbol_visible_from_file(
3762                    &ext.file_name,
3763                    &target.file_name,
3764                    key,
3765                    &symbol_metadata,
3766                )?;
3767            }
3768        }
3769        if let Some(desc) = skeletons.get_mut(&extendee) {
3770            if !ext.file_name.is_empty() {
3771                check_symbol_visible_from_file(
3772                    &ext.file_name,
3773                    &desc.file_name,
3774                    &extendee,
3775                    &symbol_metadata,
3776                )?;
3777            }
3778            desc.fields_by_name
3779                .entry(fd.name.clone())
3780                .or_insert(fd.number);
3781            if !fd.json_name.is_empty() {
3782                desc.fields_by_json_name
3783                    .entry(fd.json_name.clone())
3784                    .or_insert(fd.number);
3785            }
3786            let full = format!("{extendee}.{}", fd.name);
3787            desc.fields_by_name.insert(full, fd.number);
3788            if !ext.full_ext_name.is_empty() {
3789                desc.fields_by_name
3790                    .insert(ext.full_ext_name.clone(), fd.number);
3791                let file = if ext.file_name.is_empty() {
3792                    desc.file_name.clone()
3793                } else {
3794                    ext.file_name.clone()
3795                };
3796                ext_index.insert(
3797                    ext.full_ext_name.clone(),
3798                    (extendee.clone(), fd.number, file),
3799                );
3800            }
3801            desc.fields.insert(fd.number, fd);
3802        }
3803    }
3804    let lookup: BTreeMap<String, Arc<MessageDescriptor>> = skeletons
3805        .iter()
3806        .map(|(k, v)| (k.clone(), Arc::new(v.clone())))
3807        .collect();
3808    let mut resolved = BTreeMap::new();
3809    for (name, mut d) in skeletons {
3810        for field in d.fields.values_mut() {
3811            if let Some(tn) = &field.type_name {
3812                let key = tn.trim_start_matches('.');
3813                if let Some(target) = lookup.get(key) {
3814                    check_symbol_visible_from_file(
3815                        &d.file_name,
3816                        &target.file_name,
3817                        key,
3818                        &symbol_metadata,
3819                    )?;
3820                    field.message = Some(target.clone());
3821                    if target.is_map_entry {
3822                        field.is_map = true;
3823                        field.cardinality = Cardinality::Repeated;
3824                        field.packed = false;
3825                        field.delimited = false;
3826                    }
3827                }
3828                if field.field_type == FieldType::Enum || field.message.is_none() {
3829                    if let Some(en) = enum_arcs.get(key) {
3830                        check_symbol_visible_from_file(
3831                            &d.file_name,
3832                            &en.file_name,
3833                            key,
3834                            &symbol_metadata,
3835                        )?;
3836                        field.enum_ty = Some(en.clone());
3837                        field.field_type = FieldType::Enum;
3838                    }
3839                }
3840            }
3841        }
3842        if d.is_map_entry {
3843            for field in d.fields.values_mut() {
3844                field.delimited = false;
3845            }
3846        }
3847        let mut alts = Vec::new();
3848        for field in d.fields.values() {
3849            if field.extension_name.is_some() {
3850                continue;
3851            }
3852            if field.field_type == FieldType::Group || field.delimited {
3853                if let Some(tn) = &field.type_name {
3854                    let short = tn.rsplit('.').next().unwrap_or(tn);
3855                    alts.push((short.to_string(), field.number));
3856                    alts.push((short.to_ascii_lowercase(), field.number));
3857                }
3858            }
3859        }
3860        for (alt, n) in alts {
3861            d.fields_by_name.entry(alt).or_insert(n);
3862        }
3863        resolved.insert(name, Arc::new(d));
3864    }
3865    Ok(DescriptorPool {
3866        messages: resolved,
3867        enums: enum_arcs,
3868        extensions_by_name: ext_index,
3869        services: BTreeMap::new(),
3870        files: BTreeMap::new(),
3871        public_imports: BTreeMap::new(),
3872        file_metadata: BTreeMap::new(),
3873        symbol_metadata,
3874    })
3875}
3876
3877fn raw_field_to_desc(f: &RawField, parent: RawFeatures, edition2024: bool) -> FieldDescriptor {
3878    let feat = parent.merge(f.features);
3879    let mut field_type = FieldType::from_i32(f.ty).unwrap_or(FieldType::Message);
3880    if f.ty == 0 && !f.type_name.is_empty() {
3881        field_type = FieldType::Message;
3882    }
3883    let cardinality = match f.label {
3884        3 => Cardinality::Repeated,
3885        2 => Cardinality::Required,
3886        _ if feat.presence == 3 => Cardinality::Required,
3887        _ => Cardinality::Optional,
3888    };
3889    let presence = if cardinality == Cardinality::Repeated
3890        || field_type == FieldType::Message
3891        || field_type == FieldType::Group
3892        || f.proto3_optional
3893        || f.oneof_index.is_some()
3894        || feat.presence == 1
3895        || feat.presence == 3
3896    {
3897        Presence::Explicit
3898    } else {
3899        Presence::Implicit
3900    };
3901    let packed = f.packed.unwrap_or(
3902        cardinality == Cardinality::Repeated
3903            && field_type.is_packable()
3904            && feat.repeated_encoding == 1,
3905    );
3906    FieldDescriptor {
3907        name: f.name.clone(),
3908        number: f.number,
3909        field_type,
3910        cardinality,
3911        presence,
3912        packed,
3913        type_name: if f.type_name.is_empty() {
3914            None
3915        } else {
3916            Some(f.type_name.clone())
3917        },
3918        json_name: if f.json_name.is_empty() {
3919            f.name.clone()
3920        } else {
3921            f.json_name.clone()
3922        },
3923        is_map: false,
3924        message: None,
3925        enum_ty: None,
3926        oneof_index: f.oneof_index,
3927        // Pre-2024 map decoders use the outer field's UTF-8 flag for string entries.
3928        utf8_validate: feat.utf8 == 2 && (!edition2024 || field_type == FieldType::String),
3929        default: f.default_value.clone(),
3930        extendee: if f.extendee.is_empty() {
3931            None
3932        } else {
3933            Some(f.extendee.clone())
3934        },
3935        delimited: field_type == FieldType::Group
3936            || (feat.message_encoding == 2 && field_type == FieldType::Message),
3937        extension_name: if f.full_ext_name.is_empty() {
3938            None
3939        } else {
3940            Some(f.full_ext_name.clone())
3941        },
3942        options: f.options.clone(),
3943        comments: f.comments.clone(),
3944        deprecated: f.deprecated,
3945    }
3946}