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