Skip to main content

cairo_lang_defs/cache/
mod.rs

1use std::hash::{Hash, Hasher};
2use std::ops::{Deref, DerefMut};
3use std::path::PathBuf;
4use std::sync::Arc;
5
6use cairo_lang_diagnostics::{DiagnosticLocation, DiagnosticNote, Maybe, Severity};
7use cairo_lang_filesystem::flag::Flag;
8use cairo_lang_filesystem::ids::{
9    CodeMapping, CrateId, CrateLongId, FileId, FileKind, FileLongId, VirtualFile,
10};
11use cairo_lang_filesystem::span::{TextOffset, TextSpan, TextWidth};
12use cairo_lang_syntax::node::ast::{
13    FunctionWithBodyPtr, GenericParamPtr, ItemConstantPtr, ItemEnumPtr, ItemExternFunctionPtr,
14    ItemExternTypePtr, ItemImplAliasPtr, ItemImplPtr, ItemMacroDeclarationPtr, ItemModulePtr,
15    ItemStructPtr, ItemTraitPtr, ItemTypeAliasPtr, UsePathLeafPtr, UsePathStarPtr,
16};
17use cairo_lang_syntax::node::green::{GreenNode, GreenNodeDetails};
18use cairo_lang_syntax::node::ids::{GreenId, SyntaxStablePtrId};
19use cairo_lang_syntax::node::kind::SyntaxKind;
20use cairo_lang_syntax::node::stable_ptr::SyntaxStablePtr;
21use cairo_lang_syntax::node::{SyntaxNode, TypedSyntaxNode, ast};
22use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
23use cairo_lang_utils::{Intern, LookupIntern};
24use salsa::InternKey;
25use serde::{Deserialize, Serialize};
26use smol_str::SmolStr;
27
28use crate::db::{DefsGroup, ModuleData, ModuleDataCacheAndLoadingData};
29use crate::ids::{
30    ConstantId, ConstantLongId, EnumId, EnumLongId, ExternFunctionId, ExternFunctionLongId,
31    ExternTypeId, ExternTypeLongId, FileIndex, FreeFunctionId, FreeFunctionLongId, GenericParamId,
32    GenericParamLongId, GlobalUseId, GlobalUseLongId, ImplAliasId, ImplAliasLongId, ImplDefId,
33    ImplDefLongId, LanguageElementId, MacroDeclarationId, MacroDeclarationLongId, ModuleFileId,
34    ModuleId, ModuleItemId, ModuleTypeAliasId, ModuleTypeAliasLongId, PluginGeneratedFileId,
35    PluginGeneratedFileLongId, StructId, StructLongId, SubmoduleId, SubmoduleLongId, TraitId,
36    TraitLongId, UseId, UseLongId,
37};
38use crate::plugin::{DynGeneratedFileAuxData, PluginDiagnostic};
39
40/// Metadata for a cached crate.
41#[derive(Serialize, Deserialize)]
42pub struct CachedCrateMetadata {
43    /// Hash of the settings the crate was compiles with.
44    pub settings: Option<u64>,
45    /// The version of the compiler that compiled the crate.
46    pub compiler_version: String,
47    /// The global flags the crate was compiled with.
48    pub global_flags: OrderedHashMap<SmolStr, Flag>,
49}
50
51impl CachedCrateMetadata {
52    /// Creates a new [CachedCrateMetadata] from the input crate with the current settings.
53    pub fn new(crate_id: CrateId, db: &dyn DefsGroup) -> Self {
54        let settings = db.crate_config(crate_id).map(|config| config.settings).map(|v| {
55            let mut hasher = xxhash_rust::xxh3::Xxh3::default();
56            v.hash(&mut hasher);
57            hasher.finish()
58        });
59        let compiler_version = env!("CARGO_PKG_VERSION").to_string();
60        let global_flags = db
61            .flags()
62            .iter()
63            .map(|(flag_id, flag)| (flag_id.lookup_intern(db).0, (**flag).clone()))
64            .collect();
65        Self { settings, compiler_version, global_flags }
66    }
67}
68
69/// Validates that the metadata of the cached crate is valid.
70fn validate_metadata(crate_id: CrateId, metadata: &CachedCrateMetadata, db: &dyn DefsGroup) {
71    let current_metadata = CachedCrateMetadata::new(crate_id, db);
72
73    if current_metadata.compiler_version != metadata.compiler_version {
74        panic!("Cached crate was compiled with a different compiler version.");
75    }
76    if current_metadata.settings != metadata.settings {
77        panic!("Cached crate was compiled with different settings.");
78    }
79
80    if !current_metadata.global_flags.eq_unordered(&metadata.global_flags) {
81        panic!("Cached crate was compiled with different global flags.");
82    }
83}
84
85type DefCache = (CachedCrateMetadata, Vec<(ModuleIdCached, ModuleDataCached)>, DefCacheLookups);
86
87/// Load the cached lowering of a crate if it has a cache file configuration.
88pub fn load_cached_crate_modules(
89    db: &dyn DefsGroup,
90    crate_id: CrateId,
91) -> Option<ModuleDataCacheAndLoadingData> {
92    let blob_id = db.crate_config(crate_id)?.cache_file?;
93    let Some(content) = db.blob_content(blob_id) else {
94        return Default::default();
95    };
96
97    let size = usize::from_be_bytes(content[..8].try_into().unwrap());
98
99    let content = &content[8..size + 8];
100
101    let ((metadata, module_data, defs_lookups), _): (DefCache, _) =
102        bincode::serde::borrow_decode_from_slice(content, bincode::config::standard())
103            .unwrap_or_else(|e| {
104                panic!(
105                    "failed to deserialize modules cache for crate `{}`: {e}",
106                    crate_id.name(db),
107                )
108            });
109
110    validate_metadata(crate_id, &metadata, db);
111
112    let mut ctx = DefCacheLoadingContext::new(db, defs_lookups, crate_id);
113    Some((
114        module_data
115            .into_iter()
116            .map(|(module_id, module_data)| {
117                let module_id = module_id.embed(&mut ctx);
118
119                let module_data = module_data.embed(&mut ctx);
120                (module_id, module_data)
121            })
122            .collect::<OrderedHashMap<_, _>>()
123            .into(),
124        ctx.data.into(),
125    ))
126}
127
128/// Cache the module_data of each module in the crate and returns the cache and the context.
129pub fn generate_crate_def_cache(
130    db: &dyn DefsGroup,
131    crate_id: cairo_lang_filesystem::ids::CrateId,
132    ctx: &mut DefCacheSavingContext<'_>,
133) -> Maybe<Vec<(ModuleIdCached, ModuleDataCached)>> {
134    let modules = db.crate_modules(crate_id);
135
136    let cached: Vec<(ModuleIdCached, ModuleDataCached)> = modules
137        .iter()
138        .map(|id| {
139            let module_data = db.priv_module_data(*id)?;
140            Ok((ModuleIdCached::new(*id, ctx), ModuleDataCached::new(module_data, ctx)))
141        })
142        .collect::<Maybe<Vec<_>>>()?;
143
144    Ok(cached)
145}
146
147/// Context for loading cache into the database.
148pub struct DefCacheLoadingContext<'db> {
149    /// The variable ids of the flat lowered that is currently being loaded.
150    db: &'db dyn DefsGroup,
151
152    /// data for loading the entire cache into the database.
153    data: DefCacheLoadingData,
154}
155
156impl<'db> DefCacheLoadingContext<'db> {
157    pub fn new(db: &'db dyn DefsGroup, lookups: DefCacheLookups, self_crate_id: CrateId) -> Self {
158        let mut res = Self { db, data: DefCacheLoadingData::new(lookups, self_crate_id) };
159        res.embed_lookups();
160        res
161    }
162    fn embed_lookups(&mut self) {
163        for id in 0..self.lookups.green_ids_lookup.len() {
164            GreenIdCached(id).embed(self);
165        }
166
167        for id in 0..self.lookups.crate_ids_lookup.len() {
168            CrateIdCached::Other(id).embed(self);
169        }
170        for id in 0..self.lookups.syntax_stable_ptr_ids_lookup.len() {
171            SyntaxStablePtrIdCached(id).embed(self);
172        }
173        for id in 0..self.lookups.submodule_ids_lookup.len() {
174            SubmoduleIdCached(id).embed(self);
175        }
176        for id in 0..self.lookups.constant_ids_lookup.len() {
177            ConstantIdCached(id).embed(self);
178        }
179        for id in 0..self.lookups.use_ids_lookup.len() {
180            UseIdCached(id).embed(self);
181        }
182        for id in 0..self.lookups.free_function_ids_lookup.len() {
183            FreeFunctionIdCached(id).embed(self);
184        }
185        for id in 0..self.lookups.struct_ids_lookup.len() {
186            StructIdCached(id).embed(self);
187        }
188        for id in 0..self.lookups.enum_ids_lookup.len() {
189            EnumIdCached(id).embed(self);
190        }
191        for id in 0..self.lookups.type_alias_ids_lookup.len() {
192            ModuleTypeAliasIdCached(id).embed(self);
193        }
194        for id in 0..self.lookups.impl_alias_ids_lookup.len() {
195            ImplAliasIdCached(id).embed(self);
196        }
197        for id in 0..self.lookups.trait_ids_lookup.len() {
198            TraitIdCached(id).embed(self);
199        }
200        for id in 0..self.lookups.impl_def_ids_lookup.len() {
201            ImplDefIdCached(id).embed(self);
202        }
203        for id in 0..self.lookups.extern_type_ids_lookup.len() {
204            ExternTypeIdCached(id).embed(self);
205        }
206        for id in 0..self.lookups.extern_function_ids_lookup.len() {
207            ExternFunctionIdCached(id).embed(self);
208        }
209        for id in 0..self.lookups.global_use_ids_lookup.len() {
210            GlobalUseIdCached(id).embed(self);
211        }
212        for id in 0..self.lookups.file_ids_lookup.len() {
213            FileIdCached(id).embed(self);
214        }
215    }
216}
217
218impl Deref for DefCacheLoadingContext<'_> {
219    type Target = DefCacheLoadingData;
220
221    fn deref(&self) -> &Self::Target {
222        &self.data
223    }
224}
225impl DerefMut for DefCacheLoadingContext<'_> {
226    fn deref_mut(&mut self) -> &mut Self::Target {
227        &mut self.data
228    }
229}
230
231/// Data for loading cache into the database.
232#[derive(PartialEq, Eq)]
233pub struct DefCacheLoadingData {
234    green_ids: OrderedHashMap<GreenIdCached, GreenId>,
235    crate_ids: OrderedHashMap<CrateIdCached, CrateId>,
236    syntax_stable_ptr_ids: OrderedHashMap<SyntaxStablePtrIdCached, SyntaxStablePtrId>,
237    submodule_ids: OrderedHashMap<SubmoduleIdCached, SubmoduleId>,
238    constant_ids: OrderedHashMap<ConstantIdCached, ConstantId>,
239    use_ids: OrderedHashMap<UseIdCached, UseId>,
240    free_function_ids: OrderedHashMap<FreeFunctionIdCached, FreeFunctionId>,
241    struct_ids: OrderedHashMap<StructIdCached, StructId>,
242    enum_ids: OrderedHashMap<EnumIdCached, EnumId>,
243    type_alias_ids: OrderedHashMap<ModuleTypeAliasIdCached, ModuleTypeAliasId>,
244    impl_alias_ids: OrderedHashMap<ImplAliasIdCached, ImplAliasId>,
245    trait_ids: OrderedHashMap<TraitIdCached, TraitId>,
246    impl_def_ids: OrderedHashMap<ImplDefIdCached, ImplDefId>,
247    extern_type_ids: OrderedHashMap<ExternTypeIdCached, ExternTypeId>,
248    extern_function_ids: OrderedHashMap<ExternFunctionIdCached, ExternFunctionId>,
249    macro_declaration_ids: OrderedHashMap<MacroDeclarationIdCached, MacroDeclarationId>,
250    global_use_ids: OrderedHashMap<GlobalUseIdCached, GlobalUseId>,
251
252    file_ids: OrderedHashMap<FileIdCached, FileId>,
253    self_crate_id: CrateId,
254    lookups: DefCacheLookups,
255}
256
257impl DefCacheLoadingData {
258    fn new(lookups: DefCacheLookups, self_crate_id: CrateId) -> Self {
259        Self {
260            green_ids: OrderedHashMap::default(),
261            syntax_stable_ptr_ids: OrderedHashMap::default(),
262            crate_ids: OrderedHashMap::default(),
263            submodule_ids: OrderedHashMap::default(),
264            constant_ids: OrderedHashMap::default(),
265            use_ids: OrderedHashMap::default(),
266            free_function_ids: OrderedHashMap::default(),
267            struct_ids: OrderedHashMap::default(),
268            enum_ids: OrderedHashMap::default(),
269            type_alias_ids: OrderedHashMap::default(),
270            impl_alias_ids: OrderedHashMap::default(),
271            trait_ids: OrderedHashMap::default(),
272            impl_def_ids: OrderedHashMap::default(),
273            extern_type_ids: OrderedHashMap::default(),
274            extern_function_ids: OrderedHashMap::default(),
275            macro_declaration_ids: OrderedHashMap::default(),
276            global_use_ids: OrderedHashMap::default(),
277
278            file_ids: OrderedHashMap::default(),
279            self_crate_id,
280            lookups,
281        }
282    }
283}
284
285impl std::fmt::Debug for DefCacheLoadingData {
286    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
287        f.debug_struct("DefCacheLoadingData").finish()
288    }
289}
290
291impl Deref for DefCacheLoadingData {
292    type Target = DefCacheLookups;
293
294    fn deref(&self) -> &Self::Target {
295        &self.lookups
296    }
297}
298impl DerefMut for DefCacheLoadingData {
299    fn deref_mut(&mut self) -> &mut Self::Target {
300        &mut self.lookups
301    }
302}
303
304/// Context for saving cache from the database.
305pub struct DefCacheSavingContext<'db> {
306    db: &'db dyn DefsGroup,
307    data: DefCacheSavingData,
308    self_crate_id: CrateId,
309}
310impl Deref for DefCacheSavingContext<'_> {
311    type Target = DefCacheSavingData;
312
313    fn deref(&self) -> &Self::Target {
314        &self.data
315    }
316}
317impl DerefMut for DefCacheSavingContext<'_> {
318    fn deref_mut(&mut self) -> &mut Self::Target {
319        &mut self.data
320    }
321}
322impl<'db> DefCacheSavingContext<'db> {
323    pub fn new(db: &'db dyn DefsGroup, self_crate_id: CrateId) -> Self {
324        Self { db, data: DefCacheSavingData::default(), self_crate_id }
325    }
326}
327
328/// Data for saving cache from the database.
329#[derive(Default)]
330pub struct DefCacheSavingData {
331    green_ids: OrderedHashMap<GreenId, GreenIdCached>,
332    crate_ids: OrderedHashMap<CrateId, CrateIdCached>,
333    submodule_ids: OrderedHashMap<SubmoduleId, SubmoduleIdCached>,
334    constant_ids: OrderedHashMap<ConstantId, ConstantIdCached>,
335    use_ids: OrderedHashMap<UseId, UseIdCached>,
336    free_function_ids: OrderedHashMap<FreeFunctionId, FreeFunctionIdCached>,
337    struct_ids: OrderedHashMap<StructId, StructIdCached>,
338    enum_ids: OrderedHashMap<EnumId, EnumIdCached>,
339    type_alias_ids: OrderedHashMap<ModuleTypeAliasId, ModuleTypeAliasIdCached>,
340    impl_alias_ids: OrderedHashMap<ImplAliasId, ImplAliasIdCached>,
341    trait_ids: OrderedHashMap<TraitId, TraitIdCached>,
342    impl_def_ids: OrderedHashMap<ImplDefId, ImplDefIdCached>,
343    extern_type_ids: OrderedHashMap<ExternTypeId, ExternTypeIdCached>,
344    extern_function_ids: OrderedHashMap<ExternFunctionId, ExternFunctionIdCached>,
345    global_use_ids: OrderedHashMap<GlobalUseId, GlobalUseIdCached>,
346    macro_declaration_ids: OrderedHashMap<MacroDeclarationId, MacroDeclarationIdCached>,
347
348    syntax_stable_ptr_ids: OrderedHashMap<SyntaxStablePtrId, SyntaxStablePtrIdCached>,
349    file_ids: OrderedHashMap<FileId, FileIdCached>,
350
351    pub lookups: DefCacheLookups,
352}
353
354impl Deref for DefCacheSavingData {
355    type Target = DefCacheLookups;
356
357    fn deref(&self) -> &Self::Target {
358        &self.lookups
359    }
360}
361impl DerefMut for DefCacheSavingData {
362    fn deref_mut(&mut self) -> &mut Self::Target {
363        &mut self.lookups
364    }
365}
366
367#[derive(Serialize, Deserialize)]
368pub struct ModuleDataCached {
369    items: Vec<ModuleItemIdCached>,
370
371    constants: OrderedHashMap<ConstantIdCached, TypeSyntaxNodeCached<ast::ItemConstant>>,
372    submodules: OrderedHashMap<SubmoduleIdCached, TypeSyntaxNodeCached<ast::ItemModule>>,
373    uses: OrderedHashMap<UseIdCached, TypeSyntaxNodeCached<ast::UsePathLeaf>>,
374    free_functions:
375        OrderedHashMap<FreeFunctionIdCached, TypeSyntaxNodeCached<ast::FunctionWithBody>>,
376    structs: OrderedHashMap<StructIdCached, TypeSyntaxNodeCached<ast::ItemStruct>>,
377    enums: OrderedHashMap<EnumIdCached, TypeSyntaxNodeCached<ast::ItemEnum>>,
378    type_aliases: OrderedHashMap<ModuleTypeAliasIdCached, TypeSyntaxNodeCached<ast::ItemTypeAlias>>,
379    impl_aliases: OrderedHashMap<ImplAliasIdCached, TypeSyntaxNodeCached<ast::ItemImplAlias>>,
380    traits: OrderedHashMap<TraitIdCached, TypeSyntaxNodeCached<ast::ItemTrait>>,
381    impls: OrderedHashMap<ImplDefIdCached, TypeSyntaxNodeCached<ast::ItemImpl>>,
382    extern_types: OrderedHashMap<ExternTypeIdCached, TypeSyntaxNodeCached<ast::ItemExternType>>,
383    extern_functions:
384        OrderedHashMap<ExternFunctionIdCached, TypeSyntaxNodeCached<ast::ItemExternFunction>>,
385    macro_declarations:
386        OrderedHashMap<MacroDeclarationIdCached, TypeSyntaxNodeCached<ast::ItemMacroDeclaration>>,
387    global_uses: OrderedHashMap<GlobalUseIdCached, TypeSyntaxNodeCached<ast::UsePathStar>>,
388
389    files: Vec<FileIdCached>,
390
391    generated_file_aux_data: Vec<Option<DynGeneratedFileAuxData>>,
392    plugin_diagnostics: Vec<(ModuleFileCached, PluginDiagnosticCached)>,
393    diagnostics_notes: PluginFileDiagnosticNotesCached,
394}
395impl ModuleDataCached {
396    fn new(module_data: ModuleData, ctx: &mut DefCacheSavingContext<'_>) -> Self {
397        Self {
398            items: module_data.items.iter().map(|id| ModuleItemIdCached::new(*id, ctx)).collect(),
399            constants: module_data
400                .constants
401                .iter()
402                .map(|(id, node)| {
403                    (ConstantIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
404                })
405                .collect(),
406
407            submodules: module_data
408                .submodules
409                .iter()
410                .map(|(id, node)| {
411                    (SubmoduleIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
412                })
413                .collect(),
414
415            uses: module_data
416                .uses
417                .iter()
418                .map(|(id, node)| {
419                    (UseIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
420                })
421                .collect(),
422            free_functions: module_data
423                .free_functions
424                .iter()
425                .map(|(id, node)| {
426                    (
427                        FreeFunctionIdCached::new(*id, ctx),
428                        TypeSyntaxNodeCached::new(node.clone(), ctx),
429                    )
430                })
431                .collect(),
432            structs: module_data
433                .structs
434                .iter()
435                .map(|(id, node)| {
436                    (StructIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
437                })
438                .collect(),
439            enums: module_data
440                .enums
441                .iter()
442                .map(|(id, node)| {
443                    (EnumIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
444                })
445                .collect(),
446            type_aliases: module_data
447                .type_aliases
448                .iter()
449                .map(|(id, node)| {
450                    (
451                        ModuleTypeAliasIdCached::new(*id, ctx),
452                        TypeSyntaxNodeCached::new(node.clone(), ctx),
453                    )
454                })
455                .collect(),
456            impl_aliases: module_data
457                .impl_aliases
458                .iter()
459                .map(|(id, node)| {
460                    (ImplAliasIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
461                })
462                .collect(),
463            traits: module_data
464                .traits
465                .iter()
466                .map(|(id, node)| {
467                    (TraitIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
468                })
469                .collect(),
470            impls: module_data
471                .impls
472                .iter()
473                .map(|(id, node)| {
474                    (ImplDefIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
475                })
476                .collect(),
477            extern_types: module_data
478                .extern_types
479                .iter()
480                .map(|(id, node)| {
481                    (
482                        ExternTypeIdCached::new(*id, ctx),
483                        TypeSyntaxNodeCached::new(node.clone(), ctx),
484                    )
485                })
486                .collect(),
487            extern_functions: module_data
488                .extern_functions
489                .iter()
490                .map(|(id, node)| {
491                    (
492                        ExternFunctionIdCached::new(*id, ctx),
493                        TypeSyntaxNodeCached::new(node.clone(), ctx),
494                    )
495                })
496                .collect(),
497
498            macro_declarations: module_data
499                .macro_declarations
500                .iter()
501                .map(|(id, node)| {
502                    (
503                        MacroDeclarationIdCached::new(*id, ctx),
504                        TypeSyntaxNodeCached::new(node.clone(), ctx),
505                    )
506                })
507                .collect(),
508            global_uses: module_data
509                .global_uses
510                .iter()
511                .map(|(id, node)| {
512                    (GlobalUseIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
513                })
514                .collect(),
515            files: module_data.files.iter().map(|id| FileIdCached::new(*id, ctx)).collect(),
516            generated_file_aux_data: module_data.generated_file_aux_data.to_vec(),
517
518            plugin_diagnostics: module_data
519                .plugin_diagnostics
520                .iter()
521                .map(|(file_id, diagnostic)| {
522                    (
523                        ModuleFileCached::new(*file_id, ctx),
524                        PluginDiagnosticCached::new(diagnostic, ctx),
525                    )
526                })
527                .collect(),
528            diagnostics_notes: module_data
529                .diagnostics_notes
530                .iter()
531                .map(|(filed_id, note)| {
532                    (
533                        FileIdCached::new(*filed_id, ctx),
534                        DiagnosticNoteCached::new(note.clone(), ctx),
535                    )
536                })
537                .collect(),
538        }
539    }
540    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleData {
541        ModuleData {
542            items: self.items.iter().map(|id| id.embed(ctx)).collect(),
543            constants: Arc::new(
544                self.constants.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
545            ),
546            submodules: Arc::new(
547                self.submodules.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
548            ),
549            uses: Arc::new(
550                self.uses.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
551            ),
552            free_functions: Arc::new(
553                self.free_functions
554                    .iter()
555                    .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
556                    .collect(),
557            ),
558            structs: Arc::new(
559                self.structs.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
560            ),
561            enums: Arc::new(
562                self.enums.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
563            ),
564            type_aliases: Arc::new(
565                self.type_aliases
566                    .iter()
567                    .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
568                    .collect(),
569            ),
570            impl_aliases: Arc::new(
571                self.impl_aliases
572                    .iter()
573                    .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
574                    .collect(),
575            ),
576            traits: Arc::new(
577                self.traits.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
578            ),
579            impls: Arc::new(
580                self.impls.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
581            ),
582            extern_types: Arc::new(
583                self.extern_types
584                    .iter()
585                    .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
586                    .collect(),
587            ),
588            extern_functions: Arc::new(
589                self.extern_functions
590                    .iter()
591                    .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
592                    .collect(),
593            ),
594            macro_declarations: Arc::new(
595                self.macro_declarations
596                    .iter()
597                    .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
598                    .collect(),
599            ),
600            global_uses: Arc::new(
601                self.global_uses
602                    .iter()
603                    .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
604                    .collect(),
605            ),
606            files: self.files.iter().map(|id| id.embed(ctx)).collect(),
607
608            plugin_diagnostics: self
609                .plugin_diagnostics
610                .into_iter()
611                .map(|(file_id, diagnostic)| (file_id.embed(ctx), diagnostic.embed(ctx)))
612                .collect(),
613
614            diagnostics_notes: self
615                .diagnostics_notes
616                .into_iter()
617                .map(|(file_id, note)| (file_id.embed(ctx), note.embed(ctx)))
618                .collect(),
619
620            generated_file_aux_data: self.generated_file_aux_data.into(),
621        }
622    }
623}
624
625/// Saved interned items for the cache.
626#[derive(Serialize, Deserialize, Default, PartialEq, Eq)]
627pub struct DefCacheLookups {
628    green_ids_lookup: Vec<GreenNodeCached>,
629    crate_ids_lookup: Vec<CrateCached>,
630    syntax_stable_ptr_ids_lookup: Vec<SyntaxStablePtrCached>,
631    submodule_ids_lookup: Vec<SubmoduleCached>,
632    constant_ids_lookup: Vec<ConstantCached>,
633    use_ids_lookup: Vec<UseCached>,
634    free_function_ids_lookup: Vec<FreeFunctionCached>,
635    struct_ids_lookup: Vec<StructCached>,
636    enum_ids_lookup: Vec<EnumCached>,
637    type_alias_ids_lookup: Vec<ModuleTypeAliasCached>,
638    impl_alias_ids_lookup: Vec<ImplAliasCached>,
639    trait_ids_lookup: Vec<TraitCached>,
640    impl_def_ids_lookup: Vec<ImplDefCached>,
641    extern_type_ids_lookup: Vec<ExternTypeCached>,
642    extern_function_ids_lookup: Vec<ExternFunctionCached>,
643    global_use_ids_lookup: Vec<GlobalUseCached>,
644    macro_declaration_ids_lookup: Vec<MacroDeclarationCached>,
645
646    file_ids_lookup: Vec<FileCached>,
647}
648
649#[derive(Serialize, Deserialize, Clone)]
650struct TypeSyntaxNodeCached<T: TypedSyntaxNode> {
651    syntax_node: SyntaxNodeCached,
652    _marker: std::marker::PhantomData<T>,
653}
654impl<T: TypedSyntaxNode> TypeSyntaxNodeCached<T> {
655    fn new(syntax_node: T, ctx: &mut DefCacheSavingContext<'_>) -> Self {
656        Self {
657            syntax_node: SyntaxNodeCached::new(syntax_node.as_syntax_node(), ctx),
658            _marker: std::marker::PhantomData,
659        }
660    }
661    fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> T {
662        T::from_syntax_node(ctx.db, self.syntax_node.embed(ctx))
663    }
664}
665
666#[derive(Serialize, Deserialize, Clone)]
667pub struct GenericParamCached {
668    language_element: LanguageElementCached,
669}
670impl GenericParamCached {
671    pub fn new(generic_param_id: GenericParamId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
672        Self { language_element: LanguageElementCached::new(generic_param_id, ctx) }
673    }
674
675    pub fn get_embedded(
676        self,
677        data: &Arc<DefCacheLoadingData>,
678        db: &dyn DefsGroup,
679    ) -> GenericParamId {
680        let (module_file_id, stable_ptr) = self.language_element.get_embedded(data);
681        GenericParamLongId(module_file_id, GenericParamPtr(stable_ptr)).intern(db)
682    }
683}
684
685#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
686struct ModuleFileCached {
687    module: ModuleIdCached,
688    file_index: usize,
689}
690impl ModuleFileCached {
691    fn new(module_file_id: ModuleFileId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
692        Self { module: ModuleIdCached::new(module_file_id.0, ctx), file_index: module_file_id.1.0 }
693    }
694    fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleFileId {
695        ModuleFileId(self.module.embed(ctx), FileIndex(self.file_index))
696    }
697    fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> ModuleFileId {
698        ModuleFileId(self.module.get_embedded(data), FileIndex(self.file_index))
699    }
700}
701
702#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
703pub enum ModuleIdCached {
704    CrateRoot(CrateIdCached),
705    Submodule(SubmoduleIdCached),
706}
707impl ModuleIdCached {
708    fn new(module_id: ModuleId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
709        match module_id {
710            ModuleId::CrateRoot(crate_id) => {
711                ModuleIdCached::CrateRoot(CrateIdCached::new(crate_id, ctx))
712            }
713            ModuleId::Submodule(submodule_id) => {
714                ModuleIdCached::Submodule(SubmoduleIdCached::new(submodule_id, ctx))
715            }
716        }
717    }
718    fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleId {
719        match self {
720            ModuleIdCached::CrateRoot(crate_id) => ModuleId::CrateRoot(crate_id.embed(ctx)),
721            ModuleIdCached::Submodule(submodule_id) => ModuleId::Submodule(submodule_id.embed(ctx)),
722        }
723    }
724    fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> ModuleId {
725        match self {
726            ModuleIdCached::CrateRoot(crate_id) => ModuleId::CrateRoot(crate_id.get_embedded(data)),
727            ModuleIdCached::Submodule(submodule_id) => {
728                ModuleId::Submodule(submodule_id.get_embedded(data))
729            }
730        }
731    }
732}
733
734#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
735enum CrateCached {
736    Real { name: SmolStr, discriminator: Option<SmolStr> },
737    Virtual { name: SmolStr, file_id: FileIdCached, settings: String },
738}
739impl CrateCached {
740    fn new(crate_id: CrateLongId, _ctx: &mut DefCacheSavingContext<'_>) -> Self {
741        match crate_id {
742            CrateLongId::Real { name, discriminator } => CrateCached::Real { name, discriminator },
743            CrateLongId::Virtual { name, file_id, settings, cache_file: _ } => {
744                CrateCached::Virtual { name, file_id: FileIdCached::new(file_id, _ctx), settings }
745            }
746        }
747    }
748    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> CrateLongId {
749        match self {
750            CrateCached::Real { name, discriminator } => CrateLongId::Real { name, discriminator },
751            CrateCached::Virtual { name, file_id, settings } => {
752                CrateLongId::Virtual {
753                    name,
754                    file_id: file_id.embed(ctx),
755                    settings,
756                    cache_file: None, // todo  if two virtual crates are supported
757                }
758            }
759        }
760    }
761}
762#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
763pub enum CrateIdCached {
764    SelfCrate,
765    Other(usize),
766}
767impl CrateIdCached {
768    fn new(crate_id: CrateId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
769        if crate_id == ctx.self_crate_id {
770            return CrateIdCached::SelfCrate;
771        }
772        if let Some(id) = ctx.crate_ids.get(&crate_id) {
773            return *id;
774        }
775        let crate_long_id = CrateCached::new(crate_id.lookup_intern(ctx.db), ctx);
776        let id = CrateIdCached::Other(ctx.crate_ids_lookup.len());
777        ctx.crate_ids_lookup.push(crate_long_id);
778        ctx.crate_ids.insert(crate_id, id);
779        id
780    }
781    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> CrateId {
782        let CrateIdCached::Other(id) = self else {
783            return ctx.self_crate_id;
784        };
785
786        if let Some(crate_id) = ctx.crate_ids.get(&self) {
787            return *crate_id;
788        }
789        let crate_long_id = ctx.crate_ids_lookup[id].clone();
790        let crate_id = crate_long_id.embed(ctx).intern(ctx.db);
791        ctx.data.crate_ids.insert(self, crate_id);
792        crate_id
793    }
794    fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> CrateId {
795        let CrateIdCached::Other(_) = self else {
796            return data.self_crate_id;
797        };
798        data.crate_ids[&self]
799    }
800}
801
802#[derive(Serialize, Deserialize, Copy, Clone)]
803enum ModuleItemIdCached {
804    Constant(ConstantIdCached),
805    Submodule(SubmoduleIdCached),
806    Use(UseIdCached),
807    FreeFunction(FreeFunctionIdCached),
808    Struct(StructIdCached),
809    Enum(EnumIdCached),
810    TypeAlias(ModuleTypeAliasIdCached),
811    ImplAlias(ImplAliasIdCached),
812    Trait(TraitIdCached),
813    Impl(ImplDefIdCached),
814    ExternType(ExternTypeIdCached),
815    ExternFunction(ExternFunctionIdCached),
816    MacroDeclaration(MacroDeclarationIdCached),
817}
818
819impl ModuleItemIdCached {
820    fn new(module_item_id: ModuleItemId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
821        match module_item_id {
822            ModuleItemId::Constant(constant_id) => {
823                ModuleItemIdCached::Constant(ConstantIdCached::new(constant_id, ctx))
824            }
825            ModuleItemId::Submodule(submodule_id) => {
826                ModuleItemIdCached::Submodule(SubmoduleIdCached::new(submodule_id, ctx))
827            }
828            ModuleItemId::Use(use_id) => ModuleItemIdCached::Use(UseIdCached::new(use_id, ctx)),
829            ModuleItemId::FreeFunction(free_function_id) => {
830                ModuleItemIdCached::FreeFunction(FreeFunctionIdCached::new(free_function_id, ctx))
831            }
832            ModuleItemId::Struct(struct_id) => {
833                ModuleItemIdCached::Struct(StructIdCached::new(struct_id, ctx))
834            }
835            ModuleItemId::Enum(enum_id) => {
836                ModuleItemIdCached::Enum(EnumIdCached::new(enum_id, ctx))
837            }
838            ModuleItemId::TypeAlias(type_alias_id) => {
839                ModuleItemIdCached::TypeAlias(ModuleTypeAliasIdCached::new(type_alias_id, ctx))
840            }
841            ModuleItemId::ImplAlias(impl_alias_id) => {
842                ModuleItemIdCached::ImplAlias(ImplAliasIdCached::new(impl_alias_id, ctx))
843            }
844            ModuleItemId::Trait(trait_id) => {
845                ModuleItemIdCached::Trait(TraitIdCached::new(trait_id, ctx))
846            }
847            ModuleItemId::Impl(impl_def_id) => {
848                ModuleItemIdCached::Impl(ImplDefIdCached::new(impl_def_id, ctx))
849            }
850            ModuleItemId::ExternType(extern_type_id) => {
851                ModuleItemIdCached::ExternType(ExternTypeIdCached::new(extern_type_id, ctx))
852            }
853            ModuleItemId::ExternFunction(extern_function_id) => ModuleItemIdCached::ExternFunction(
854                ExternFunctionIdCached::new(extern_function_id, ctx),
855            ),
856            ModuleItemId::MacroDeclaration(macro_declaration_id) => {
857                ModuleItemIdCached::MacroDeclaration(MacroDeclarationIdCached::new(
858                    macro_declaration_id,
859                    ctx,
860                ))
861            }
862        }
863    }
864    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleItemId {
865        match self {
866            ModuleItemIdCached::Constant(constant_id) => {
867                ModuleItemId::Constant(constant_id.embed(ctx))
868            }
869            ModuleItemIdCached::Submodule(submodule_id) => {
870                ModuleItemId::Submodule(submodule_id.embed(ctx))
871            }
872            ModuleItemIdCached::Use(use_id) => ModuleItemId::Use(use_id.embed(ctx)),
873            ModuleItemIdCached::FreeFunction(free_function_id) => {
874                ModuleItemId::FreeFunction(free_function_id.embed(ctx))
875            }
876            ModuleItemIdCached::Struct(struct_id) => ModuleItemId::Struct(struct_id.embed(ctx)),
877            ModuleItemIdCached::Enum(enum_id) => ModuleItemId::Enum(enum_id.embed(ctx)),
878            ModuleItemIdCached::TypeAlias(type_alias_id) => {
879                ModuleItemId::TypeAlias(type_alias_id.embed(ctx))
880            }
881            ModuleItemIdCached::ImplAlias(impl_alias_id) => {
882                ModuleItemId::ImplAlias(impl_alias_id.embed(ctx))
883            }
884            ModuleItemIdCached::Trait(trait_id) => ModuleItemId::Trait(trait_id.embed(ctx)),
885            ModuleItemIdCached::Impl(impl_def_id) => ModuleItemId::Impl(impl_def_id.embed(ctx)),
886            ModuleItemIdCached::ExternType(extern_type_id) => {
887                ModuleItemId::ExternType(extern_type_id.embed(ctx))
888            }
889            ModuleItemIdCached::ExternFunction(extern_function_id) => {
890                ModuleItemId::ExternFunction(extern_function_id.embed(ctx))
891            }
892            ModuleItemIdCached::MacroDeclaration(macro_declaration_id) => {
893                ModuleItemId::MacroDeclaration(macro_declaration_id.embed(ctx))
894            }
895        }
896    }
897}
898
899#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
900struct ConstantCached {
901    language_element: LanguageElementCached,
902}
903impl ConstantCached {
904    fn new(constant_id: ConstantLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
905        Self { language_element: LanguageElementCached::new(constant_id.intern(ctx.db), ctx) }
906    }
907    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ConstantLongId {
908        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
909
910        ConstantLongId(module_file_id, ItemConstantPtr(stable_ptr))
911    }
912}
913
914#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
915struct ConstantIdCached(usize);
916
917impl ConstantIdCached {
918    fn new(constant_id: ConstantId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
919        if let Some(id) = ctx.constant_ids.get(&constant_id) {
920            return *id;
921        }
922        let constant = ConstantCached::new(constant_id.lookup_intern(ctx.db), ctx);
923        let id = ConstantIdCached(ctx.constant_ids_lookup.len());
924        ctx.constant_ids_lookup.push(constant);
925        ctx.constant_ids.insert(constant_id, id);
926        id
927    }
928    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ConstantId {
929        if let Some(constant_id) = ctx.constant_ids.get(&self) {
930            return *constant_id;
931        }
932        let constant = ctx.constant_ids_lookup[self.0].clone();
933        let constant = constant.embed(ctx).intern(ctx.db);
934        ctx.constant_ids.insert(self, constant);
935        constant
936    }
937}
938
939#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
940struct SubmoduleCached {
941    language_element: LanguageElementCached,
942}
943impl SubmoduleCached {
944    fn new(submodule_id: SubmoduleLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
945        Self { language_element: LanguageElementCached::new(submodule_id.intern(ctx.db), ctx) }
946    }
947    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> SubmoduleLongId {
948        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
949
950        SubmoduleLongId(module_file_id, ItemModulePtr(stable_ptr))
951    }
952}
953
954#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
955pub struct SubmoduleIdCached(usize);
956
957impl SubmoduleIdCached {
958    fn new(submodule_id: SubmoduleId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
959        if let Some(id) = ctx.submodule_ids.get(&submodule_id) {
960            return *id;
961        }
962        let submodule = SubmoduleCached::new(submodule_id.lookup_intern(ctx.db), ctx);
963        let id = SubmoduleIdCached(ctx.submodule_ids_lookup.len());
964        ctx.submodule_ids_lookup.push(submodule);
965        ctx.submodule_ids.insert(submodule_id, id);
966        id
967    }
968    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> SubmoduleId {
969        if let Some(submodule_id) = ctx.submodule_ids.get(&self) {
970            return *submodule_id;
971        }
972        let submodule = ctx.submodule_ids_lookup[self.0].clone();
973        let submodule = submodule.embed(ctx).intern(ctx.db);
974        ctx.submodule_ids.insert(self, submodule);
975        submodule
976    }
977    fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> SubmoduleId {
978        data.submodule_ids[&self]
979    }
980}
981
982#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
983struct UseCached {
984    language_element: LanguageElementCached,
985}
986impl UseCached {
987    fn new(use_id: UseLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
988        Self { language_element: LanguageElementCached::new(use_id.intern(ctx.db), ctx) }
989    }
990    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> UseLongId {
991        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
992
993        UseLongId(module_file_id, UsePathLeafPtr(stable_ptr))
994    }
995}
996
997#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
998struct UseIdCached(usize);
999
1000impl UseIdCached {
1001    fn new(use_id: UseId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1002        if let Some(id) = ctx.use_ids.get(&use_id) {
1003            return *id;
1004        }
1005        let use_cache = UseCached::new(use_id.lookup_intern(ctx.db), ctx);
1006        let id = UseIdCached(ctx.use_ids_lookup.len());
1007        ctx.use_ids_lookup.push(use_cache);
1008        ctx.use_ids.insert(use_id, id);
1009        id
1010    }
1011    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> UseId {
1012        if let Some(use_id) = ctx.use_ids.get(&self) {
1013            return *use_id;
1014        }
1015        let use_cached = ctx.use_ids_lookup[self.0].clone();
1016        let use_cached = use_cached.embed(ctx).intern(ctx.db);
1017        ctx.use_ids.insert(self, use_cached);
1018        use_cached
1019    }
1020}
1021
1022#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1023struct FreeFunctionCached {
1024    language_element: LanguageElementCached,
1025}
1026impl FreeFunctionCached {
1027    fn new(free_function_id: FreeFunctionLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1028        Self { language_element: LanguageElementCached::new(free_function_id.intern(ctx.db), ctx) }
1029    }
1030    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> FreeFunctionLongId {
1031        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1032
1033        FreeFunctionLongId(module_file_id, FunctionWithBodyPtr(stable_ptr))
1034    }
1035}
1036
1037#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1038struct FreeFunctionIdCached(usize);
1039
1040impl FreeFunctionIdCached {
1041    fn new(free_function_id: FreeFunctionId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1042        if let Some(id) = ctx.free_function_ids.get(&free_function_id) {
1043            return *id;
1044        }
1045        let free_function = FreeFunctionCached::new(free_function_id.lookup_intern(ctx.db), ctx);
1046        let id = FreeFunctionIdCached(ctx.free_function_ids_lookup.len());
1047        ctx.free_function_ids_lookup.push(free_function);
1048        ctx.free_function_ids.insert(free_function_id, id);
1049        id
1050    }
1051    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> FreeFunctionId {
1052        if let Some(free_function_id) = ctx.free_function_ids.get(&self) {
1053            return *free_function_id;
1054        }
1055        let free_function = ctx.free_function_ids_lookup[self.0].clone();
1056        let free_function = free_function.embed(ctx).intern(ctx.db);
1057        ctx.free_function_ids.insert(self, free_function);
1058        free_function
1059    }
1060}
1061
1062#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1063struct StructCached {
1064    language_element: LanguageElementCached,
1065}
1066impl StructCached {
1067    fn new(struct_id: StructLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1068        Self { language_element: LanguageElementCached::new(struct_id.intern(ctx.db), ctx) }
1069    }
1070    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> StructLongId {
1071        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1072
1073        StructLongId(module_file_id, ItemStructPtr(stable_ptr))
1074    }
1075}
1076
1077#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1078struct StructIdCached(usize);
1079
1080impl StructIdCached {
1081    fn new(struct_id: StructId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1082        if let Some(id) = ctx.struct_ids.get(&struct_id) {
1083            return *id;
1084        }
1085        let struct_cached = StructCached::new(struct_id.lookup_intern(ctx.db), ctx);
1086        let id = StructIdCached(ctx.struct_ids_lookup.len());
1087        ctx.struct_ids_lookup.push(struct_cached);
1088        ctx.struct_ids.insert(struct_id, id);
1089        id
1090    }
1091    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> StructId {
1092        if let Some(struct_id) = ctx.struct_ids.get(&self) {
1093            return *struct_id;
1094        }
1095        let struct_cached = ctx.struct_ids_lookup[self.0].clone();
1096        let struct_cached = struct_cached.embed(ctx).intern(ctx.db);
1097        ctx.struct_ids.insert(self, struct_cached);
1098        struct_cached
1099    }
1100}
1101
1102#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1103struct EnumCached {
1104    language_element: LanguageElementCached,
1105}
1106impl EnumCached {
1107    fn new(enum_id: EnumLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1108        Self { language_element: LanguageElementCached::new(enum_id.intern(ctx.db), ctx) }
1109    }
1110    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> EnumLongId {
1111        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1112
1113        EnumLongId(module_file_id, ItemEnumPtr(stable_ptr))
1114    }
1115}
1116
1117#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1118struct EnumIdCached(usize);
1119
1120impl EnumIdCached {
1121    fn new(enum_id: EnumId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1122        if let Some(id) = ctx.enum_ids.get(&enum_id) {
1123            return *id;
1124        }
1125        let enum_cached = EnumCached::new(enum_id.lookup_intern(ctx.db), ctx);
1126        let id = EnumIdCached(ctx.enum_ids_lookup.len());
1127        ctx.enum_ids_lookup.push(enum_cached);
1128        ctx.enum_ids.insert(enum_id, id);
1129        id
1130    }
1131    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> EnumId {
1132        if let Some(enum_id) = ctx.enum_ids.get(&self) {
1133            return *enum_id;
1134        }
1135        let enum_cached = ctx.enum_ids_lookup[self.0].clone();
1136        let enum_cached = enum_cached.embed(ctx).intern(ctx.db);
1137        ctx.enum_ids.insert(self, enum_cached);
1138        enum_cached
1139    }
1140}
1141
1142#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1143struct ModuleTypeAliasCached {
1144    language_element: LanguageElementCached,
1145}
1146impl ModuleTypeAliasCached {
1147    fn new(type_alias_id: ModuleTypeAliasLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1148        Self { language_element: LanguageElementCached::new(type_alias_id.intern(ctx.db), ctx) }
1149    }
1150    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleTypeAliasLongId {
1151        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1152
1153        ModuleTypeAliasLongId(module_file_id, ItemTypeAliasPtr(stable_ptr))
1154    }
1155}
1156
1157#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1158struct ModuleTypeAliasIdCached(usize);
1159
1160impl ModuleTypeAliasIdCached {
1161    fn new(type_alias_id: ModuleTypeAliasId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1162        if let Some(id) = ctx.type_alias_ids.get(&type_alias_id) {
1163            return *id;
1164        }
1165        let type_alias = ModuleTypeAliasCached::new(type_alias_id.lookup_intern(ctx.db), ctx);
1166        let id = ModuleTypeAliasIdCached(ctx.type_alias_ids_lookup.len());
1167        ctx.type_alias_ids_lookup.push(type_alias);
1168        ctx.type_alias_ids.insert(type_alias_id, id);
1169        id
1170    }
1171    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ModuleTypeAliasId {
1172        if let Some(type_alias_id) = ctx.type_alias_ids.get(&self) {
1173            return *type_alias_id;
1174        }
1175        let type_alias = ctx.type_alias_ids_lookup[self.0].clone();
1176        let type_alias = type_alias.embed(ctx).intern(ctx.db);
1177        ctx.type_alias_ids.insert(self, type_alias);
1178        type_alias
1179    }
1180}
1181
1182#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1183struct ImplAliasCached {
1184    language_element: LanguageElementCached,
1185}
1186impl ImplAliasCached {
1187    fn new(impl_alias_id: ImplAliasLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1188        Self { language_element: LanguageElementCached::new(impl_alias_id.intern(ctx.db), ctx) }
1189    }
1190    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ImplAliasLongId {
1191        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1192
1193        ImplAliasLongId(module_file_id, ItemImplAliasPtr(stable_ptr))
1194    }
1195}
1196
1197#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1198struct ImplAliasIdCached(usize);
1199
1200impl ImplAliasIdCached {
1201    fn new(impl_alias_id: ImplAliasId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1202        if let Some(id) = ctx.impl_alias_ids.get(&impl_alias_id) {
1203            return *id;
1204        }
1205        let impl_alias = ImplAliasCached::new(impl_alias_id.lookup_intern(ctx.db), ctx);
1206        let id = ImplAliasIdCached(ctx.impl_alias_ids_lookup.len());
1207        ctx.impl_alias_ids_lookup.push(impl_alias);
1208        ctx.impl_alias_ids.insert(impl_alias_id, id);
1209        id
1210    }
1211    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ImplAliasId {
1212        if let Some(impl_alias_id) = ctx.impl_alias_ids.get(&self) {
1213            return *impl_alias_id;
1214        }
1215        let impl_alias = ctx.impl_alias_ids_lookup[self.0].clone();
1216        let impl_alias = impl_alias.embed(ctx).intern(ctx.db);
1217        ctx.impl_alias_ids.insert(self, impl_alias);
1218        impl_alias
1219    }
1220}
1221
1222#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1223struct TraitCached {
1224    language_element: LanguageElementCached,
1225}
1226impl TraitCached {
1227    fn new(trait_id: TraitLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1228        Self { language_element: LanguageElementCached::new(trait_id.intern(ctx.db), ctx) }
1229    }
1230    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> TraitLongId {
1231        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1232
1233        TraitLongId(module_file_id, ItemTraitPtr(stable_ptr))
1234    }
1235}
1236
1237#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1238struct TraitIdCached(usize);
1239
1240impl TraitIdCached {
1241    fn new(trait_id: TraitId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1242        if let Some(id) = ctx.trait_ids.get(&trait_id) {
1243            return *id;
1244        }
1245        let trait_cached = TraitCached::new(trait_id.lookup_intern(ctx.db), ctx);
1246        let id = TraitIdCached(ctx.trait_ids_lookup.len());
1247        ctx.trait_ids_lookup.push(trait_cached);
1248        ctx.trait_ids.insert(trait_id, id);
1249        id
1250    }
1251    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> TraitId {
1252        if let Some(trait_id) = ctx.trait_ids.get(&self) {
1253            return *trait_id;
1254        }
1255        let trait_cached = ctx.trait_ids_lookup[self.0].clone();
1256        let trait_cached = trait_cached.embed(ctx).intern(ctx.db);
1257        ctx.trait_ids.insert(self, trait_cached);
1258        trait_cached
1259    }
1260}
1261
1262#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1263struct ImplDefCached {
1264    language_element: LanguageElementCached,
1265}
1266impl ImplDefCached {
1267    fn new(impl_def_id: ImplDefLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1268        Self { language_element: LanguageElementCached::new(impl_def_id.intern(ctx.db), ctx) }
1269    }
1270    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ImplDefLongId {
1271        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1272
1273        ImplDefLongId(module_file_id, ItemImplPtr(stable_ptr))
1274    }
1275}
1276
1277#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1278pub struct ImplDefIdCached(usize);
1279
1280impl ImplDefIdCached {
1281    pub fn new(impl_def_id: ImplDefId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1282        if let Some(id) = ctx.impl_def_ids.get(&impl_def_id) {
1283            return *id;
1284        }
1285        let impl_def = ImplDefCached::new(impl_def_id.lookup_intern(ctx.db), ctx);
1286        let id = ImplDefIdCached(ctx.impl_def_ids_lookup.len());
1287        ctx.impl_def_ids_lookup.push(impl_def);
1288        ctx.impl_def_ids.insert(impl_def_id, id);
1289        id
1290    }
1291
1292    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ImplDefId {
1293        if let Some(impl_def_id) = ctx.impl_def_ids.get(&self) {
1294            return *impl_def_id;
1295        }
1296        let impl_def = ctx.impl_def_ids_lookup[self.0].clone();
1297        let impl_def = impl_def.embed(ctx).intern(ctx.db);
1298        ctx.impl_def_ids.insert(self, impl_def);
1299        impl_def
1300    }
1301
1302    pub fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> ImplDefId {
1303        data.impl_def_ids[&self]
1304    }
1305}
1306
1307#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1308struct ExternTypeCached {
1309    language_element: LanguageElementCached,
1310}
1311impl ExternTypeCached {
1312    fn new(extern_type_id: ExternTypeLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1313        Self { language_element: LanguageElementCached::new(extern_type_id.intern(ctx.db), ctx) }
1314    }
1315    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ExternTypeLongId {
1316        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1317
1318        ExternTypeLongId(module_file_id, ItemExternTypePtr(stable_ptr))
1319    }
1320}
1321
1322#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1323struct ExternTypeIdCached(usize);
1324
1325impl ExternTypeIdCached {
1326    fn new(extern_type_id: ExternTypeId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1327        if let Some(id) = ctx.extern_type_ids.get(&extern_type_id) {
1328            return *id;
1329        }
1330        let extern_type = ExternTypeCached::new(extern_type_id.lookup_intern(ctx.db), ctx);
1331        let id = ExternTypeIdCached(ctx.extern_type_ids_lookup.len());
1332        ctx.extern_type_ids_lookup.push(extern_type);
1333        ctx.extern_type_ids.insert(extern_type_id, id);
1334        id
1335    }
1336    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ExternTypeId {
1337        if let Some(extern_type_id) = ctx.extern_type_ids.get(&self) {
1338            return *extern_type_id;
1339        }
1340        let extern_type = ctx.extern_type_ids_lookup[self.0].clone();
1341        let extern_type = extern_type.embed(ctx).intern(ctx.db);
1342        ctx.extern_type_ids.insert(self, extern_type);
1343        extern_type
1344    }
1345}
1346
1347#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1348struct ExternFunctionCached {
1349    language_element: LanguageElementCached,
1350}
1351impl ExternFunctionCached {
1352    fn new(extern_function_id: ExternFunctionLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1353        Self {
1354            language_element: LanguageElementCached::new(extern_function_id.intern(ctx.db), ctx),
1355        }
1356    }
1357    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ExternFunctionLongId {
1358        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1359
1360        ExternFunctionLongId(module_file_id, ItemExternFunctionPtr(stable_ptr))
1361    }
1362}
1363
1364#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1365struct ExternFunctionIdCached(usize);
1366
1367impl ExternFunctionIdCached {
1368    fn new(extern_function_id: ExternFunctionId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1369        if let Some(id) = ctx.extern_function_ids.get(&extern_function_id) {
1370            return *id;
1371        }
1372        let extern_function =
1373            ExternFunctionCached::new(extern_function_id.lookup_intern(ctx.db), ctx);
1374        let id = ExternFunctionIdCached(ctx.extern_function_ids_lookup.len());
1375        ctx.extern_function_ids_lookup.push(extern_function);
1376        ctx.extern_function_ids.insert(extern_function_id, id);
1377        id
1378    }
1379    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> ExternFunctionId {
1380        if let Some(extern_function_id) = ctx.extern_function_ids.get(&self) {
1381            return *extern_function_id;
1382        }
1383        let extern_function = ctx.extern_function_ids_lookup[self.0].clone();
1384        let extern_function = extern_function.embed(ctx).intern(ctx.db);
1385        ctx.extern_function_ids.insert(self, extern_function);
1386        extern_function
1387    }
1388}
1389#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1390struct MacroDeclarationCached {
1391    language_element: LanguageElementCached,
1392}
1393
1394impl MacroDeclarationCached {
1395    fn new(
1396        macro_declaration_id: MacroDeclarationLongId,
1397        ctx: &mut DefCacheSavingContext<'_>,
1398    ) -> Self {
1399        Self {
1400            language_element: LanguageElementCached::new(macro_declaration_id.intern(ctx.db), ctx),
1401        }
1402    }
1403    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> MacroDeclarationLongId {
1404        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1405
1406        MacroDeclarationLongId(module_file_id, ItemMacroDeclarationPtr(stable_ptr))
1407    }
1408}
1409
1410#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1411struct MacroDeclarationIdCached(usize);
1412
1413impl MacroDeclarationIdCached {
1414    fn new(macro_declaration_id: MacroDeclarationId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1415        if let Some(id) = ctx.macro_declaration_ids.get(&macro_declaration_id) {
1416            return *id;
1417        }
1418        let macro_declaration =
1419            MacroDeclarationCached::new(macro_declaration_id.lookup_intern(ctx.db), ctx);
1420        let id = MacroDeclarationIdCached(ctx.macro_declaration_ids_lookup.len());
1421        ctx.macro_declaration_ids_lookup.push(macro_declaration);
1422        ctx.macro_declaration_ids.insert(macro_declaration_id, id);
1423        id
1424    }
1425    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> MacroDeclarationId {
1426        if let Some(macro_declaration_id) = ctx.macro_declaration_ids.get(&self) {
1427            return *macro_declaration_id;
1428        }
1429        let macro_declaration = ctx.macro_declaration_ids_lookup[self.0].clone();
1430        let macro_declaration = macro_declaration.embed(ctx).intern(ctx.db);
1431        ctx.macro_declaration_ids.insert(self, macro_declaration);
1432        macro_declaration
1433    }
1434}
1435
1436#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1437struct GlobalUseCached {
1438    language_element: LanguageElementCached,
1439}
1440impl GlobalUseCached {
1441    fn new(global_use_id: GlobalUseLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1442        Self { language_element: LanguageElementCached::new(global_use_id.intern(ctx.db), ctx) }
1443    }
1444    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> GlobalUseLongId {
1445        let (module_file_id, stable_ptr) = self.language_element.embed(ctx);
1446
1447        GlobalUseLongId(module_file_id, UsePathStarPtr(stable_ptr))
1448    }
1449}
1450
1451#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1452struct GlobalUseIdCached(usize);
1453
1454impl GlobalUseIdCached {
1455    fn new(global_use_id: GlobalUseId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1456        if let Some(id) = ctx.global_use_ids.get(&global_use_id) {
1457            return *id;
1458        }
1459        let global_use = GlobalUseCached::new(global_use_id.lookup_intern(ctx.db), ctx);
1460        let id = GlobalUseIdCached(ctx.global_use_ids_lookup.len());
1461        ctx.global_use_ids_lookup.push(global_use);
1462        ctx.global_use_ids.insert(global_use_id, id);
1463        id
1464    }
1465    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> GlobalUseId {
1466        if let Some(global_use_id) = ctx.global_use_ids.get(&self) {
1467            return *global_use_id;
1468        }
1469        let global_use = ctx.global_use_ids_lookup[self.0].clone();
1470        let global_use = global_use.embed(ctx).intern(ctx.db);
1471        ctx.global_use_ids.insert(self, global_use);
1472        global_use
1473    }
1474}
1475
1476#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
1477struct SyntaxNodeCached(Box<SyntaxNodeInnerCached>);
1478
1479#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
1480struct SyntaxNodeInnerCached {
1481    green: GreenIdCached,
1482    offset: TextOffset,
1483    parent: Option<SyntaxNodeCached>,
1484    stable_ptr: SyntaxStablePtrIdCached,
1485}
1486
1487impl SyntaxNodeCached {
1488    fn new(syntax_node: SyntaxNode, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1489        let db = ctx.db;
1490        let green = GreenIdCached::new(syntax_node.green_node(db).intern(db), ctx);
1491        let parent = syntax_node.parent(db).map(|it| Self::new(it, ctx));
1492        let stable_ptr = SyntaxStablePtrIdCached::new(syntax_node.stable_ptr(db), ctx);
1493        let offset = syntax_node.offset(db);
1494        let inner = SyntaxNodeInnerCached { green, offset, parent, stable_ptr };
1495        SyntaxNodeCached(Box::new(inner))
1496    }
1497    fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> SyntaxNode {
1498        let inner = self.0.as_ref();
1499        let green = inner.green.embed(ctx);
1500        let parent = inner.parent.as_ref().map(|it| it.embed(ctx));
1501        let stable_ptr = inner.stable_ptr.embed(ctx);
1502        let offset = inner.offset;
1503        SyntaxNode::new_with_inner(ctx.db, green, offset, parent, stable_ptr)
1504    }
1505}
1506
1507#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
1508pub struct LanguageElementCached {
1509    module_file_id: ModuleFileCached,
1510    stable_ptr: SyntaxStablePtrIdCached,
1511}
1512impl LanguageElementCached {
1513    pub fn new<T: LanguageElementId>(
1514        language_element: T,
1515        ctx: &mut DefCacheSavingContext<'_>,
1516    ) -> Self {
1517        Self {
1518            module_file_id: ModuleFileCached::new(language_element.module_file_id(ctx.db), ctx),
1519            stable_ptr: SyntaxStablePtrIdCached::new(
1520                language_element.untyped_stable_ptr(ctx.db),
1521                ctx,
1522            ),
1523        }
1524    }
1525    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> (ModuleFileId, SyntaxStablePtrId) {
1526        let module_file_id = self.module_file_id.embed(ctx);
1527        let stable_ptr = self.stable_ptr.embed(ctx);
1528        (module_file_id, stable_ptr)
1529    }
1530    pub fn get_embedded(
1531        self,
1532        data: &Arc<DefCacheLoadingData>,
1533    ) -> (ModuleFileId, SyntaxStablePtrId) {
1534        let module_file_id = self.module_file_id.get_embedded(data);
1535        let stable_ptr = self.stable_ptr.get_embedded(data);
1536        (module_file_id, stable_ptr)
1537    }
1538}
1539
1540#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1541enum SyntaxStablePtrCached {
1542    /// The root node of the tree.
1543    Root(FileIdCached, GreenIdCached),
1544    /// A child node.
1545    Child {
1546        /// The parent of the node.
1547        parent: SyntaxStablePtrIdCached,
1548        /// The SyntaxKind of the node.
1549        kind: SyntaxKind,
1550        /// A list of field values for this node, to index by.
1551        /// Which fields are used is determined by each SyntaxKind.
1552        /// For example, a function item might use the name of the function.
1553        key_fields: Vec<GreenIdCached>,
1554        /// Chronological index among all nodes with the same (parent, kind, key_fields).
1555        index: usize,
1556    },
1557}
1558
1559impl SyntaxStablePtrCached {
1560    fn new(syntax_stable_ptr: SyntaxStablePtr, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1561        match syntax_stable_ptr {
1562            SyntaxStablePtr::Root(root, green_id) => SyntaxStablePtrCached::Root(
1563                FileIdCached::new(root, ctx),
1564                GreenIdCached::new(green_id, ctx),
1565            ),
1566            SyntaxStablePtr::Child { parent, kind, key_fields, index } => {
1567                SyntaxStablePtrCached::Child {
1568                    parent: SyntaxStablePtrIdCached::new(parent, ctx),
1569                    kind,
1570                    key_fields: key_fields
1571                        .iter()
1572                        .map(|field| GreenIdCached::new(*field, ctx))
1573                        .collect(),
1574                    index,
1575                }
1576            }
1577        }
1578    }
1579    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> SyntaxStablePtr {
1580        match self {
1581            SyntaxStablePtrCached::Root(file, green_id) => {
1582                SyntaxStablePtr::Root(file.embed(ctx), green_id.embed(ctx))
1583            }
1584            SyntaxStablePtrCached::Child { parent, kind, key_fields, index } => {
1585                SyntaxStablePtr::Child {
1586                    parent: parent.embed(ctx),
1587                    kind,
1588                    key_fields: key_fields.into_iter().map(|field| field.embed(ctx)).collect(),
1589                    index,
1590                }
1591            }
1592        }
1593    }
1594}
1595
1596#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1597pub struct SyntaxStablePtrIdCached(usize);
1598impl SyntaxStablePtrIdCached {
1599    pub fn new(
1600        syntax_stable_ptr_id: SyntaxStablePtrId,
1601        ctx: &mut DefCacheSavingContext<'_>,
1602    ) -> Self {
1603        if let Some(id) = ctx.syntax_stable_ptr_ids.get(&syntax_stable_ptr_id) {
1604            return *id;
1605        }
1606        let stable_ptr =
1607            SyntaxStablePtrCached::new(syntax_stable_ptr_id.lookup_intern(ctx.db), ctx);
1608        let id = SyntaxStablePtrIdCached(ctx.syntax_stable_ptr_ids_lookup.len());
1609        ctx.syntax_stable_ptr_ids_lookup.push(stable_ptr);
1610        ctx.syntax_stable_ptr_ids.insert(syntax_stable_ptr_id, id);
1611        id
1612    }
1613    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> SyntaxStablePtrId {
1614        if let Some(syntax_stable_ptr_id) = ctx.syntax_stable_ptr_ids.get(&self) {
1615            return *syntax_stable_ptr_id;
1616        }
1617        let stable_ptr = ctx.syntax_stable_ptr_ids_lookup[self.0].clone();
1618        let stable_ptr = stable_ptr.embed(ctx);
1619        let stable_ptr_id = stable_ptr.intern(ctx.db);
1620        ctx.syntax_stable_ptr_ids.insert(self, stable_ptr_id);
1621        stable_ptr_id
1622    }
1623    pub fn get_embedded(self, data: &Arc<DefCacheLoadingData>) -> SyntaxStablePtrId {
1624        data.syntax_stable_ptr_ids[&self]
1625    }
1626}
1627
1628#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1629enum GreenNodeDetailsCached {
1630    Token(SmolStr),
1631    Node { children: Vec<GreenIdCached>, width: TextWidth },
1632}
1633
1634impl GreenNodeDetailsCached {
1635    fn new(
1636        green_node_details: &GreenNodeDetails,
1637        ctx: &mut DefCacheSavingContext<'_>,
1638    ) -> GreenNodeDetailsCached {
1639        match green_node_details {
1640            GreenNodeDetails::Token(token) => GreenNodeDetailsCached::Token(token.clone()),
1641            GreenNodeDetails::Node { children, width } => GreenNodeDetailsCached::Node {
1642                children: children.iter().map(|child| GreenIdCached::new(*child, ctx)).collect(),
1643                width: *width,
1644            },
1645        }
1646    }
1647    fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> GreenNodeDetails {
1648        match self {
1649            GreenNodeDetailsCached::Token(token) => GreenNodeDetails::Token(token.clone()),
1650            GreenNodeDetailsCached::Node { children, width } => GreenNodeDetails::Node {
1651                children: children.iter().map(|child| child.embed(ctx)).collect(),
1652                width: *width,
1653            },
1654        }
1655    }
1656}
1657
1658#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1659struct GreenNodeCached {
1660    kind: SyntaxKind,
1661    details: GreenNodeDetailsCached,
1662}
1663impl GreenNodeCached {
1664    fn new(green_node: &GreenNode, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1665        Self {
1666            kind: green_node.kind,
1667            details: GreenNodeDetailsCached::new(&green_node.details, ctx),
1668        }
1669    }
1670    fn embed(&self, ctx: &mut DefCacheLoadingContext<'_>) -> GreenNode {
1671        GreenNode { kind: self.kind, details: self.details.embed(ctx) }
1672    }
1673}
1674
1675#[derive(Serialize, Deserialize, Clone, Copy, Eq, Hash, PartialEq)]
1676struct GreenIdCached(usize);
1677
1678impl GreenIdCached {
1679    fn new(green_id: GreenId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1680        if let Some(id) = ctx.green_ids.get(&green_id) {
1681            return *id;
1682        }
1683        let green_node = GreenNodeCached::new(green_id.lookup_intern(ctx.db).as_ref(), ctx);
1684        let id = GreenIdCached(ctx.green_ids_lookup.len());
1685        ctx.green_ids_lookup.push(green_node);
1686        ctx.green_ids.insert(green_id, id);
1687        id
1688    }
1689    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> GreenId {
1690        if let Some(green_id) = ctx.green_ids.get(&self) {
1691            return *green_id;
1692        }
1693        let green_node = ctx.green_ids_lookup[self.0].clone();
1694        let green_node = Arc::new(green_node.embed(ctx));
1695        let green_id = green_node.intern(ctx.db);
1696        ctx.green_ids.insert(self, green_id);
1697        green_id
1698    }
1699}
1700#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1701enum FileCached {
1702    OnDisk(PathBuf),
1703    Virtual(VirtualFileCached),
1704    External(PluginGeneratedFileCached),
1705}
1706
1707impl FileCached {
1708    fn new(file: &FileLongId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1709        match file {
1710            FileLongId::OnDisk(path) => FileCached::OnDisk(path.clone()),
1711            FileLongId::Virtual(virtual_file) => {
1712                FileCached::Virtual(VirtualFileCached::new(virtual_file, ctx))
1713            }
1714            FileLongId::External(external_file) => {
1715                FileCached::External(PluginGeneratedFileCached::new(
1716                    PluginGeneratedFileId::from_intern_id(*external_file),
1717                    ctx,
1718                ))
1719            }
1720        }
1721    }
1722    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> FileLongId {
1723        match self {
1724            FileCached::OnDisk(path) => FileLongId::OnDisk(path),
1725            FileCached::Virtual(virtual_file) => FileLongId::Virtual(virtual_file.embed(ctx)),
1726            FileCached::External(external_file) => {
1727                FileLongId::External(external_file.embed(ctx).as_intern_id())
1728            }
1729        }
1730    }
1731}
1732
1733#[derive(Serialize, Deserialize, Clone, Copy, Eq, Hash, PartialEq)]
1734struct FileIdCached(usize);
1735impl FileIdCached {
1736    fn new(file_id: FileId, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1737        if let Some(id) = ctx.file_ids.get(&file_id) {
1738            return *id;
1739        }
1740        let file = FileCached::new(&file_id.lookup_intern(ctx.db), ctx);
1741        let id = FileIdCached(ctx.file_ids_lookup.len());
1742        ctx.file_ids_lookup.push(file);
1743        ctx.file_ids.insert(file_id, id);
1744        id
1745    }
1746    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> FileId {
1747        if let Some(file_id) = ctx.file_ids.get(&self) {
1748            return *file_id;
1749        }
1750        let file = ctx.file_ids_lookup[self.0].clone();
1751        let file = file.embed(ctx);
1752        let file_id = file.intern(ctx.db);
1753        ctx.file_ids.insert(self, file_id);
1754        file_id
1755    }
1756}
1757
1758#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1759struct VirtualFileCached {
1760    parent: Option<FileIdCached>,
1761    name: SmolStr,
1762    content: String,
1763    code_mappings: Vec<CodeMapping>,
1764    kind: FileKind,
1765    original_item_removed: bool,
1766}
1767
1768impl VirtualFileCached {
1769    fn new(virtual_file: &VirtualFile, ctx: &mut DefCacheSavingContext<'_>) -> Self {
1770        Self {
1771            parent: virtual_file.parent.map(|parent| FileIdCached::new(parent, ctx)),
1772            name: virtual_file.name.clone(),
1773            content: String::from(&*(virtual_file.content)),
1774            code_mappings: virtual_file.code_mappings.to_vec(),
1775            kind: virtual_file.kind.clone(),
1776            original_item_removed: virtual_file.original_item_removed,
1777        }
1778    }
1779    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> VirtualFile {
1780        VirtualFile {
1781            parent: self.parent.map(|parent| parent.embed(ctx)),
1782            name: self.name,
1783            content: self.content.into(),
1784            code_mappings: self.code_mappings.into(),
1785            kind: self.kind,
1786            original_item_removed: self.original_item_removed,
1787        }
1788    }
1789}
1790
1791#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1792struct PluginGeneratedFileCached {
1793    module_id: ModuleIdCached,
1794    stable_ptr: SyntaxStablePtrIdCached,
1795    name: SmolStr,
1796}
1797
1798impl PluginGeneratedFileCached {
1799    fn new(
1800        plugin_generated_file: PluginGeneratedFileId,
1801        ctx: &mut DefCacheSavingContext<'_>,
1802    ) -> Self {
1803        let long_id = plugin_generated_file.lookup_intern(ctx.db);
1804        Self {
1805            module_id: ModuleIdCached::new(long_id.module_id, ctx),
1806            stable_ptr: SyntaxStablePtrIdCached::new(long_id.stable_ptr, ctx),
1807            name: long_id.name,
1808        }
1809    }
1810    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> PluginGeneratedFileId {
1811        let module_id = self.module_id.embed(ctx);
1812        let stable_ptr = self.stable_ptr.embed(ctx);
1813        let long_id = PluginGeneratedFileLongId { module_id, stable_ptr, name: self.name };
1814        long_id.intern(ctx.db)
1815    }
1816}
1817
1818#[derive(Serialize, Deserialize, Clone)]
1819enum SeverityCached {
1820    Error,
1821    Warning,
1822}
1823
1824#[derive(Serialize, Deserialize, Clone)]
1825struct PluginDiagnosticCached {
1826    stable_ptr: SyntaxStablePtrIdCached,
1827    message: String,
1828    severity: SeverityCached,
1829    inner_span: Option<(TextWidth, TextWidth)>,
1830}
1831
1832impl PluginDiagnosticCached {
1833    fn new(
1834        diagnostic: &PluginDiagnostic,
1835        ctx: &mut DefCacheSavingContext<'_>,
1836    ) -> PluginDiagnosticCached {
1837        PluginDiagnosticCached {
1838            stable_ptr: SyntaxStablePtrIdCached::new(diagnostic.stable_ptr, ctx),
1839            message: diagnostic.message.clone(),
1840            severity: match diagnostic.severity {
1841                Severity::Error => SeverityCached::Error,
1842                Severity::Warning => SeverityCached::Warning,
1843            },
1844            inner_span: diagnostic.inner_span,
1845        }
1846    }
1847    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> PluginDiagnostic {
1848        PluginDiagnostic {
1849            stable_ptr: self.stable_ptr.embed(ctx),
1850            message: self.message,
1851            severity: match self.severity {
1852                SeverityCached::Error => Severity::Error,
1853                SeverityCached::Warning => Severity::Warning,
1854            },
1855            inner_span: self.inner_span,
1856        }
1857    }
1858}
1859
1860type PluginFileDiagnosticNotesCached = OrderedHashMap<FileIdCached, DiagnosticNoteCached>;
1861
1862#[derive(Serialize, Deserialize, Clone)]
1863struct DiagnosticNoteCached {
1864    text: String,
1865    location: Option<DiagnosticLocationCached>,
1866}
1867
1868impl DiagnosticNoteCached {
1869    fn new(note: DiagnosticNote, ctx: &mut DefCacheSavingContext<'_>) -> DiagnosticNoteCached {
1870        DiagnosticNoteCached {
1871            text: note.text.clone(),
1872            location: note.location.map(|location| DiagnosticLocationCached::new(&location, ctx)),
1873        }
1874    }
1875    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> DiagnosticNote {
1876        DiagnosticNote {
1877            text: self.text,
1878            location: self.location.map(|location| location.embed(ctx)),
1879        }
1880    }
1881}
1882
1883#[derive(Serialize, Deserialize, Clone)]
1884struct DiagnosticLocationCached {
1885    file_id: FileIdCached,
1886    span: TextSpan,
1887}
1888
1889impl DiagnosticLocationCached {
1890    fn new(
1891        location: &DiagnosticLocation,
1892        ctx: &mut DefCacheSavingContext<'_>,
1893    ) -> DiagnosticLocationCached {
1894        DiagnosticLocationCached {
1895            file_id: FileIdCached::new(location.file_id, ctx),
1896            span: location.span,
1897        }
1898    }
1899    fn embed(self, ctx: &mut DefCacheLoadingContext<'_>) -> DiagnosticLocation {
1900        DiagnosticLocation { file_id: self.file_id.embed(ctx), span: self.span }
1901    }
1902}