flams_stex/quickparse/stex/
mod.rs

1pub mod rules;
2pub mod structs;
3
4use flams_math_archives::backend::AnyBackend;
5use flams_utils::{
6    parsing::ParseStr,
7    prelude::{TreeChild, TreeLike},
8    sourcerefs::{LSPLineCol, SourceRange},
9    vecmap::VecSet,
10};
11use ftml_ontology::narrative::elements::{paragraphs::ParagraphKind, problems::CognitiveDimension};
12use ftml_uris::{ArchiveId, DocumentUri, Language, ModuleUri, SymbolUri, UriName, UriWithArchive};
13use rules::{
14    MathStructureArg, MathStructureArgIter, NotationArg, NotationArgIter, ParagraphArg,
15    ParagraphArgIter, ProblemArg, ProblemArgIter, SModuleArg, SModuleArgIter, SymdeclArg,
16    SymdeclArgIter, SymdefArg, SymdefArgIter, TextSymdeclArg, TextSymdeclArgIter, VardefArg,
17    VardefArgIter,
18};
19use smallvec::SmallVec;
20use std::path::Path;
21use structs::{
22    InlineMorphAssIter, InlineMorphAssign, ModuleOrStruct, ModuleReference, ModuleRules,
23    MorphismKind, STeXModuleStore, STeXParseState, STeXToken, SymbolReference, SymnameMode,
24};
25
26use crate::quickparse::stex::rules::{IncludeProblemArg, MHGraphicsArg};
27
28use super::latex::LaTeXParser;
29
30#[derive(Default, Debug)]
31pub struct STeXParseDataI {
32    pub annotations: Vec<STeXAnnot>,
33    pub diagnostics: VecSet<STeXDiagnostic>,
34    pub modules: SmallVec<(ModuleUri, ModuleRules<LSPLineCol>), 1>,
35    pub dependencies: Vec<std::sync::Arc<Path>>,
36}
37impl STeXParseDataI {
38    #[inline]
39    #[must_use]
40    pub fn lock(self) -> STeXParseData {
41        flams_utils::triomphe::Arc::new(parking_lot::Mutex::new(self))
42    }
43    #[inline]
44    pub fn replace(self, old: &STeXParseData) {
45        *old.lock() = self;
46    }
47    #[inline]
48    #[must_use]
49    pub const fn is_empty(&self) -> bool {
50        self.annotations.is_empty() && self.diagnostics.is_empty()
51    }
52}
53
54pub type STeXParseData = flams_utils::triomphe::Arc<parking_lot::Mutex<STeXParseDataI>>;
55
56#[allow(clippy::large_enum_variant)]
57#[derive(Debug, Clone, serde::Serialize)]
58pub enum STeXAnnot {
59    Module {
60        uri: ModuleUri,
61        name_range: SourceRange<LSPLineCol>,
62        opts: Vec<SModuleArg<LSPLineCol, Self>>,
63        sig: Option<Language>,
64        meta_theory: Option<ModuleReference>,
65        full_range: SourceRange<LSPLineCol>,
66        smodule_range: SourceRange<LSPLineCol>,
67        children: Vec<Self>,
68    },
69    MathStructure {
70        uri: SymbolReference<LSPLineCol>,
71        extends: Vec<(SymbolReference<LSPLineCol>, SourceRange<LSPLineCol>)>,
72        name_range: SourceRange<LSPLineCol>,
73        opts: Vec<MathStructureArg<LSPLineCol, Self>>,
74        full_range: SourceRange<LSPLineCol>,
75        children: Vec<Self>,
76        mathstructure_range: SourceRange<LSPLineCol>,
77    },
78    ConservativeExt {
79        uri: SymbolReference<LSPLineCol>,
80        ext_range: SourceRange<LSPLineCol>,
81        full_range: SourceRange<LSPLineCol>,
82        extstructure_range: SourceRange<LSPLineCol>,
83        children: Vec<Self>,
84    },
85    MorphismEnv {
86        full_range: SourceRange<LSPLineCol>,
87        name_range: SourceRange<LSPLineCol>,
88        env_range: SourceRange<LSPLineCol>,
89        uri: SymbolUri,
90        star: bool,
91        domain: ModuleOrStruct<LSPLineCol>,
92        domain_range: SourceRange<LSPLineCol>,
93        kind: MorphismKind,
94        children: Vec<Self>,
95    },
96    InlineMorphism {
97        full_range: SourceRange<LSPLineCol>,
98        token_range: SourceRange<LSPLineCol>,
99        name_range: SourceRange<LSPLineCol>,
100        uri: SymbolUri,
101        domain: ModuleOrStruct<LSPLineCol>,
102        domain_range: SourceRange<LSPLineCol>,
103        kind: MorphismKind,
104        assignments: Vec<InlineMorphAssign<LSPLineCol, Self>>,
105    },
106    SemanticMacro {
107        uri: SymbolReference<LSPLineCol>,
108        argnum: u8,
109        token_range: SourceRange<LSPLineCol>,
110        full_range: SourceRange<LSPLineCol>,
111    },
112    VariableMacro {
113        name: UriName,
114        argnum: u8,
115        orig: SourceRange<LSPLineCol>,
116        sequence: bool,
117        token_range: SourceRange<LSPLineCol>,
118        full_range: SourceRange<LSPLineCol>,
119    },
120    Svar {
121        name: UriName,
122        token_range: SourceRange<LSPLineCol>,
123        full_range: SourceRange<LSPLineCol>,
124        arg_range: SourceRange<LSPLineCol>,
125        name_range: Option<SourceRange<LSPLineCol>>,
126    },
127    ImportModule {
128        archive_range: Option<SourceRange<LSPLineCol>>,
129        path_range: SourceRange<LSPLineCol>,
130        module: ModuleReference,
131        token_range: SourceRange<LSPLineCol>,
132        full_range: SourceRange<LSPLineCol>,
133    },
134    UseModule {
135        archive_range: Option<SourceRange<LSPLineCol>>,
136        path_range: SourceRange<LSPLineCol>,
137        module: ModuleReference,
138        token_range: SourceRange<LSPLineCol>,
139        full_range: SourceRange<LSPLineCol>,
140    },
141    UseStructure {
142        structure: SymbolReference<LSPLineCol>,
143        structure_range: SourceRange<LSPLineCol>,
144        token_range: SourceRange<LSPLineCol>,
145        full_range: SourceRange<LSPLineCol>,
146    },
147    SetMetatheory {
148        archive_range: Option<SourceRange<LSPLineCol>>,
149        path_range: SourceRange<LSPLineCol>,
150        module: ModuleReference,
151        token_range: SourceRange<LSPLineCol>,
152        full_range: SourceRange<LSPLineCol>,
153    },
154    Inputref {
155        archive: Option<(ArchiveId, SourceRange<LSPLineCol>)>,
156        filepath: (std::sync::Arc<str>, SourceRange<LSPLineCol>),
157        token_range: SourceRange<LSPLineCol>,
158        full_range: SourceRange<LSPLineCol>,
159    },
160    MHInput {
161        archive: Option<(ArchiveId, SourceRange<LSPLineCol>)>,
162        filepath: (std::sync::Arc<str>, SourceRange<LSPLineCol>),
163        token_range: SourceRange<LSPLineCol>,
164        full_range: SourceRange<LSPLineCol>,
165    },
166    #[allow(clippy::type_complexity)]
167    Symdecl {
168        uri: SymbolReference<LSPLineCol>,
169        main_name_range: SourceRange<LSPLineCol>,
170        parsed_args: Vec<SymdeclArg<LSPLineCol, Self>>,
171        token_range: SourceRange<LSPLineCol>,
172        full_range: SourceRange<LSPLineCol>,
173    },
174    #[allow(clippy::type_complexity)]
175    TextSymdecl {
176        uri: SymbolReference<LSPLineCol>,
177        main_name_range: SourceRange<LSPLineCol>,
178        parsed_args: Vec<TextSymdeclArg<LSPLineCol, Self>>,
179        token_range: SourceRange<LSPLineCol>,
180        full_range: SourceRange<LSPLineCol>,
181    },
182    Notation {
183        uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
184        token_range: SourceRange<LSPLineCol>,
185        name_range: SourceRange<LSPLineCol>,
186        notation_args: Vec<NotationArg<LSPLineCol, Self>>,
187        full_range: SourceRange<LSPLineCol>,
188    },
189    RenameDecl {
190        uri: SymbolReference<LSPLineCol>,
191        token_range: SourceRange<LSPLineCol>,
192        orig_range: SourceRange<LSPLineCol>,
193        name_range: Option<SourceRange<LSPLineCol>>,
194        macroname_range: SourceRange<LSPLineCol>,
195        full_range: SourceRange<LSPLineCol>,
196    },
197    Assign {
198        uri: SymbolReference<LSPLineCol>,
199        token_range: SourceRange<LSPLineCol>,
200        orig_range: SourceRange<LSPLineCol>,
201        full_range: SourceRange<LSPLineCol>,
202    },
203    #[allow(clippy::type_complexity)]
204    Symdef {
205        uri: SymbolReference<LSPLineCol>,
206        main_name_range: SourceRange<LSPLineCol>,
207        parsed_args: Vec<SymdefArg<LSPLineCol, Self>>,
208        token_range: SourceRange<LSPLineCol>,
209        full_range: SourceRange<LSPLineCol>,
210    },
211    #[allow(clippy::type_complexity)]
212    Vardef {
213        name: UriName,
214        main_name_range: SourceRange<LSPLineCol>,
215        parsed_args: Vec<VardefArg<LSPLineCol, Self>>,
216        token_range: SourceRange<LSPLineCol>,
217        full_range: SourceRange<LSPLineCol>,
218    },
219    #[allow(clippy::type_complexity)]
220    Varseq {
221        name: UriName,
222        main_name_range: SourceRange<LSPLineCol>,
223        parsed_args: Vec<VardefArg<LSPLineCol, Self>>,
224        token_range: SourceRange<LSPLineCol>,
225        full_range: SourceRange<LSPLineCol>,
226    },
227    SymName {
228        uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
229        full_range: SourceRange<LSPLineCol>,
230        token_range: SourceRange<LSPLineCol>,
231        name_range: SourceRange<LSPLineCol>,
232        mode: SymnameMode<LSPLineCol>,
233    },
234    IncludeProblem {
235        filepath: (std::sync::Arc<str>, SourceRange<LSPLineCol>),
236        archive: Option<(ArchiveId, SourceRange<LSPLineCol>)>,
237        full_range: SourceRange<LSPLineCol>,
238        token_range: SourceRange<LSPLineCol>,
239        args: Vec<IncludeProblemArg<LSPLineCol>>,
240    },
241    Symuse {
242        uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
243        full_range: SourceRange<LSPLineCol>,
244        token_range: SourceRange<LSPLineCol>,
245        name_range: SourceRange<LSPLineCol>,
246    },
247    Symref {
248        uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
249        full_range: SourceRange<LSPLineCol>,
250        token_range: SourceRange<LSPLineCol>,
251        name_range: SourceRange<LSPLineCol>,
252        text: (SourceRange<LSPLineCol>, Vec<Self>),
253    },
254    Definiens {
255        uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
256        full_range: SourceRange<LSPLineCol>,
257        token_range: SourceRange<LSPLineCol>,
258        name_range: Option<SourceRange<LSPLineCol>>,
259    },
260    Defnotation {
261        full_range: SourceRange<LSPLineCol>,
262    },
263    Paragraph {
264        kind: ParagraphKind,
265        full_range: SourceRange<LSPLineCol>,
266        name_range: SourceRange<LSPLineCol>,
267        symbol: Option<SymbolReference<LSPLineCol>>,
268        parsed_args: Vec<ParagraphArg<LSPLineCol, Self>>,
269        children: Vec<Self>,
270    },
271    Problem {
272        sub: bool,
273        full_range: SourceRange<LSPLineCol>,
274        name_range: SourceRange<LSPLineCol>,
275        parsed_args: Vec<ProblemArg<LSPLineCol, Self>>,
276        children: Vec<Self>,
277    },
278    Precondition {
279        uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
280        full_range: SourceRange<LSPLineCol>,
281        token_range: SourceRange<LSPLineCol>,
282        dim_range: SourceRange<LSPLineCol>,
283        symbol_range: SourceRange<LSPLineCol>,
284        dim: CognitiveDimension,
285    },
286    Objective {
287        uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
288        full_range: SourceRange<LSPLineCol>,
289        token_range: SourceRange<LSPLineCol>,
290        dim_range: SourceRange<LSPLineCol>,
291        symbol_range: SourceRange<LSPLineCol>,
292        dim: CognitiveDimension,
293    },
294    InlineParagraph {
295        kind: ParagraphKind,
296        full_range: SourceRange<LSPLineCol>,
297        token_range: SourceRange<LSPLineCol>,
298        symbol: Option<SymbolReference<LSPLineCol>>,
299        parsed_args: Vec<ParagraphArg<LSPLineCol, Self>>,
300        children: Vec<Self>,
301        children_range: SourceRange<LSPLineCol>,
302    },
303    MHGraphics {
304        filepath: (std::sync::Arc<str>, SourceRange<LSPLineCol>),
305        archive: Option<(ArchiveId, SourceRange<LSPLineCol>)>,
306        full_range: SourceRange<LSPLineCol>,
307        token_range: SourceRange<LSPLineCol>,
308        args: Vec<MHGraphicsArg<LSPLineCol>>,
309    },
310}
311impl STeXAnnot {
312    #[allow(clippy::too_many_lines)]
313    fn from_tokens<I: IntoIterator<Item = STeXToken<LSPLineCol>>>(
314        iter: I,
315        mut modules: Option<&mut SmallVec<(ModuleUri, ModuleRules<LSPLineCol>), 1>>,
316    ) -> Vec<Self> {
317        let mut v = Vec::new();
318        macro_rules! cont {
319      ($e:ident) => { $e.into_iter().map(|o| o.into_other(cont!(+))).collect() };
320      (+) => { |v| Self::from_tokens(v,if let Some(m) = modules.as_mut() { Some(*m) } else { None }) };
321    }
322        for t in iter {
323            match t {
324                STeXToken::Module {
325                    uri,
326                    name_range,
327                    sig,
328                    meta_theory,
329                    full_range,
330                    smodule_range,
331                    children,
332                    rules,
333                    opts,
334                } => {
335                    if let Some(ref mut m) = modules {
336                        m.push((uri.clone(), rules));
337                    }
338                    v.push(Self::Module {
339                        uri,
340                        name_range,
341                        sig,
342                        meta_theory,
343                        full_range,
344                        smodule_range,
345                        opts: cont!(opts),
346                        children: Self::from_tokens(children, None),
347                    });
348                }
349                STeXToken::MHGraphics {
350                    filepath,
351                    archive,
352                    full_range,
353                    token_range,
354                    args,
355                } => v.push(Self::MHGraphics {
356                    filepath,
357                    archive,
358                    full_range,
359                    token_range,
360                    args,
361                }),
362                STeXToken::UseStructure {
363                    structure,
364                    structure_range,
365                    full_range,
366                    token_range,
367                } => v.push(Self::UseStructure {
368                    structure,
369                    structure_range,
370                    full_range,
371                    token_range,
372                }),
373                STeXToken::ConservativeExt {
374                    uri,
375                    ext_range,
376                    full_range,
377                    children,
378                    extstructure_range,
379                } => v.push(Self::ConservativeExt {
380                    uri,
381                    ext_range,
382                    full_range,
383                    children: Self::from_tokens(children, None),
384                    extstructure_range,
385                }),
386                STeXToken::MathStructure {
387                    uri,
388                    extends,
389                    name_range,
390                    opts,
391                    full_range,
392                    children,
393                    mathstructure_range,
394                    ..
395                } => {
396                    v.push(Self::MathStructure {
397                        uri,
398                        extends,
399                        name_range,
400                        opts: cont!(opts),
401                        full_range,
402                        children: Self::from_tokens(children, None),
403                        mathstructure_range,
404                    });
405                }
406                STeXToken::MorphismEnv {
407                    uri,
408                    star,
409                    env_range,
410                    full_range,
411                    children,
412                    name_range,
413                    domain,
414                    domain_range,
415                    kind,
416                    ..
417                } => v.push(Self::MorphismEnv {
418                    uri,
419                    env_range,
420                    star,
421                    full_range,
422                    children: Self::from_tokens(children, None),
423                    name_range,
424                    domain,
425                    domain_range,
426                    kind,
427                }),
428                STeXToken::InlineMorphism {
429                    full_range,
430                    token_range,
431                    name_range,
432                    uri,
433                    domain,
434                    domain_range,
435                    kind,
436                    assignments,
437                    ..
438                } => v.push(Self::InlineMorphism {
439                    full_range,
440                    token_range,
441                    name_range,
442                    uri,
443                    domain,
444                    domain_range,
445                    kind,
446                    assignments: cont!(assignments),
447                }),
448                STeXToken::SemanticMacro {
449                    uri,
450                    argnum,
451                    token_range,
452                    full_range,
453                } => v.push(Self::SemanticMacro {
454                    uri,
455                    argnum,
456                    token_range,
457                    full_range,
458                }),
459                STeXToken::VariableMacro {
460                    name,
461                    sequence,
462                    argnum,
463                    orig,
464                    token_range,
465                    full_range,
466                } => v.push(Self::VariableMacro {
467                    name,
468                    argnum,
469                    sequence,
470                    orig,
471                    token_range,
472                    full_range,
473                }),
474                STeXToken::Svar {
475                    name,
476                    full_range,
477                    token_range,
478                    name_range,
479                    arg_range,
480                } => v.push(Self::Svar {
481                    name,
482                    full_range,
483                    token_range,
484                    name_range,
485                    arg_range,
486                }),
487                STeXToken::ImportModule {
488                    archive_range,
489                    path_range,
490                    module,
491                    token_range,
492                    full_range,
493                } => v.push(Self::ImportModule {
494                    archive_range,
495                    path_range,
496                    module,
497                    token_range,
498                    full_range,
499                }),
500                STeXToken::UseModule {
501                    archive_range,
502                    path_range,
503                    module,
504                    token_range,
505                    full_range,
506                } => v.push(Self::UseModule {
507                    archive_range,
508                    path_range,
509                    module,
510                    token_range,
511                    full_range,
512                }),
513                STeXToken::IncludeProblem {
514                    filepath,
515                    full_range,
516                    token_range,
517                    archive,
518                    args,
519                } => v.push(Self::IncludeProblem {
520                    filepath,
521                    archive,
522                    full_range,
523                    token_range,
524                    args,
525                }),
526                STeXToken::SetMetatheory {
527                    archive_range,
528                    path_range,
529                    module,
530                    token_range,
531                    full_range,
532                } => v.push(Self::SetMetatheory {
533                    archive_range,
534                    path_range,
535                    module,
536                    token_range,
537                    full_range,
538                }),
539                STeXToken::Inputref {
540                    archive,
541                    filepath,
542                    token_range,
543                    full_range,
544                } => v.push(Self::Inputref {
545                    archive,
546                    filepath,
547                    token_range,
548                    full_range,
549                }),
550                STeXToken::MHInput {
551                    archive,
552                    filepath,
553                    token_range,
554                    full_range,
555                } => v.push(Self::MHInput {
556                    archive,
557                    filepath,
558                    token_range,
559                    full_range,
560                }),
561                STeXToken::Symdecl {
562                    uri,
563                    main_name_range,
564                    token_range,
565                    full_range,
566                    parsed_args,
567                } => v.push(Self::Symdecl {
568                    uri,
569                    main_name_range,
570                    token_range,
571                    full_range,
572                    parsed_args: cont!(parsed_args),
573                }),
574                STeXToken::TextSymdecl {
575                    uri,
576                    main_name_range,
577                    full_range,
578                    parsed_args,
579                    token_range,
580                } => v.push(Self::TextSymdecl {
581                    uri,
582                    main_name_range,
583                    full_range,
584                    token_range,
585                    parsed_args: cont!(parsed_args),
586                }),
587                STeXToken::Definiens {
588                    uri,
589                    full_range,
590                    token_range,
591                    name_range,
592                } => v.push(Self::Definiens {
593                    uri,
594                    full_range,
595                    token_range,
596                    name_range,
597                }),
598                STeXToken::Defnotation { full_range } => {
599                    v.push(Self::Defnotation { full_range });
600                }
601                STeXToken::Notation {
602                    uri,
603                    token_range,
604                    name_range,
605                    notation_args,
606                    full_range,
607                } => v.push(Self::Notation {
608                    uri,
609                    token_range,
610                    name_range,
611                    full_range,
612                    notation_args: cont!(notation_args),
613                }),
614                STeXToken::Symdef {
615                    uri,
616                    main_name_range,
617                    token_range,
618                    full_range,
619                    parsed_args,
620                } => v.push(Self::Symdef {
621                    uri,
622                    main_name_range,
623                    token_range,
624                    full_range,
625                    parsed_args: cont!(parsed_args),
626                }),
627                STeXToken::Vardef {
628                    name,
629                    main_name_range,
630                    token_range,
631                    full_range,
632                    parsed_args,
633                } => v.push(Self::Vardef {
634                    name,
635                    main_name_range,
636                    token_range,
637                    full_range,
638                    parsed_args: cont!(parsed_args),
639                }),
640                STeXToken::Varseq {
641                    name,
642                    main_name_range,
643                    token_range,
644                    full_range,
645                    parsed_args,
646                } => v.push(Self::Varseq {
647                    name,
648                    main_name_range,
649                    token_range,
650                    full_range,
651                    parsed_args: cont!(parsed_args),
652                }),
653                STeXToken::Symref {
654                    uri,
655                    full_range,
656                    token_range,
657                    name_range,
658                    text,
659                } => v.push(Self::Symref {
660                    uri,
661                    full_range,
662                    token_range,
663                    name_range,
664                    text: (text.0, Self::from_tokens(text.1, None)),
665                }),
666                STeXToken::Precondition {
667                    uri,
668                    full_range,
669                    token_range,
670                    dim_range,
671                    symbol_range,
672                    dim,
673                } => v.push(Self::Precondition {
674                    uri,
675                    full_range,
676                    token_range,
677                    dim_range,
678                    symbol_range,
679                    dim,
680                }),
681                STeXToken::Objective {
682                    uri,
683                    full_range,
684                    token_range,
685                    dim_range,
686                    symbol_range,
687                    dim,
688                } => v.push(Self::Objective {
689                    uri,
690                    full_range,
691                    token_range,
692                    dim_range,
693                    symbol_range,
694                    dim,
695                }),
696                STeXToken::SymName {
697                    uri,
698                    full_range,
699                    token_range,
700                    name_range,
701                    mode: mod_,
702                } => v.push(Self::SymName {
703                    uri,
704                    full_range,
705                    token_range,
706                    name_range,
707                    mode: mod_,
708                }),
709                STeXToken::Symuse {
710                    uri,
711                    full_range,
712                    token_range,
713                    name_range,
714                } => v.push(Self::Symuse {
715                    uri,
716                    full_range,
717                    token_range,
718                    name_range,
719                }),
720                STeXToken::Paragraph {
721                    kind,
722                    full_range,
723                    name_range,
724                    symbol,
725                    parsed_args,
726                    children,
727                } => v.push(Self::Paragraph {
728                    symbol,
729                    kind,
730                    full_range,
731                    name_range,
732                    parsed_args: cont!(parsed_args),
733                    children: Self::from_tokens(children, None),
734                }),
735                STeXToken::Problem {
736                    sub,
737                    full_range,
738                    name_range,
739                    parsed_args,
740                    children,
741                } => v.push(Self::Problem {
742                    sub,
743                    full_range,
744                    name_range,
745                    parsed_args: cont!(parsed_args),
746                    children: Self::from_tokens(children, None),
747                }),
748                STeXToken::InlineParagraph {
749                    kind,
750                    full_range,
751                    token_range,
752                    children_range,
753                    symbol,
754                    parsed_args,
755                    children,
756                } => v.push(Self::InlineParagraph {
757                    symbol,
758                    kind,
759                    full_range,
760                    token_range,
761                    children_range,
762                    parsed_args: cont!(parsed_args),
763                    children: Self::from_tokens(children, None),
764                }),
765                STeXToken::RenameDecl {
766                    uri,
767                    token_range,
768                    orig_range,
769                    name_range,
770                    macroname_range,
771                    full_range,
772                } => v.push(Self::RenameDecl {
773                    uri,
774                    token_range,
775                    orig_range,
776                    name_range,
777                    macroname_range,
778                    full_range,
779                }),
780                STeXToken::Assign {
781                    uri,
782                    token_range,
783                    orig_range,
784                    full_range,
785                } => v.push(Self::Assign {
786                    uri,
787                    token_range,
788                    orig_range,
789                    full_range,
790                }),
791                STeXToken::Vec(vi) => v.extend(Self::from_tokens(
792                    vi,
793                    modules.as_mut().map_or(None, |m| Some(*m)),
794                )),
795            }
796        }
797        v
798    }
799
800    #[must_use]
801    #[inline]
802    pub const fn range(&self) -> SourceRange<LSPLineCol> {
803        match self {
804            Self::Module { full_range, .. }
805            | Self::MathStructure { full_range, .. }
806            | Self::SemanticMacro { full_range, .. }
807            | Self::ImportModule { full_range, .. }
808            | Self::UseModule { full_range, .. }
809            | Self::SetMetatheory { full_range, .. }
810            | Self::Symdecl { full_range, .. }
811            | Self::Symdef { full_range, .. }
812            | Self::IncludeProblem { full_range, .. }
813            | Self::SymName { full_range, .. }
814            | Self::Symuse { full_range, .. }
815            | Self::Symref { full_range, .. }
816            | Self::Vardef { full_range, .. }
817            | Self::VariableMacro { full_range, .. }
818            | Self::Varseq { full_range, .. }
819            | Self::Notation { full_range, .. }
820            | Self::Svar { full_range, .. }
821            | Self::Definiens { full_range, .. }
822            | Self::Defnotation { full_range }
823            | Self::ConservativeExt { full_range, .. }
824            | Self::Paragraph { full_range, .. }
825            | Self::Problem { full_range, .. }
826            | Self::UseStructure { full_range, .. }
827            | Self::InlineParagraph { full_range, .. }
828            | Self::MorphismEnv { full_range, .. }
829            | Self::RenameDecl { full_range, .. }
830            | Self::Assign { full_range, .. }
831            | Self::Inputref { full_range, .. }
832            | Self::MHInput { full_range, .. }
833            | Self::InlineMorphism { full_range, .. }
834            | Self::Precondition { full_range, .. }
835            | Self::Objective { full_range, .. }
836            | Self::MHGraphics { full_range, .. }
837            | Self::TextSymdecl { full_range, .. } => *full_range,
838        }
839    }
840}
841
842pub enum AnnotIter<'a> {
843    Module(
844        std::iter::Chain<
845            SModuleArgIter<'a, LSPLineCol, STeXAnnot>,
846            std::slice::Iter<'a, STeXAnnot>,
847        >,
848    ),
849    InlineAss(InlineMorphAssIter<'a, LSPLineCol, STeXAnnot>),
850    Slice(std::slice::Iter<'a, STeXAnnot>),
851    Paragraph(std::iter::Chain<ParagraphArgIter<'a, STeXAnnot>, std::slice::Iter<'a, STeXAnnot>>),
852    Problem(std::iter::Chain<ProblemArgIter<'a, STeXAnnot>, std::slice::Iter<'a, STeXAnnot>>),
853    Structure(
854        std::iter::Chain<
855            MathStructureArgIter<'a, LSPLineCol, STeXAnnot>,
856            std::slice::Iter<'a, STeXAnnot>,
857        >,
858    ),
859    Symdecl(SymdeclArgIter<'a, LSPLineCol, STeXAnnot>),
860    TextSymdecl(TextSymdeclArgIter<'a, LSPLineCol, STeXAnnot>),
861    Notation(NotationArgIter<'a, LSPLineCol, STeXAnnot>),
862    Symdef(SymdefArgIter<'a, LSPLineCol, STeXAnnot>),
863    Vardef(VardefArgIter<'a, LSPLineCol, STeXAnnot>),
864}
865impl<'a> From<std::slice::Iter<'a, STeXAnnot>> for AnnotIter<'a> {
866    #[inline]
867    fn from(v: std::slice::Iter<'a, STeXAnnot>) -> Self {
868        Self::Slice(v)
869    }
870}
871impl<'a> Iterator for AnnotIter<'a> {
872    type Item = &'a STeXAnnot;
873    #[inline]
874    fn next(&mut self) -> Option<Self::Item> {
875        match self {
876            Self::Module(i) => i.next(),
877            Self::Structure(i) => i.next(),
878            Self::InlineAss(i) => i.next(),
879            Self::Paragraph(i) => i.next(),
880            Self::Problem(i) => i.next(),
881            Self::Symdecl(i) => i.next(),
882            Self::TextSymdecl(i) => i.next(),
883            Self::Notation(i) => i.next(),
884            Self::Symdef(i) => i.next(),
885            Self::Vardef(i) => i.next(),
886            Self::Slice(i) => i.next(),
887        }
888    }
889}
890
891impl TreeLike for STeXAnnot {
892    type Child<'a> = &'a Self;
893    type RefIter<'a> = AnnotIter<'a>;
894    fn children(&self) -> Option<Self::RefIter<'_>> {
895        match self {
896            Self::Module { opts, children, .. } => Some(AnnotIter::Module(
897                SModuleArgIter::new(opts).chain(children.iter()),
898            )),
899            Self::InlineMorphism { assignments, .. } => {
900                Some(AnnotIter::InlineAss(InlineMorphAssIter::new(assignments)))
901            }
902            Self::Paragraph {
903                parsed_args,
904                children,
905                ..
906            }
907            | Self::InlineParagraph {
908                parsed_args,
909                children,
910                ..
911            } => Some(AnnotIter::Paragraph(
912                ParagraphArgIter::new(parsed_args).chain(children.iter()),
913            )),
914            Self::Problem {
915                parsed_args,
916                children,
917                ..
918            } => Some(AnnotIter::Problem(
919                ProblemArgIter::new(parsed_args).chain(children.iter()),
920            )),
921            Self::Symdecl { parsed_args, .. } => {
922                Some(AnnotIter::Symdecl(SymdeclArgIter::new(parsed_args)))
923            }
924            Self::TextSymdecl { parsed_args, .. } => {
925                Some(AnnotIter::TextSymdecl(TextSymdeclArgIter::new(parsed_args)))
926            }
927            Self::Notation { notation_args, .. } => {
928                Some(AnnotIter::Notation(NotationArgIter::new(notation_args)))
929            }
930            Self::Symdef { parsed_args, .. } => {
931                Some(AnnotIter::Symdef(SymdefArgIter::new(parsed_args)))
932            }
933            Self::Vardef { parsed_args, .. } | Self::Varseq { parsed_args, .. } => {
934                Some(AnnotIter::Vardef(VardefArgIter::new(parsed_args)))
935            }
936            Self::MathStructure { children, opts, .. } => Some(AnnotIter::Structure(
937                MathStructureArgIter::new(opts).chain(children.iter()),
938            )),
939            Self::ConservativeExt { children, .. } | Self::MorphismEnv { children, .. } => {
940                Some(AnnotIter::Slice(children.iter()))
941            }
942            Self::SemanticMacro { .. }
943            | Self::VariableMacro { .. }
944            | Self::ImportModule { .. }
945            | Self::UseModule { .. }
946            | Self::SetMetatheory { .. }
947            | Self::Inputref { .. }
948            | Self::MHInput { .. }
949            | Self::SymName { .. }
950            | Self::Symref { .. }
951            | Self::Symuse { .. }
952            | Self::Svar { .. }
953            | Self::Definiens { .. }
954            | Self::Defnotation { .. }
955            | Self::UseStructure { .. }
956            | Self::Precondition { .. }
957            | Self::Objective { .. }
958            | Self::RenameDecl { .. }
959            | Self::IncludeProblem { .. }
960            | Self::MHGraphics { .. }
961            | Self::Assign { .. } => None,
962        }
963    }
964}
965
966impl TreeChild<STeXAnnot> for &STeXAnnot {
967    fn children<'a>(&self) -> Option<AnnotIter<'a>>
968    where
969        Self: 'a,
970    {
971        <STeXAnnot as TreeLike>::children(self)
972    }
973}
974
975#[derive(Copy, Clone, Debug, PartialEq, Eq)]
976pub enum DiagnosticLevel {
977    Error,
978    Warning,
979    Info,
980    Hint,
981}
982
983#[derive(PartialEq, Eq, Debug)]
984pub struct STeXDiagnostic {
985    pub level: DiagnosticLevel,
986    pub message: String,
987    pub range: SourceRange<LSPLineCol>,
988}
989
990#[must_use]
991pub fn quickparse<'a, S: STeXModuleStore>(
992    uri: &'a DocumentUri,
993    source: &'a str,
994    path: &'a Path,
995    backend: &'a AnyBackend,
996    store: S,
997) -> STeXParseDataI {
998    let mut diagnostics = VecSet::new();
999    let mut modules = SmallVec::new();
1000    let err = |message, range, level| {
1001        diagnostics.insert(STeXDiagnostic {
1002            level,
1003            message,
1004            range,
1005        });
1006    };
1007    let mut parser = if S::FULL {
1008        LaTeXParser::with_rules(
1009            ParseStr::new(source),
1010            STeXParseState::new(Some(uri.archive_uri()), Some(path), uri, backend, store),
1011            err,
1012            LaTeXParser::default_rules()
1013                .into_iter()
1014                .chain(rules::all_rules()),
1015            LaTeXParser::default_env_rules()
1016                .into_iter()
1017                .chain(rules::all_env_rules()),
1018        )
1019    } else {
1020        LaTeXParser::with_rules(
1021            ParseStr::new(source),
1022            STeXParseState::new(Some(uri.archive_uri()), Some(path), uri, backend, store),
1023            err,
1024            LaTeXParser::default_rules()
1025                .into_iter()
1026                .chain(rules::declarative_rules()),
1027            LaTeXParser::default_env_rules()
1028                .into_iter()
1029                .chain(rules::declarative_env_rules()),
1030        )
1031    };
1032
1033    let annotations = STeXAnnot::from_tokens(&mut parser, Some(&mut modules));
1034
1035    let dependents = parser.state.dependencies;
1036    STeXParseDataI {
1037        annotations,
1038        diagnostics,
1039        modules,
1040        dependencies: dependents,
1041    }
1042}