Skip to main content

vulkan_registry/
parser.rs

1use quick_xml::{
2    Reader,
3    escape::resolve_xml_entity,
4    events::{BytesStart, Event, attributes::Attribute},
5};
6
7use crate::registry::*;
8
9impl Registry {
10    /// Parses the given XML text. This library is only tested with the bundled
11    /// XML file versions, but may work with others.
12    pub fn parse(xml: &str) -> Self {
13        let mut parser = Parser {
14            reader: Reader::from_str(xml),
15        };
16        parser.parse_file()
17    }
18
19    /// Parses the bundled copy of
20    /// [video.xml](https://github.com/KhronosGroup/Vulkan-Headers/blob/main/registry/video.xml).
21    pub fn video() -> Self {
22        Self::parse(include_str!("video.xml"))
23    }
24
25    /// Parses the bundled copy of
26    /// [vk.xml](https://github.com/KhronosGroup/Vulkan-Headers/blob/main/registry/vk.xml).
27    pub fn vk() -> Self {
28        Self::parse(include_str!("vk.xml"))
29    }
30}
31
32struct Parser<'a> {
33    reader: Reader<&'a [u8]>,
34}
35
36enum Content<'a> {
37    Text(&'a str),
38    Elem(Elem<'a>),
39}
40
41#[derive(Debug)]
42struct Elem<'a> {
43    is_empty: bool,
44    start: BytesStart<'a>,
45}
46
47impl<'a> Parser<'a> {
48    fn next_event<'b>(&mut self, buf: &'b mut Vec<u8>) -> Event<'b> {
49        self.reader.read_event_into(buf).unwrap()
50    }
51
52    fn save_attr(&mut self, attr: Attribute, out: &mut Option<String>) {
53        assert_eq!(*out, None);
54        let decoder = self.reader.decoder();
55        let value = attr.decode_and_unescape_value(decoder).unwrap();
56        *out = Some(value.into_owned());
57    }
58
59    fn assert_is_ws(&mut self, text: &[u8]) {
60        for &b in text {
61            assert!(matches!(b, b'\n' | b'\r' | b' '));
62        }
63    }
64
65    fn parse_contents<F>(&mut self, elem: Elem, mut f: F)
66    where
67        F: FnMut(&mut Parser, Content),
68    {
69        if elem.is_empty {
70            return;
71        }
72
73        let mut buf = Vec::new();
74        loop {
75            match self.next_event(&mut buf) {
76                Event::Comment(_) => {
77                    ();
78                }
79                Event::Text(text) => {
80                    let text = text.xml_content().unwrap();
81                    f(self, Content::Text(&text));
82                }
83                Event::GeneralRef(text) => {
84                    let text = text.xml_content().unwrap();
85                    let text = resolve_xml_entity(&text).unwrap();
86                    f(self, Content::Text(text));
87                }
88                Event::Empty(start) => {
89                    let is_empty = true;
90                    f(self, Content::Elem(Elem { is_empty, start }));
91                }
92                Event::Start(start) => {
93                    let is_empty = false;
94                    f(self, Content::Elem(Elem { is_empty, start }));
95                }
96                Event::End(end) => {
97                    assert_eq!(end.name(), elem.start.name());
98                    break;
99                }
100                event => {
101                    panic!("unexpected event: {event:?}");
102                }
103            }
104            buf.clear();
105        }
106    }
107
108    fn parse_file(&mut self) -> Registry {
109        let mut registry = None;
110
111        let mut buf = Vec::new();
112        loop {
113            match self.next_event(&mut buf) {
114                Event::Decl(_) => {
115                    ();
116                }
117                Event::Text(text) => {
118                    self.assert_is_ws(&text);
119                }
120                Event::Start(start) => match start.name().as_ref() {
121                    b"registry" => {
122                        let is_empty = false;
123                        assert_eq!(registry, None);
124                        registry = Some(self.parse_registry(Elem { is_empty, start }));
125                    }
126                    _ => {
127                        panic!("unexpected elem: {start:?}");
128                    }
129                },
130                Event::Eof => {
131                    break;
132                }
133                event => {
134                    panic!("unexpected event: {event:?}");
135                }
136            }
137            buf.clear();
138        }
139
140        registry.unwrap()
141    }
142
143    fn parse_registry(&mut self, elem: Elem) -> Registry {
144        for attr in elem.start.attributes() {
145            let attr = attr.unwrap();
146            match attr.key.as_ref() {
147                _ => panic!("unexpected attr: {attr:?}"),
148            }
149        }
150
151        let mut contents = Vec::new();
152        self.parse_contents(elem, |this, content| match content {
153            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
154            Content::Elem(elem) => match elem.start.name().as_ref() {
155                b"comment" => {
156                    let text = this.parse_text_elem(elem);
157                    contents.push(RegistryContent::Comment(text));
158                }
159                b"platforms" => {
160                    let platforms = this.parse_platforms(elem);
161                    contents.push(RegistryContent::Platforms(platforms));
162                }
163                b"tags" => {
164                    let tags = this.parse_tags(elem);
165                    contents.push(RegistryContent::Tags(tags));
166                }
167                b"types" => {
168                    let types = this.parse_types(elem);
169                    contents.push(RegistryContent::Types(types));
170                }
171                b"enums" => {
172                    let enums = this.parse_enums(elem);
173                    contents.push(RegistryContent::Enums(enums));
174                }
175                b"commands" => {
176                    let commands = this.parse_commands(elem);
177                    contents.push(RegistryContent::Commands(commands));
178                }
179                b"feature" => {
180                    let feature = this.parse_feature(elem);
181                    contents.push(RegistryContent::Feature(feature));
182                }
183                b"extensions" => {
184                    let extensions = this.parse_extensions(elem);
185                    contents.push(RegistryContent::Extensions(extensions));
186                }
187                b"formats" => {
188                    let formats = this.parse_formats(elem);
189                    contents.push(RegistryContent::Formats(formats));
190                }
191                b"spirvextensions" => {
192                    let extensions = this.parse_spirv_extensions(elem);
193                    contents.push(RegistryContent::SpirvExtensions(extensions));
194                }
195                b"spirvcapabilities" => {
196                    let capabilities = this.parse_spirv_capabilities(elem);
197                    contents.push(RegistryContent::SpirvCapabilities(capabilities));
198                }
199                b"sync" => {
200                    let syncs = this.parse_syncs(elem);
201                    contents.push(RegistryContent::Syncs(syncs));
202                }
203                b"videocodecs" => {
204                    let codecs = this.parse_video_codecs(elem);
205                    contents.push(RegistryContent::VideoCodecs(codecs));
206                }
207                _ => {
208                    panic!("unexpected elem: {elem:?}");
209                }
210            },
211        });
212
213        Registry { contents }
214    }
215
216    fn parse_text_elem(&mut self, elem: Elem) -> String {
217        for attr in elem.start.attributes() {
218            let attr = attr.unwrap();
219            match attr.key.as_ref() {
220                _ => panic!("unexpected attr: {attr:?}"),
221            }
222        }
223
224        let mut contents = String::new();
225        self.parse_contents(elem, |_this, content| match content {
226            Content::Text(text) => contents += text,
227            Content::Elem(elem) => panic!("unexpected elem: {elem:?}"),
228        });
229
230        contents
231    }
232
233    fn parse_platforms(&mut self, elem: Elem) -> Platforms {
234        let mut comment = None;
235
236        for attr in elem.start.attributes() {
237            let attr = attr.unwrap();
238            match attr.key.as_ref() {
239                b"comment" => self.save_attr(attr, &mut comment),
240                _ => panic!("unexpected attr: {attr:?}"),
241            }
242        }
243
244        let mut contents = Vec::new();
245        self.parse_contents(elem, |this, content| match content {
246            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
247            Content::Elem(elem) => match elem.start.name().as_ref() {
248                b"platform" => {
249                    let platform = this.parse_platform(elem);
250                    contents.push(PlatformsContent::Platform(platform));
251                }
252                _ => {
253                    panic!("unexpected elem: {elem:?}");
254                }
255            },
256        });
257
258        Platforms { comment, contents }
259    }
260
261    fn parse_platform(&mut self, elem: Elem) -> Platform {
262        let mut comment = None;
263        let mut name = None;
264        let mut protect = None;
265
266        for attr in elem.start.attributes() {
267            let attr = attr.unwrap();
268            match attr.key.as_ref() {
269                b"comment" => self.save_attr(attr, &mut comment),
270                b"name" => self.save_attr(attr, &mut name),
271                b"protect" => self.save_attr(attr, &mut protect),
272                _ => panic!("unexpected attr: {attr:?}"),
273            }
274        }
275
276        assert_eq!(elem.is_empty, true);
277        Platform {
278            comment,
279            name,
280            protect,
281        }
282    }
283
284    fn parse_tags(&mut self, elem: Elem) -> Tags {
285        let mut comment = None;
286
287        for attr in elem.start.attributes() {
288            let attr = attr.unwrap();
289            match attr.key.as_ref() {
290                b"comment" => self.save_attr(attr, &mut comment),
291                _ => panic!("unexpected attr: {attr:?}"),
292            }
293        }
294
295        let mut contents = Vec::new();
296        self.parse_contents(elem, |this, content| match content {
297            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
298            Content::Elem(elem) => match elem.start.name().as_ref() {
299                b"tag" => {
300                    let tag = this.parse_tag(elem);
301                    contents.push(TagsContent::Tag(tag));
302                }
303                _ => {
304                    panic!("unexpected elem: {elem:?}");
305                }
306            },
307        });
308
309        Tags { comment, contents }
310    }
311
312    fn parse_tag(&mut self, elem: Elem) -> Tag {
313        let mut author = None;
314        let mut contact = None;
315        let mut name = None;
316
317        for attr in elem.start.attributes() {
318            let attr = attr.unwrap();
319            match attr.key.as_ref() {
320                b"author" => self.save_attr(attr, &mut author),
321                b"contact" => self.save_attr(attr, &mut contact),
322                b"name" => self.save_attr(attr, &mut name),
323                _ => panic!("unexpected attr: {attr:?}"),
324            }
325        }
326
327        assert_eq!(elem.is_empty, true);
328        Tag {
329            author,
330            contact,
331            name,
332        }
333    }
334
335    fn parse_types(&mut self, elem: Elem) -> Types {
336        let mut comment = None;
337
338        for attr in elem.start.attributes() {
339            let attr = attr.unwrap();
340            match attr.key.as_ref() {
341                b"comment" => self.save_attr(attr, &mut comment),
342                _ => panic!("unexpected attr: {attr:?}"),
343            }
344        }
345
346        let mut contents = Vec::new();
347        self.parse_contents(elem, |this, content| match content {
348            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
349            Content::Elem(elem) => match elem.start.name().as_ref() {
350                b"comment" => {
351                    let comment = this.parse_text_elem(elem);
352                    contents.push(TypesContent::Comment(comment));
353                }
354                b"type" => {
355                    let typ = this.parse_type(elem);
356                    contents.push(TypesContent::Type(typ));
357                }
358                _ => {
359                    panic!("unexpected elem: {elem:?}");
360                }
361            },
362        });
363
364        Types { comment, contents }
365    }
366
367    fn parse_type(&mut self, elem: Elem) -> Type {
368        let mut alias = None;
369        let mut allowduplicate = None;
370        let mut api = None;
371        let mut bitvalues = None;
372        let mut category = None;
373        let mut comment = None;
374        let mut name = None;
375        let mut objtypeenum = None;
376        let mut parent = None;
377        let mut requiredlimittype = None;
378        let mut requires = None;
379        let mut returnedonly = None;
380        let mut structextends = None;
381
382        for attr in elem.start.attributes() {
383            let attr = attr.unwrap();
384            match attr.key.as_ref() {
385                b"alias" => self.save_attr(attr, &mut alias),
386                b"allowduplicate" => self.save_attr(attr, &mut allowduplicate),
387                b"api" => self.save_attr(attr, &mut api),
388                b"bitvalues" => self.save_attr(attr, &mut bitvalues),
389                b"category" => self.save_attr(attr, &mut category),
390                b"comment" => self.save_attr(attr, &mut comment),
391                b"name" => self.save_attr(attr, &mut name),
392                b"objtypeenum" => self.save_attr(attr, &mut objtypeenum),
393                b"parent" => self.save_attr(attr, &mut parent),
394                b"requiredlimittype" => self.save_attr(attr, &mut requiredlimittype),
395                b"requires" => self.save_attr(attr, &mut requires),
396                b"returnedonly" => self.save_attr(attr, &mut returnedonly),
397                b"structextends" => self.save_attr(attr, &mut structextends),
398                _ => panic!("unexpected attr: {attr:?}"),
399            }
400        }
401
402        let mut contents = Vec::new();
403        self.parse_contents(elem, |this, content| match content {
404            Content::Text(text) => {
405                contents.push(TypeContent::Text(text.to_owned()));
406            }
407            Content::Elem(elem) => match elem.start.name().as_ref() {
408                b"comment" => {
409                    let comment = this.parse_text_elem(elem);
410                    contents.push(TypeContent::Comment(comment));
411                }
412                b"type" => {
413                    let typ = this.parse_text_elem(elem);
414                    contents.push(TypeContent::Type(typ));
415                }
416                b"name" => {
417                    let name = this.parse_text_elem(elem);
418                    contents.push(TypeContent::Name(name));
419                }
420                b"member" => {
421                    let member = this.parse_member(elem);
422                    contents.push(TypeContent::Member(member));
423                }
424                b"proto" => {
425                    let proto = this.parse_proto(elem);
426                    contents.push(TypeContent::Proto(proto));
427                }
428                b"param" => {
429                    let param = this.parse_param(elem);
430                    contents.push(TypeContent::Param(param));
431                }
432                _ => {
433                    panic!("unexpected elem: {elem:?}");
434                }
435            },
436        });
437
438        Type {
439            alias,
440            allowduplicate,
441            api,
442            bitvalues,
443            category,
444            comment,
445            name,
446            objtypeenum,
447            parent,
448            requiredlimittype,
449            requires,
450            returnedonly,
451            structextends,
452            contents,
453        }
454    }
455
456    fn parse_member(&mut self, elem: Elem) -> Member {
457        let mut altlen = None;
458        let mut api = None;
459        let mut deprecated = None;
460        let mut externsync = None;
461        let mut featurelink = None;
462        let mut len = None;
463        let mut limittype = None;
464        let mut noautovalidity = None;
465        let mut objecttype = None;
466        let mut optional = None;
467        let mut selection = None;
468        let mut selector = None;
469        let mut values = None;
470
471        for attr in elem.start.attributes() {
472            let attr = attr.unwrap();
473            match attr.key.as_ref() {
474                b"altlen" => self.save_attr(attr, &mut altlen),
475                b"api" => self.save_attr(attr, &mut api),
476                b"deprecated" => self.save_attr(attr, &mut deprecated),
477                b"externsync" => self.save_attr(attr, &mut externsync),
478                b"featurelink" => self.save_attr(attr, &mut featurelink),
479                b"len" => self.save_attr(attr, &mut len),
480                b"limittype" => self.save_attr(attr, &mut limittype),
481                b"noautovalidity" => self.save_attr(attr, &mut noautovalidity),
482                b"objecttype" => self.save_attr(attr, &mut objecttype),
483                b"optional" => self.save_attr(attr, &mut optional),
484                b"selection" => self.save_attr(attr, &mut selection),
485                b"selector" => self.save_attr(attr, &mut selector),
486                b"values" => self.save_attr(attr, &mut values),
487                _ => panic!("unexpected attr: {attr:?}"),
488            }
489        }
490
491        let mut contents = Vec::new();
492        self.parse_contents(elem, |this, content| match content {
493            Content::Text(text) => {
494                contents.push(MemberContent::Text(text.to_owned()));
495            }
496            Content::Elem(elem) => match elem.start.name().as_ref() {
497                b"comment" => {
498                    let comment = this.parse_text_elem(elem);
499                    contents.push(MemberContent::Comment(comment));
500                }
501                b"type" => {
502                    let typ = this.parse_text_elem(elem);
503                    contents.push(MemberContent::Type(typ));
504                }
505                b"name" => {
506                    let name = this.parse_text_elem(elem);
507                    contents.push(MemberContent::Name(name));
508                }
509                b"enum" => {
510                    let enu = this.parse_text_elem(elem);
511                    contents.push(MemberContent::Enum(enu));
512                }
513                _ => {
514                    panic!("unexpected elem: {elem:?}");
515                }
516            },
517        });
518
519        Member {
520            altlen,
521            api,
522            deprecated,
523            externsync,
524            featurelink,
525            len,
526            limittype,
527            noautovalidity,
528            objecttype,
529            optional,
530            selection,
531            selector,
532            values,
533            contents,
534        }
535    }
536
537    fn parse_enums(&mut self, elem: Elem) -> Enums {
538        let mut bitwidth = None;
539        let mut comment = None;
540        let mut name = None;
541        let mut typ = None;
542
543        for attr in elem.start.attributes() {
544            let attr = attr.unwrap();
545            match attr.key.as_ref() {
546                b"bitwidth" => self.save_attr(attr, &mut bitwidth),
547                b"comment" => self.save_attr(attr, &mut comment),
548                b"name" => self.save_attr(attr, &mut name),
549                b"type" => self.save_attr(attr, &mut typ),
550                _ => panic!("unexpected attr: {attr:?}"),
551            }
552        }
553
554        let mut contents = Vec::new();
555        self.parse_contents(elem, |this, content| match content {
556            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
557            Content::Elem(elem) => match elem.start.name().as_ref() {
558                b"comment" => {
559                    let comment = this.parse_text_elem(elem);
560                    contents.push(EnumsContent::Comment(comment));
561                }
562                b"enum" => {
563                    let enu = this.parse_enum(elem);
564                    contents.push(EnumsContent::Enum(enu));
565                }
566                b"unused" => {
567                    let unused = this.parse_unused(elem);
568                    contents.push(EnumsContent::Unused(unused));
569                }
570                _ => {
571                    panic!("unexpected elem: {elem:?}");
572                }
573            },
574        });
575
576        Enums {
577            bitwidth,
578            comment,
579            name,
580            typ,
581            contents,
582        }
583    }
584
585    fn parse_enum(&mut self, elem: Elem) -> Enum {
586        let mut alias = None;
587        let mut api = None;
588        let mut bitpos = None;
589        let mut comment = None;
590        let mut deprecated = None;
591        let mut name = None;
592        let mut typ = None;
593        let mut value = None;
594
595        for attr in elem.start.attributes() {
596            let attr = attr.unwrap();
597            match attr.key.as_ref() {
598                b"alias" => self.save_attr(attr, &mut alias),
599                b"api" => self.save_attr(attr, &mut api),
600                b"bitpos" => self.save_attr(attr, &mut bitpos),
601                b"comment" => self.save_attr(attr, &mut comment),
602                b"deprecated" => self.save_attr(attr, &mut deprecated),
603                b"name" => self.save_attr(attr, &mut name),
604                b"type" => self.save_attr(attr, &mut typ),
605                b"value" => self.save_attr(attr, &mut value),
606                _ => panic!("unexpected attr: {attr:?}"),
607            }
608        }
609
610        assert_eq!(elem.is_empty, true);
611        Enum {
612            alias,
613            api,
614            bitpos,
615            comment,
616            deprecated,
617            name,
618            typ,
619            value,
620        }
621    }
622
623    fn parse_unused(&mut self, elem: Elem) -> Unused {
624        let mut comment = None;
625        let mut start = None;
626
627        for attr in elem.start.attributes() {
628            let attr = attr.unwrap();
629            match attr.key.as_ref() {
630                b"comment" => self.save_attr(attr, &mut comment),
631                b"start" => self.save_attr(attr, &mut start),
632                _ => panic!("unexpected attr: {attr:?}"),
633            }
634        }
635
636        assert_eq!(elem.is_empty, true);
637        Unused { comment, start }
638    }
639
640    fn parse_commands(&mut self, elem: Elem) -> Commands {
641        let mut comment = None;
642
643        for attr in elem.start.attributes() {
644            let attr = attr.unwrap();
645            match attr.key.as_ref() {
646                b"comment" => self.save_attr(attr, &mut comment),
647                _ => panic!("unexpected attr: {attr:?}"),
648            }
649        }
650
651        let mut contents = Vec::new();
652        self.parse_contents(elem, |this, content| match content {
653            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
654            Content::Elem(elem) => match elem.start.name().as_ref() {
655                b"command" => {
656                    let command = this.parse_command(elem);
657                    contents.push(CommandsContent::Command(command));
658                }
659                _ => {
660                    panic!("unexpected elem: {elem:?}");
661                }
662            },
663        });
664
665        Commands { comment, contents }
666    }
667
668    fn parse_command(&mut self, elem: Elem) -> Command {
669        let mut alias = None;
670        let mut allownoqueues = None;
671        let mut api = None;
672        let mut cmdbufferlevel = None;
673        let mut comment = None;
674        let mut conditionalrendering = None;
675        let mut errorcodes = None;
676        let mut export = None;
677        let mut name = None;
678        let mut queues = None;
679        let mut renderpass = None;
680        let mut successcodes = None;
681        let mut tasks = None;
682        let mut videocoding = None;
683
684        for attr in elem.start.attributes() {
685            let attr = attr.unwrap();
686            match attr.key.as_ref() {
687                b"alias" => self.save_attr(attr, &mut alias),
688                b"allownoqueues" => self.save_attr(attr, &mut allownoqueues),
689                b"api" => self.save_attr(attr, &mut api),
690                b"cmdbufferlevel" => self.save_attr(attr, &mut cmdbufferlevel),
691                b"comment" => self.save_attr(attr, &mut comment),
692                b"conditionalrendering" => self.save_attr(attr, &mut conditionalrendering),
693                b"errorcodes" => self.save_attr(attr, &mut errorcodes),
694                b"export" => self.save_attr(attr, &mut export),
695                b"name" => self.save_attr(attr, &mut name),
696                b"queues" => self.save_attr(attr, &mut queues),
697                b"renderpass" => self.save_attr(attr, &mut renderpass),
698                b"successcodes" => self.save_attr(attr, &mut successcodes),
699                b"tasks" => self.save_attr(attr, &mut tasks),
700                b"videocoding" => self.save_attr(attr, &mut videocoding),
701                _ => panic!("unexpected attr: {attr:?}"),
702            }
703        }
704
705        let mut contents = Vec::new();
706        self.parse_contents(elem, |this, content| match content {
707            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
708            Content::Elem(elem) => match elem.start.name().as_ref() {
709                b"proto" => {
710                    let proto = this.parse_proto(elem);
711                    contents.push(CommandContent::Proto(proto));
712                }
713                b"param" => {
714                    let param = this.parse_param(elem);
715                    contents.push(CommandContent::Param(param));
716                }
717                b"implicitexternsyncparams" => {
718                    let params = this.parse_implicit_extern_sync_params(elem);
719                    contents.push(CommandContent::ImplicitExternSyncParams(params));
720                }
721                _ => {
722                    panic!("unexpected elem: {elem:?}");
723                }
724            },
725        });
726
727        Command {
728            alias,
729            allownoqueues,
730            api,
731            cmdbufferlevel,
732            comment,
733            conditionalrendering,
734            errorcodes,
735            export,
736            name,
737            queues,
738            renderpass,
739            successcodes,
740            tasks,
741            videocoding,
742            contents,
743        }
744    }
745
746    fn parse_proto(&mut self, elem: Elem) -> Proto {
747        for attr in elem.start.attributes() {
748            let attr = attr.unwrap();
749            match attr.key.as_ref() {
750                _ => panic!("unexpected attr: {attr:?}"),
751            }
752        }
753
754        let mut contents = Vec::new();
755        self.parse_contents(elem, |this, content| match content {
756            Content::Text(text) => {
757                contents.push(ProtoContent::Text(text.to_owned()));
758            }
759            Content::Elem(elem) => match elem.start.name().as_ref() {
760                b"type" => {
761                    let typ = this.parse_text_elem(elem);
762                    contents.push(ProtoContent::Type(typ));
763                }
764                b"name" => {
765                    let name = this.parse_text_elem(elem);
766                    contents.push(ProtoContent::Name(name));
767                }
768                _ => {
769                    panic!("unexpected elem: {elem:?}");
770                }
771            },
772        });
773
774        Proto { contents }
775    }
776
777    fn parse_param(&mut self, elem: Elem) -> Param {
778        let mut altlen = None;
779        let mut api = None;
780        let mut externsync = None;
781        let mut len = None;
782        let mut noautovalidity = None;
783        let mut objecttype = None;
784        let mut optional = None;
785        let mut stride = None;
786        let mut validstructs = None;
787
788        for attr in elem.start.attributes() {
789            let attr = attr.unwrap();
790            match attr.key.as_ref() {
791                b"altlen" => self.save_attr(attr, &mut altlen),
792                b"api" => self.save_attr(attr, &mut api),
793                b"externsync" => self.save_attr(attr, &mut externsync),
794                b"len" => self.save_attr(attr, &mut len),
795                b"noautovalidity" => self.save_attr(attr, &mut noautovalidity),
796                b"objecttype" => self.save_attr(attr, &mut objecttype),
797                b"optional" => self.save_attr(attr, &mut optional),
798                b"stride" => self.save_attr(attr, &mut stride),
799                b"validstructs" => self.save_attr(attr, &mut validstructs),
800                _ => panic!("unexpected attr: {attr:?}"),
801            }
802        }
803
804        let mut contents = Vec::new();
805        self.parse_contents(elem, |this, content| match content {
806            Content::Text(text) => {
807                contents.push(ParamContent::Text(text.to_owned()));
808            }
809            Content::Elem(elem) => match elem.start.name().as_ref() {
810                b"type" => {
811                    let typ = this.parse_text_elem(elem);
812                    contents.push(ParamContent::Type(typ));
813                }
814                b"name" => {
815                    let name = this.parse_text_elem(elem);
816                    contents.push(ParamContent::Name(name));
817                }
818                _ => {
819                    panic!("unexpected elem: {elem:?}");
820                }
821            },
822        });
823
824        Param {
825            altlen,
826            api,
827            externsync,
828            len,
829            noautovalidity,
830            objecttype,
831            optional,
832            stride,
833            validstructs,
834            contents,
835        }
836    }
837
838    fn parse_implicit_extern_sync_params(&mut self, elem: Elem) -> ImplicitExternSyncParams {
839        for attr in elem.start.attributes() {
840            let attr = attr.unwrap();
841            match attr.key.as_ref() {
842                _ => panic!("unexpected attr: {attr:?}"),
843            }
844        }
845
846        let mut contents = Vec::new();
847        self.parse_contents(elem, |this, content| match content {
848            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
849            Content::Elem(elem) => match elem.start.name().as_ref() {
850                b"param" => {
851                    let param = this.parse_text_elem(elem);
852                    contents.push(ImplicitExternSyncParamsContent::Param(param));
853                }
854                _ => {
855                    panic!("unexpected elem: {elem:?}");
856                }
857            },
858        });
859
860        ImplicitExternSyncParams { contents }
861    }
862
863    fn parse_feature(&mut self, elem: Elem) -> Feature {
864        let mut api = None;
865        let mut apitype = None;
866        let mut comment = None;
867        let mut depends = None;
868        let mut name = None;
869        let mut number = None;
870
871        for attr in elem.start.attributes() {
872            let attr = attr.unwrap();
873            match attr.key.as_ref() {
874                b"api" => self.save_attr(attr, &mut api),
875                b"apitype" => self.save_attr(attr, &mut apitype),
876                b"comment" => self.save_attr(attr, &mut comment),
877                b"depends" => self.save_attr(attr, &mut depends),
878                b"name" => self.save_attr(attr, &mut name),
879                b"number" => self.save_attr(attr, &mut number),
880                _ => panic!("unexpected attr: {attr:?}"),
881            }
882        }
883
884        let mut contents = Vec::new();
885        self.parse_contents(elem, |this, content| match content {
886            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
887            Content::Elem(elem) => match elem.start.name().as_ref() {
888                b"require" => {
889                    let require = this.parse_require(elem);
890                    contents.push(FeatureContent::Require(require));
891                }
892                b"deprecate" => {
893                    let deprecate = this.parse_deprecate(elem);
894                    contents.push(FeatureContent::Deprecate(deprecate));
895                }
896                b"remove" => {
897                    let remove = this.parse_remove(elem);
898                    contents.push(FeatureContent::Remove(remove));
899                }
900                _ => {
901                    panic!("unexpected elem: {elem:?}");
902                }
903            },
904        });
905
906        Feature {
907            api,
908            apitype,
909            comment,
910            depends,
911            name,
912            number,
913            contents,
914        }
915    }
916
917    fn parse_extensions(&mut self, elem: Elem) -> Extensions {
918        let mut comment = None;
919
920        for attr in elem.start.attributes() {
921            let attr = attr.unwrap();
922            match attr.key.as_ref() {
923                b"comment" => self.save_attr(attr, &mut comment),
924                _ => panic!("unexpected attr: {attr:?}"),
925            }
926        }
927
928        let mut contents = Vec::new();
929        self.parse_contents(elem, |this, content| match content {
930            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
931            Content::Elem(elem) => match elem.start.name().as_ref() {
932                b"extension" => {
933                    let extension = this.parse_extension(elem);
934                    contents.push(ExtensionsContent::Extension(extension));
935                }
936                _ => {
937                    panic!("unexpected elem: {elem:?}");
938                }
939            },
940        });
941
942        Extensions { comment, contents }
943    }
944
945    fn parse_extension(&mut self, elem: Elem) -> Extension {
946        let mut author = None;
947        let mut comment = None;
948        let mut contact = None;
949        let mut depends = None;
950        let mut deprecatedby = None;
951        let mut name = None;
952        let mut nofeatures = None;
953        let mut number = None;
954        let mut obsoletedby = None;
955        let mut platform = None;
956        let mut promotedto = None;
957        let mut provisional = None;
958        let mut ratified = None;
959        let mut sortorder = None;
960        let mut specialuse = None;
961        let mut supported = None;
962        let mut typ = None;
963
964        for attr in elem.start.attributes() {
965            let attr = attr.unwrap();
966            match attr.key.as_ref() {
967                b"author" => self.save_attr(attr, &mut author),
968                b"comment" => self.save_attr(attr, &mut comment),
969                b"contact" => self.save_attr(attr, &mut contact),
970                b"depends" => self.save_attr(attr, &mut depends),
971                b"deprecatedby" => self.save_attr(attr, &mut deprecatedby),
972                b"name" => self.save_attr(attr, &mut name),
973                b"nofeatures" => self.save_attr(attr, &mut nofeatures),
974                b"number" => self.save_attr(attr, &mut number),
975                b"obsoletedby" => self.save_attr(attr, &mut obsoletedby),
976                b"platform" => self.save_attr(attr, &mut platform),
977                b"promotedto" => self.save_attr(attr, &mut promotedto),
978                b"provisional" => self.save_attr(attr, &mut provisional),
979                b"ratified" => self.save_attr(attr, &mut ratified),
980                b"sortorder" => self.save_attr(attr, &mut sortorder),
981                b"specialuse" => self.save_attr(attr, &mut specialuse),
982                b"supported" => self.save_attr(attr, &mut supported),
983                b"type" => self.save_attr(attr, &mut typ),
984                _ => panic!("unexpected attr: {attr:?}"),
985            }
986        }
987
988        let mut contents = Vec::new();
989        self.parse_contents(elem, |this, content| match content {
990            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
991            Content::Elem(elem) => match elem.start.name().as_ref() {
992                b"require" => {
993                    let require = this.parse_require(elem);
994                    contents.push(ExtensionContent::Require(require));
995                }
996                b"deprecate" => {
997                    let deprecate = this.parse_deprecate(elem);
998                    contents.push(ExtensionContent::Deprecate(deprecate));
999                }
1000                b"remove" => {
1001                    let remove = this.parse_remove(elem);
1002                    contents.push(ExtensionContent::Remove(remove));
1003                }
1004                _ => {
1005                    panic!("unexpected elem: {elem:?}");
1006                }
1007            },
1008        });
1009
1010        Extension {
1011            author,
1012            comment,
1013            contact,
1014            depends,
1015            deprecatedby,
1016            name,
1017            nofeatures,
1018            number,
1019            obsoletedby,
1020            platform,
1021            promotedto,
1022            provisional,
1023            ratified,
1024            sortorder,
1025            specialuse,
1026            supported,
1027            typ,
1028            contents,
1029        }
1030    }
1031
1032    fn parse_require(&mut self, elem: Elem) -> Require {
1033        let mut api = None;
1034        let mut comment = None;
1035        let mut depends = None;
1036
1037        for attr in elem.start.attributes() {
1038            let attr = attr.unwrap();
1039            match attr.key.as_ref() {
1040                b"api" => self.save_attr(attr, &mut api),
1041                b"comment" => self.save_attr(attr, &mut comment),
1042                b"depends" => self.save_attr(attr, &mut depends),
1043                _ => panic!("unexpected attr: {attr:?}"),
1044            }
1045        }
1046
1047        let mut contents = Vec::new();
1048        self.parse_contents(elem, |this, content| match content {
1049            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1050            Content::Elem(elem) => match elem.start.name().as_ref() {
1051                b"comment" => {
1052                    let comment = this.parse_text_elem(elem);
1053                    contents.push(RequireContent::Comment(comment));
1054                }
1055                b"type" => {
1056                    let typ = this.parse_general_ref(elem);
1057                    contents.push(RequireContent::Type(typ));
1058                }
1059                b"enum" => {
1060                    let enu = this.parse_require_enum(elem);
1061                    contents.push(RequireContent::Enum(enu));
1062                }
1063                b"command" => {
1064                    let command = this.parse_general_ref(elem);
1065                    contents.push(RequireContent::Command(command));
1066                }
1067                b"feature" => {
1068                    let feature = this.parse_feature_ref(elem);
1069                    contents.push(RequireContent::Feature(feature));
1070                }
1071                _ => {
1072                    panic!("unexpected elem: {elem:?}");
1073                }
1074            },
1075        });
1076
1077        Require {
1078            api,
1079            comment,
1080            depends,
1081            contents,
1082        }
1083    }
1084
1085    fn parse_require_enum(&mut self, elem: Elem) -> RequireEnum {
1086        let mut alias = None;
1087        let mut api = None;
1088        let mut bitpos = None;
1089        let mut comment = None;
1090        let mut deprecated = None;
1091        let mut dir = None;
1092        let mut extends = None;
1093        let mut extnumber = None;
1094        let mut name = None;
1095        let mut offset = None;
1096        let mut protect = None;
1097        let mut typ = None;
1098        let mut value = None;
1099
1100        for attr in elem.start.attributes() {
1101            let attr = attr.unwrap();
1102            match attr.key.as_ref() {
1103                b"alias" => self.save_attr(attr, &mut alias),
1104                b"api" => self.save_attr(attr, &mut api),
1105                b"bitpos" => self.save_attr(attr, &mut bitpos),
1106                b"comment" => self.save_attr(attr, &mut comment),
1107                b"deprecated" => self.save_attr(attr, &mut deprecated),
1108                b"dir" => self.save_attr(attr, &mut dir),
1109                b"extends" => self.save_attr(attr, &mut extends),
1110                b"extnumber" => self.save_attr(attr, &mut extnumber),
1111                b"name" => self.save_attr(attr, &mut name),
1112                b"offset" => self.save_attr(attr, &mut offset),
1113                b"protect" => self.save_attr(attr, &mut protect),
1114                b"type" => self.save_attr(attr, &mut typ),
1115                b"value" => self.save_attr(attr, &mut value),
1116                _ => panic!("unexpected attr: {attr:?}"),
1117            }
1118        }
1119
1120        assert_eq!(elem.is_empty, true);
1121        RequireEnum {
1122            alias,
1123            api,
1124            bitpos,
1125            comment,
1126            deprecated,
1127            dir,
1128            extends,
1129            extnumber,
1130            name,
1131            offset,
1132            protect,
1133            typ,
1134            value,
1135        }
1136    }
1137
1138    fn parse_deprecate(&mut self, elem: Elem) -> Deprecate {
1139        let mut explanationlink = None;
1140
1141        for attr in elem.start.attributes() {
1142            let attr = attr.unwrap();
1143            match attr.key.as_ref() {
1144                b"explanationlink" => self.save_attr(attr, &mut explanationlink),
1145                _ => panic!("unexpected attr: {attr:?}"),
1146            }
1147        }
1148
1149        let mut contents = Vec::new();
1150        self.parse_contents(elem, |this, content| match content {
1151            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1152            Content::Elem(elem) => match elem.start.name().as_ref() {
1153                b"type" => {
1154                    let typ = this.parse_general_ref(elem);
1155                    contents.push(DeprecateContent::Type(typ));
1156                }
1157                b"command" => {
1158                    let command = this.parse_general_ref(elem);
1159                    contents.push(DeprecateContent::Command(command));
1160                }
1161                _ => {
1162                    panic!("unexpected elem: {elem:?}");
1163                }
1164            },
1165        });
1166
1167        Deprecate {
1168            explanationlink,
1169            contents,
1170        }
1171    }
1172
1173    fn parse_remove(&mut self, elem: Elem) -> Remove {
1174        let mut comment = None;
1175        let mut reasonlink = None;
1176
1177        for attr in elem.start.attributes() {
1178            let attr = attr.unwrap();
1179            match attr.key.as_ref() {
1180                b"comment" => self.save_attr(attr, &mut comment),
1181                b"reasonlink" => self.save_attr(attr, &mut reasonlink),
1182                _ => panic!("unexpected attr: {attr:?}"),
1183            }
1184        }
1185
1186        let mut contents = Vec::new();
1187        self.parse_contents(elem, |this, content| match content {
1188            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1189            Content::Elem(elem) => match elem.start.name().as_ref() {
1190                b"type" => {
1191                    let typ = this.parse_general_ref(elem);
1192                    contents.push(RemoveContent::Type(typ));
1193                }
1194                b"enum" => {
1195                    let enu = this.parse_general_ref(elem);
1196                    contents.push(RemoveContent::Enum(enu));
1197                }
1198                b"command" => {
1199                    let command = this.parse_general_ref(elem);
1200                    contents.push(RemoveContent::Command(command));
1201                }
1202                b"feature" => {
1203                    let feature = this.parse_feature_ref(elem);
1204                    contents.push(RemoveContent::Feature(feature));
1205                }
1206                _ => {
1207                    panic!("unexpected elem: {elem:?}");
1208                }
1209            },
1210        });
1211
1212        Remove {
1213            comment,
1214            reasonlink,
1215            contents,
1216        }
1217    }
1218
1219    fn parse_general_ref(&mut self, elem: Elem) -> GeneralRef {
1220        let mut comment = None;
1221        let mut name = None;
1222
1223        for attr in elem.start.attributes() {
1224            let attr = attr.unwrap();
1225            match attr.key.as_ref() {
1226                b"comment" => self.save_attr(attr, &mut comment),
1227                b"name" => self.save_attr(attr, &mut name),
1228                _ => panic!("unexpected attr: {attr:?}"),
1229            }
1230        }
1231
1232        assert_eq!(elem.is_empty, true);
1233        GeneralRef { comment, name }
1234    }
1235
1236    fn parse_feature_ref(&mut self, elem: Elem) -> FeatureRef {
1237        let mut name = None;
1238        let mut struc = None;
1239
1240        for attr in elem.start.attributes() {
1241            let attr = attr.unwrap();
1242            match attr.key.as_ref() {
1243                b"name" => self.save_attr(attr, &mut name),
1244                b"struct" => self.save_attr(attr, &mut struc),
1245                _ => panic!("unexpected attr: {attr:?}"),
1246            }
1247        }
1248
1249        assert_eq!(elem.is_empty, true);
1250        FeatureRef { name, struc }
1251    }
1252
1253    fn parse_formats(&mut self, elem: Elem) -> Formats {
1254        for attr in elem.start.attributes() {
1255            let attr = attr.unwrap();
1256            match attr.key.as_ref() {
1257                _ => panic!("unexpected attr: {attr:?}"),
1258            }
1259        }
1260
1261        let mut contents = Vec::new();
1262        self.parse_contents(elem, |this, content| match content {
1263            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1264            Content::Elem(elem) => match elem.start.name().as_ref() {
1265                b"format" => {
1266                    let format = this.parse_format(elem);
1267                    contents.push(FormatsContent::Format(format));
1268                }
1269                _ => {
1270                    panic!("unexpected elem: {elem:?}");
1271                }
1272            },
1273        });
1274
1275        Formats { contents }
1276    }
1277
1278    fn parse_format(&mut self, elem: Elem) -> Format {
1279        let mut block_extent = None;
1280        let mut block_size = None;
1281        let mut chroma = None;
1282        let mut class = None;
1283        let mut compressed = None;
1284        let mut name = None;
1285        let mut packed = None;
1286        let mut texels_per_block = None;
1287
1288        for attr in elem.start.attributes() {
1289            let attr = attr.unwrap();
1290            match attr.key.as_ref() {
1291                b"blockExtent" => self.save_attr(attr, &mut block_extent),
1292                b"blockSize" => self.save_attr(attr, &mut block_size),
1293                b"chroma" => self.save_attr(attr, &mut chroma),
1294                b"class" => self.save_attr(attr, &mut class),
1295                b"compressed" => self.save_attr(attr, &mut compressed),
1296                b"name" => self.save_attr(attr, &mut name),
1297                b"packed" => self.save_attr(attr, &mut packed),
1298                b"texelsPerBlock" => self.save_attr(attr, &mut texels_per_block),
1299                _ => panic!("unexpected attr: {attr:?}"),
1300            }
1301        }
1302
1303        let mut contents = Vec::new();
1304        self.parse_contents(elem, |this, content| match content {
1305            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1306            Content::Elem(elem) => match elem.start.name().as_ref() {
1307                b"component" => {
1308                    let component = this.parse_component(elem);
1309                    contents.push(FormatContent::Component(component));
1310                }
1311                b"plane" => {
1312                    let plane = this.parse_plane(elem);
1313                    contents.push(FormatContent::Plane(plane));
1314                }
1315                b"spirvimageformat" => {
1316                    let format = this.parse_spirv_image_format(elem);
1317                    contents.push(FormatContent::SpirvImageFormat(format));
1318                }
1319                _ => {
1320                    panic!("unexpected elem: {elem:?}");
1321                }
1322            },
1323        });
1324
1325        Format {
1326            block_extent,
1327            block_size,
1328            chroma,
1329            class,
1330            compressed,
1331            name,
1332            packed,
1333            texels_per_block,
1334            contents,
1335        }
1336    }
1337
1338    fn parse_component(&mut self, elem: Elem) -> Component {
1339        let mut bits = None;
1340        let mut name = None;
1341        let mut numeric_format = None;
1342        let mut plane_index = None;
1343
1344        for attr in elem.start.attributes() {
1345            let attr = attr.unwrap();
1346            match attr.key.as_ref() {
1347                b"bits" => self.save_attr(attr, &mut bits),
1348                b"name" => self.save_attr(attr, &mut name),
1349                b"numericFormat" => self.save_attr(attr, &mut numeric_format),
1350                b"planeIndex" => self.save_attr(attr, &mut plane_index),
1351                _ => panic!("unexpected attr: {attr:?}"),
1352            }
1353        }
1354
1355        assert_eq!(elem.is_empty, true);
1356        Component {
1357            bits,
1358            name,
1359            numeric_format,
1360            plane_index,
1361        }
1362    }
1363
1364    fn parse_plane(&mut self, elem: Elem) -> Plane {
1365        let mut compatible = None;
1366        let mut height_divisor = None;
1367        let mut index = None;
1368        let mut width_divisor = None;
1369
1370        for attr in elem.start.attributes() {
1371            let attr = attr.unwrap();
1372            match attr.key.as_ref() {
1373                b"compatible" => self.save_attr(attr, &mut compatible),
1374                b"heightDivisor" => self.save_attr(attr, &mut height_divisor),
1375                b"index" => self.save_attr(attr, &mut index),
1376                b"widthDivisor" => self.save_attr(attr, &mut width_divisor),
1377                _ => panic!("unexpected attr: {attr:?}"),
1378            }
1379        }
1380
1381        assert_eq!(elem.is_empty, true);
1382        Plane {
1383            compatible,
1384            height_divisor,
1385            index,
1386            width_divisor,
1387        }
1388    }
1389
1390    fn parse_spirv_image_format(&mut self, elem: Elem) -> SpirvImageFormat {
1391        let mut name = None;
1392
1393        for attr in elem.start.attributes() {
1394            let attr = attr.unwrap();
1395            match attr.key.as_ref() {
1396                b"name" => self.save_attr(attr, &mut name),
1397                _ => panic!("unexpected attr: {attr:?}"),
1398            }
1399        }
1400
1401        assert_eq!(elem.is_empty, true);
1402        SpirvImageFormat { name }
1403    }
1404
1405    fn parse_spirv_extensions(&mut self, elem: Elem) -> SpirvExtensions {
1406        let mut comment = None;
1407
1408        for attr in elem.start.attributes() {
1409            let attr = attr.unwrap();
1410            match attr.key.as_ref() {
1411                b"comment" => self.save_attr(attr, &mut comment),
1412                _ => panic!("unexpected attr: {attr:?}"),
1413            }
1414        }
1415
1416        let mut contents = Vec::new();
1417        self.parse_contents(elem, |this, content| match content {
1418            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1419            Content::Elem(elem) => match elem.start.name().as_ref() {
1420                b"spirvextension" => {
1421                    let extension = this.parse_spirv_extension(elem);
1422                    contents.push(SpirvExtensionsContent::SpirvExtension(extension));
1423                }
1424                _ => {
1425                    panic!("unexpected elem: {elem:?}");
1426                }
1427            },
1428        });
1429
1430        SpirvExtensions { comment, contents }
1431    }
1432
1433    fn parse_spirv_extension(&mut self, elem: Elem) -> SpirvExtension {
1434        let mut name = None;
1435
1436        for attr in elem.start.attributes() {
1437            let attr = attr.unwrap();
1438            match attr.key.as_ref() {
1439                b"name" => self.save_attr(attr, &mut name),
1440                _ => panic!("unexpected attr: {attr:?}"),
1441            }
1442        }
1443
1444        let mut contents = Vec::new();
1445        self.parse_contents(elem, |this, content| match content {
1446            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1447            Content::Elem(elem) => match elem.start.name().as_ref() {
1448                b"enable" => {
1449                    let enable = this.parse_spirv_extension_enable(elem);
1450                    contents.push(SpirvExtensionContent::Enable(enable));
1451                }
1452                _ => {
1453                    panic!("unexpected elem: {elem:?}");
1454                }
1455            },
1456        });
1457
1458        SpirvExtension { name, contents }
1459    }
1460
1461    fn parse_spirv_extension_enable(&mut self, elem: Elem) -> SpirvExtensionEnable {
1462        let mut extension = None;
1463        let mut version = None;
1464
1465        for attr in elem.start.attributes() {
1466            let attr = attr.unwrap();
1467            match attr.key.as_ref() {
1468                b"extension" => self.save_attr(attr, &mut extension),
1469                b"version" => self.save_attr(attr, &mut version),
1470                _ => panic!("unexpected attr: {attr:?}"),
1471            }
1472        }
1473
1474        assert_eq!(elem.is_empty, true);
1475        SpirvExtensionEnable { extension, version }
1476    }
1477
1478    fn parse_spirv_capabilities(&mut self, elem: Elem) -> SpirvCapabilities {
1479        let mut comment = None;
1480
1481        for attr in elem.start.attributes() {
1482            let attr = attr.unwrap();
1483            match attr.key.as_ref() {
1484                b"comment" => self.save_attr(attr, &mut comment),
1485                _ => panic!("unexpected attr: {attr:?}"),
1486            }
1487        }
1488
1489        let mut contents = Vec::new();
1490        self.parse_contents(elem, |this, content| match content {
1491            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1492            Content::Elem(elem) => match elem.start.name().as_ref() {
1493                b"spirvcapability" => {
1494                    let capability = this.parse_spirv_capability(elem);
1495                    contents.push(SpirvCapabilitiesContent::SpirvCapability(capability));
1496                }
1497                _ => {
1498                    panic!("unexpected elem: {elem:?}");
1499                }
1500            },
1501        });
1502
1503        SpirvCapabilities { comment, contents }
1504    }
1505
1506    fn parse_spirv_capability(&mut self, elem: Elem) -> SpirvCapability {
1507        let mut name = None;
1508
1509        for attr in elem.start.attributes() {
1510            let attr = attr.unwrap();
1511            match attr.key.as_ref() {
1512                b"name" => self.save_attr(attr, &mut name),
1513                _ => panic!("unexpected attr: {attr:?}"),
1514            }
1515        }
1516
1517        let mut contents = Vec::new();
1518        self.parse_contents(elem, |this, content| match content {
1519            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1520            Content::Elem(elem) => match elem.start.name().as_ref() {
1521                b"enable" => {
1522                    let enable = this.parse_spirv_capability_enable(elem);
1523                    contents.push(SpirvCapabilityContent::Enable(enable));
1524                }
1525                _ => {
1526                    panic!("unexpected elem: {elem:?}");
1527                }
1528            },
1529        });
1530
1531        SpirvCapability { name, contents }
1532    }
1533
1534    fn parse_spirv_capability_enable(&mut self, elem: Elem) -> SpirvCapabilityEnable {
1535        let mut alias = None;
1536        let mut extension = None;
1537        let mut feature = None;
1538        let mut member = None;
1539        let mut property = None;
1540        let mut requires = None;
1541        let mut struc = None;
1542        let mut value = None;
1543        let mut version = None;
1544
1545        for attr in elem.start.attributes() {
1546            let attr = attr.unwrap();
1547            match attr.key.as_ref() {
1548                b"alias" => self.save_attr(attr, &mut alias),
1549                b"extension" => self.save_attr(attr, &mut extension),
1550                b"feature" => self.save_attr(attr, &mut feature),
1551                b"member" => self.save_attr(attr, &mut member),
1552                b"property" => self.save_attr(attr, &mut property),
1553                b"requires" => self.save_attr(attr, &mut requires),
1554                b"struct" => self.save_attr(attr, &mut struc),
1555                b"value" => self.save_attr(attr, &mut value),
1556                b"version" => self.save_attr(attr, &mut version),
1557                _ => panic!("unexpected attr: {attr:?}"),
1558            }
1559        }
1560
1561        assert_eq!(elem.is_empty, true);
1562        SpirvCapabilityEnable {
1563            alias,
1564            extension,
1565            feature,
1566            member,
1567            property,
1568            requires,
1569            struc,
1570            value,
1571            version,
1572        }
1573    }
1574
1575    fn parse_syncs(&mut self, elem: Elem) -> Syncs {
1576        let mut comment = None;
1577
1578        for attr in elem.start.attributes() {
1579            let attr = attr.unwrap();
1580            match attr.key.as_ref() {
1581                b"comment" => self.save_attr(attr, &mut comment),
1582                _ => panic!("unexpected attr: {attr:?}"),
1583            }
1584        }
1585
1586        let mut contents = Vec::new();
1587        self.parse_contents(elem, |this, content| match content {
1588            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1589            Content::Elem(elem) => match elem.start.name().as_ref() {
1590                b"syncstage" => {
1591                    let stage = this.parse_sync_stage(elem);
1592                    contents.push(SyncsContent::SyncStage(stage));
1593                }
1594                b"syncaccess" => {
1595                    let access = this.parse_sync_access(elem);
1596                    contents.push(SyncsContent::SyncAccess(access));
1597                }
1598                b"syncpipeline" => {
1599                    let pipeline = this.parse_sync_pipeline(elem);
1600                    contents.push(SyncsContent::SyncPipeline(pipeline));
1601                }
1602                _ => {
1603                    panic!("unexpected elem: {elem:?}");
1604                }
1605            },
1606        });
1607
1608        Syncs { comment, contents }
1609    }
1610
1611    fn parse_sync_stage(&mut self, elem: Elem) -> SyncStage {
1612        let mut alias = None;
1613        let mut name = None;
1614
1615        for attr in elem.start.attributes() {
1616            let attr = attr.unwrap();
1617            match attr.key.as_ref() {
1618                b"alias" => self.save_attr(attr, &mut alias),
1619                b"name" => self.save_attr(attr, &mut name),
1620                _ => panic!("unexpected attr: {attr:?}"),
1621            }
1622        }
1623
1624        let mut contents = Vec::new();
1625        self.parse_contents(elem, |this, content| match content {
1626            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1627            Content::Elem(elem) => match elem.start.name().as_ref() {
1628                b"syncsupport" => {
1629                    let support = this.parse_sync_stage_support(elem);
1630                    contents.push(SyncStageContent::SyncSupport(support));
1631                }
1632                b"syncequivalent" => {
1633                    let equivalent = this.parse_sync_stage_equivalent(elem);
1634                    contents.push(SyncStageContent::SyncEquivalent(equivalent));
1635                }
1636                _ => {
1637                    panic!("unexpected elem: {elem:?}");
1638                }
1639            },
1640        });
1641
1642        SyncStage {
1643            alias,
1644            name,
1645            contents,
1646        }
1647    }
1648
1649    fn parse_sync_stage_support(&mut self, elem: Elem) -> SyncStageSupport {
1650        let mut queues = None;
1651
1652        for attr in elem.start.attributes() {
1653            let attr = attr.unwrap();
1654            match attr.key.as_ref() {
1655                b"queues" => self.save_attr(attr, &mut queues),
1656                _ => panic!("unexpected attr: {attr:?}"),
1657            }
1658        }
1659
1660        assert_eq!(elem.is_empty, true);
1661        SyncStageSupport { queues }
1662    }
1663
1664    fn parse_sync_stage_equivalent(&mut self, elem: Elem) -> SyncStageEquivalent {
1665        let mut stage = None;
1666
1667        for attr in elem.start.attributes() {
1668            let attr = attr.unwrap();
1669            match attr.key.as_ref() {
1670                b"stage" => self.save_attr(attr, &mut stage),
1671                _ => panic!("unexpected attr: {attr:?}"),
1672            }
1673        }
1674
1675        assert_eq!(elem.is_empty, true);
1676        SyncStageEquivalent { stage }
1677    }
1678
1679    fn parse_sync_access(&mut self, elem: Elem) -> SyncAccess {
1680        let mut alias = None;
1681        let mut name = None;
1682
1683        for attr in elem.start.attributes() {
1684            let attr = attr.unwrap();
1685            match attr.key.as_ref() {
1686                b"alias" => self.save_attr(attr, &mut alias),
1687                b"name" => self.save_attr(attr, &mut name),
1688                _ => panic!("unexpected attr: {attr:?}"),
1689            }
1690        }
1691
1692        let mut contents = Vec::new();
1693        self.parse_contents(elem, |this, content| match content {
1694            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1695            Content::Elem(elem) => match elem.start.name().as_ref() {
1696                b"comment" => {
1697                    let comment = this.parse_text_elem(elem);
1698                    contents.push(SyncAccessContent::Comment(comment));
1699                }
1700                b"syncsupport" => {
1701                    let support = this.parse_sync_access_support(elem);
1702                    contents.push(SyncAccessContent::SyncSupport(support));
1703                }
1704                b"syncequivalent" => {
1705                    let equivalent = this.parse_sync_access_equivalent(elem);
1706                    contents.push(SyncAccessContent::SyncEquivalent(equivalent));
1707                }
1708                _ => {
1709                    panic!("unexpected elem: {elem:?}");
1710                }
1711            },
1712        });
1713
1714        SyncAccess {
1715            alias,
1716            name,
1717            contents,
1718        }
1719    }
1720
1721    fn parse_sync_access_support(&mut self, elem: Elem) -> SyncAccessSupport {
1722        let mut stage = None;
1723
1724        for attr in elem.start.attributes() {
1725            let attr = attr.unwrap();
1726            match attr.key.as_ref() {
1727                b"stage" => self.save_attr(attr, &mut stage),
1728                _ => panic!("unexpected attr: {attr:?}"),
1729            }
1730        }
1731
1732        assert_eq!(elem.is_empty, true);
1733        SyncAccessSupport { stage }
1734    }
1735
1736    fn parse_sync_access_equivalent(&mut self, elem: Elem) -> SyncAccessEquivalent {
1737        let mut access = None;
1738
1739        for attr in elem.start.attributes() {
1740            let attr = attr.unwrap();
1741            match attr.key.as_ref() {
1742                b"access" => self.save_attr(attr, &mut access),
1743                _ => panic!("unexpected attr: {attr:?}"),
1744            }
1745        }
1746
1747        assert_eq!(elem.is_empty, true);
1748        SyncAccessEquivalent { access }
1749    }
1750
1751    fn parse_sync_pipeline(&mut self, elem: Elem) -> SyncPipeline {
1752        let mut depends = None;
1753        let mut name = None;
1754
1755        for attr in elem.start.attributes() {
1756            let attr = attr.unwrap();
1757            match attr.key.as_ref() {
1758                b"depends" => self.save_attr(attr, &mut depends),
1759                b"name" => self.save_attr(attr, &mut name),
1760                _ => panic!("unexpected attr: {attr:?}"),
1761            }
1762        }
1763
1764        let mut contents = Vec::new();
1765        self.parse_contents(elem, |this, content| match content {
1766            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1767            Content::Elem(elem) => match elem.start.name().as_ref() {
1768                b"syncpipelinestage" => {
1769                    let stage = this.parse_sync_pipeline_stage(elem);
1770                    contents.push(SyncPipelineContent::SyncPipelineStage(stage));
1771                }
1772                _ => {
1773                    panic!("unexpected elem: {elem:?}");
1774                }
1775            },
1776        });
1777
1778        SyncPipeline {
1779            depends,
1780            name,
1781            contents,
1782        }
1783    }
1784
1785    fn parse_sync_pipeline_stage(&mut self, elem: Elem) -> SyncPipelineStage {
1786        let mut before = None;
1787        let mut order = None;
1788
1789        for attr in elem.start.attributes() {
1790            let attr = attr.unwrap();
1791            match attr.key.as_ref() {
1792                b"before" => self.save_attr(attr, &mut before),
1793                b"order" => self.save_attr(attr, &mut order),
1794                _ => panic!("unexpected attr: {attr:?}"),
1795            }
1796        }
1797
1798        let mut contents = String::new();
1799        self.parse_contents(elem, |_this, content| match content {
1800            Content::Text(text) => contents += text,
1801            Content::Elem(elem) => panic!("unexpected elem: {elem:?}"),
1802        });
1803
1804        SyncPipelineStage {
1805            before,
1806            order,
1807            contents,
1808        }
1809    }
1810
1811    fn parse_video_codecs(&mut self, elem: Elem) -> VideoCodecs {
1812        for attr in elem.start.attributes() {
1813            let attr = attr.unwrap();
1814            match attr.key.as_ref() {
1815                _ => panic!("unexpected attr: {attr:?}"),
1816            }
1817        }
1818
1819        let mut contents = Vec::new();
1820        self.parse_contents(elem, |this, content| match content {
1821            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1822            Content::Elem(elem) => match elem.start.name().as_ref() {
1823                b"videocodec" => {
1824                    let codec = this.parse_video_codec(elem);
1825                    contents.push(VideoCodecsContent::VideoCodec(codec));
1826                }
1827                _ => {
1828                    panic!("unexpected elem: {elem:?}");
1829                }
1830            },
1831        });
1832
1833        VideoCodecs { contents }
1834    }
1835
1836    fn parse_video_codec(&mut self, elem: Elem) -> VideoCodec {
1837        let mut extend = None;
1838        let mut name = None;
1839        let mut value = None;
1840
1841        for attr in elem.start.attributes() {
1842            let attr = attr.unwrap();
1843            match attr.key.as_ref() {
1844                b"extend" => self.save_attr(attr, &mut extend),
1845                b"name" => self.save_attr(attr, &mut name),
1846                b"value" => self.save_attr(attr, &mut value),
1847                _ => panic!("unexpected attr: {attr:?}"),
1848            }
1849        }
1850
1851        let mut contents = Vec::new();
1852        self.parse_contents(elem, |this, content| match content {
1853            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1854            Content::Elem(elem) => match elem.start.name().as_ref() {
1855                b"videocapabilities" => {
1856                    let capabilities = this.parse_video_capabilities(elem);
1857                    contents.push(VideoCodecContent::VideoCapabilities(capabilities));
1858                }
1859                b"videoformat" => {
1860                    let format = this.parse_video_format(elem);
1861                    contents.push(VideoCodecContent::VideoFormat(format));
1862                }
1863                b"videoprofiles" => {
1864                    let profiles = this.parse_video_profiles(elem);
1865                    contents.push(VideoCodecContent::VideoProfiles(profiles));
1866                }
1867                _ => {
1868                    panic!("unexpected elem: {elem:?}");
1869                }
1870            },
1871        });
1872
1873        VideoCodec {
1874            extend,
1875            name,
1876            value,
1877            contents,
1878        }
1879    }
1880
1881    fn parse_video_capabilities(&mut self, elem: Elem) -> VideoCapabilities {
1882        let mut struc = None;
1883
1884        for attr in elem.start.attributes() {
1885            let attr = attr.unwrap();
1886            match attr.key.as_ref() {
1887                b"struct" => self.save_attr(attr, &mut struc),
1888                _ => panic!("unexpected attr: {attr:?}"),
1889            }
1890        }
1891
1892        assert_eq!(elem.is_empty, true);
1893        VideoCapabilities { struc }
1894    }
1895
1896    fn parse_video_format(&mut self, elem: Elem) -> VideoFormat {
1897        let mut extend = None;
1898        let mut name = None;
1899        let mut usage = None;
1900
1901        for attr in elem.start.attributes() {
1902            let attr = attr.unwrap();
1903            match attr.key.as_ref() {
1904                b"extend" => self.save_attr(attr, &mut extend),
1905                b"name" => self.save_attr(attr, &mut name),
1906                b"usage" => self.save_attr(attr, &mut usage),
1907                _ => panic!("unexpected attr: {attr:?}"),
1908            }
1909        }
1910
1911        let mut contents = Vec::new();
1912        self.parse_contents(elem, |this, content| match content {
1913            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1914            Content::Elem(elem) => match elem.start.name().as_ref() {
1915                b"videorequirecapabilities" => {
1916                    let capabilities = this.parse_video_require_capabilities(elem);
1917                    contents.push(VideoFormatContent::VideoRequireCapabilities(capabilities));
1918                }
1919                b"videoformatproperties" => {
1920                    let properties = this.parse_video_format_properties(elem);
1921                    contents.push(VideoFormatContent::VideoFormatProperties(properties));
1922                }
1923                _ => {
1924                    panic!("unexpected elem: {elem:?}");
1925                }
1926            },
1927        });
1928
1929        VideoFormat {
1930            extend,
1931            name,
1932            usage,
1933            contents,
1934        }
1935    }
1936
1937    fn parse_video_require_capabilities(&mut self, elem: Elem) -> VideoRequireCapabilities {
1938        let mut member = None;
1939        let mut struc = None;
1940        let mut value = None;
1941
1942        for attr in elem.start.attributes() {
1943            let attr = attr.unwrap();
1944            match attr.key.as_ref() {
1945                b"member" => self.save_attr(attr, &mut member),
1946                b"struct" => self.save_attr(attr, &mut struc),
1947                b"value" => self.save_attr(attr, &mut value),
1948                _ => panic!("unexpected attr: {attr:?}"),
1949            }
1950        }
1951
1952        assert_eq!(elem.is_empty, true);
1953        VideoRequireCapabilities {
1954            member,
1955            struc,
1956            value,
1957        }
1958    }
1959
1960    fn parse_video_format_properties(&mut self, elem: Elem) -> VideoFormatProperties {
1961        let mut struc = None;
1962
1963        for attr in elem.start.attributes() {
1964            let attr = attr.unwrap();
1965            match attr.key.as_ref() {
1966                b"struct" => self.save_attr(attr, &mut struc),
1967                _ => panic!("unexpected attr: {attr:?}"),
1968            }
1969        }
1970
1971        assert_eq!(elem.is_empty, true);
1972        VideoFormatProperties { struc }
1973    }
1974
1975    fn parse_video_profiles(&mut self, elem: Elem) -> VideoProfiles {
1976        let mut struc = None;
1977
1978        for attr in elem.start.attributes() {
1979            let attr = attr.unwrap();
1980            match attr.key.as_ref() {
1981                b"struct" => self.save_attr(attr, &mut struc),
1982                _ => panic!("unexpected attr: {attr:?}"),
1983            }
1984        }
1985
1986        let mut contents = Vec::new();
1987        self.parse_contents(elem, |this, content| match content {
1988            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
1989            Content::Elem(elem) => match elem.start.name().as_ref() {
1990                b"videoprofilemember" => {
1991                    let member = this.parse_video_profile_member(elem);
1992                    contents.push(VideoProfilesContent::VideoProfileMember(member));
1993                }
1994                _ => {
1995                    panic!("unexpected elem: {elem:?}");
1996                }
1997            },
1998        });
1999
2000        VideoProfiles { struc, contents }
2001    }
2002
2003    fn parse_video_profile_member(&mut self, elem: Elem) -> VideoProfileMember {
2004        let mut name = None;
2005
2006        for attr in elem.start.attributes() {
2007            let attr = attr.unwrap();
2008            match attr.key.as_ref() {
2009                b"name" => self.save_attr(attr, &mut name),
2010                _ => panic!("unexpected attr: {attr:?}"),
2011            }
2012        }
2013
2014        let mut contents = Vec::new();
2015        self.parse_contents(elem, |this, content| match content {
2016            Content::Text(text) => this.assert_is_ws(text.as_bytes()),
2017            Content::Elem(elem) => match elem.start.name().as_ref() {
2018                b"videoprofile" => {
2019                    let profile = this.parse_video_profile(elem);
2020                    contents.push(VideoProfileMemberContent::VideoProfile(profile));
2021                }
2022                _ => {
2023                    panic!("unexpected elem: {elem:?}");
2024                }
2025            },
2026        });
2027
2028        VideoProfileMember { name, contents }
2029    }
2030
2031    fn parse_video_profile(&mut self, elem: Elem) -> VideoProfile {
2032        let mut name = None;
2033        let mut value = None;
2034
2035        for attr in elem.start.attributes() {
2036            let attr = attr.unwrap();
2037            match attr.key.as_ref() {
2038                b"name" => self.save_attr(attr, &mut name),
2039                b"value" => self.save_attr(attr, &mut value),
2040                _ => panic!("unexpected attr: {attr:?}"),
2041            }
2042        }
2043
2044        assert_eq!(elem.is_empty, true);
2045        VideoProfile { name, value }
2046    }
2047}