Skip to main content

flams_stex/quickparse/stex/
mod.rs

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