cynic_parser/type_system/
writer.rs

1use std::sync::Arc;
2
3use indexmap::IndexSet;
4
5use crate::common::IdRange;
6use crate::values::writer::ValueWriter;
7
8use super::{ids::*, storage::*};
9use super::{DefinitionRecord, TypeSystemDocument};
10
11pub struct TypeSystemAstWriter {
12    pub(crate) values: crate::values::writer::ValueWriter,
13
14    strings: IndexSet<Box<str>>,
15    block_strings: Vec<Box<str>>,
16
17    definitions: Vec<DefinitionRecord>,
18
19    schema_definitions: Vec<SchemaDefinitionRecord>,
20    scalar_definitions: Vec<ScalarDefinitionRecord>,
21    object_definitions: Vec<ObjectDefinitionRecord>,
22    interface_definitions: Vec<InterfaceDefinitionRecord>,
23    union_definitions: Vec<UnionDefinitionRecord>,
24    enum_definitions: Vec<EnumDefinitionRecord>,
25    input_object_definitions: Vec<InputObjectDefinitionRecord>,
26    directive_definitions: Vec<DirectiveDefinitionRecord>,
27
28    root_operation_definitions: Vec<RootOperationTypeDefinitionRecord>,
29
30    field_definitions: Vec<FieldDefinitionRecord>,
31    input_value_definitions: Vec<InputValueDefinitionRecord>,
32    enum_value_definitions: Vec<EnumValueDefinitionRecord>,
33    union_members: Vec<UnionMemberRecord>,
34
35    type_references: Vec<TypeRecord>,
36
37    directives: Vec<DirectiveRecord>,
38    arguments: Vec<ArgumentRecord>,
39    descriptions: Vec<DescriptionRecord>,
40
41    field_id_cursor: FieldDefinitionId,
42    input_value_id_cursor: InputValueDefinitionId,
43    enum_value_id_cursor: EnumValueDefinitionId,
44    directive_id_cursor: DirectiveId,
45    argument_id_cursor: ArgumentId,
46    union_member_id_cursor: UnionMemberId,
47}
48
49// TODO: Don't forget the spans etc.
50impl TypeSystemAstWriter {
51    pub fn new() -> Self {
52        TypeSystemAstWriter {
53            strings: Default::default(),
54            block_strings: Default::default(),
55            definitions: Default::default(),
56            schema_definitions: Default::default(),
57            scalar_definitions: Default::default(),
58            object_definitions: Default::default(),
59            interface_definitions: Default::default(),
60            union_definitions: Default::default(),
61            enum_definitions: Default::default(),
62            input_object_definitions: Default::default(),
63            directive_definitions: Default::default(),
64            root_operation_definitions: Default::default(),
65            field_definitions: Default::default(),
66            input_value_definitions: Default::default(),
67            enum_value_definitions: Default::default(),
68            union_members: Default::default(),
69            type_references: Default::default(),
70            directives: Default::default(),
71            arguments: Default::default(),
72            descriptions: Default::default(),
73
74            values: Default::default(),
75
76            field_id_cursor: FieldDefinitionId::new(0),
77            input_value_id_cursor: InputValueDefinitionId::new(0),
78            enum_value_id_cursor: EnumValueDefinitionId::new(0),
79            directive_id_cursor: DirectiveId::new(0),
80            argument_id_cursor: ArgumentId::new(0),
81            union_member_id_cursor: UnionMemberId::new(0),
82        }
83    }
84
85    pub fn update(ast: TypeSystemDocument) -> Self {
86        let TypeSystemDocument {
87            strings,
88            block_strings,
89            definitions,
90            schema_definitions,
91            scalar_definitions,
92            object_definitions,
93            interface_definitions,
94            union_definitions,
95            enum_definitions,
96            input_object_definitions,
97            directive_definitions,
98            root_operation_definitions,
99            field_definitions,
100            input_value_definitions,
101            enum_value_definitions,
102            union_members,
103            type_references,
104            directives,
105            arguments,
106            descriptions,
107            values,
108        } = ast;
109
110        let values = ValueWriter::update(values);
111        let strings = Arc::unwrap_or_clone(strings);
112
113        TypeSystemAstWriter {
114            field_id_cursor: FieldDefinitionId::new(field_definitions.len()),
115            input_value_id_cursor: InputValueDefinitionId::new(input_value_definitions.len()),
116            directive_id_cursor: DirectiveId::new(directives.len()),
117            enum_value_id_cursor: EnumValueDefinitionId::new(enum_value_definitions.len()),
118            argument_id_cursor: ArgumentId::new(arguments.len()),
119            union_member_id_cursor: UnionMemberId::new(union_members.len()),
120
121            strings,
122            block_strings,
123            definitions,
124            schema_definitions,
125            scalar_definitions,
126            object_definitions,
127            interface_definitions,
128            union_definitions,
129            enum_definitions,
130            input_object_definitions,
131            directive_definitions,
132            root_operation_definitions,
133            field_definitions,
134            input_value_definitions,
135            enum_value_definitions,
136            union_members,
137            type_references,
138            directives,
139            arguments,
140            descriptions,
141
142            values,
143        }
144    }
145
146    pub fn finish(self) -> TypeSystemDocument {
147        // TODO: Possibly assert things in here for safety...
148        let Self {
149            strings,
150            block_strings,
151            definitions,
152            schema_definitions,
153            scalar_definitions,
154            object_definitions,
155            interface_definitions,
156            union_definitions,
157            enum_definitions,
158            input_object_definitions,
159            directive_definitions,
160            root_operation_definitions,
161            field_definitions,
162            input_value_definitions,
163            enum_value_definitions,
164            union_members,
165            type_references,
166            directives,
167            arguments,
168            descriptions,
169
170            values,
171
172            field_id_cursor: _,
173            input_value_id_cursor: _,
174            enum_value_id_cursor: _,
175            directive_id_cursor: _,
176            argument_id_cursor: _,
177            union_member_id_cursor: _,
178        } = self;
179
180        let strings = Arc::new(strings);
181        let values = values.finish(Arc::clone(&strings));
182
183        TypeSystemDocument {
184            strings,
185            block_strings,
186            definitions,
187            schema_definitions,
188            scalar_definitions,
189            object_definitions,
190            interface_definitions,
191            union_definitions,
192            enum_definitions,
193            input_object_definitions,
194            directive_definitions,
195            root_operation_definitions,
196            field_definitions,
197            input_value_definitions,
198            enum_value_definitions,
199            union_members,
200            type_references,
201            directives,
202            arguments,
203            descriptions,
204            values,
205        }
206    }
207
208    pub fn store_description(
209        &mut self,
210        definition: DefinitionId,
211        description: Option<DescriptionId>,
212    ) {
213        if let Some(description) = description {
214            match self.definitions[definition.get()] {
215                DefinitionRecord::Schema(id) | DefinitionRecord::SchemaExtension(id) => {
216                    self.schema_definitions[id.get()].description = Some(description);
217                }
218                DefinitionRecord::Scalar(id) | DefinitionRecord::ScalarExtension(id) => {
219                    self.scalar_definitions[id.get()].description = Some(description);
220                }
221                DefinitionRecord::Object(id) | DefinitionRecord::ObjectExtension(id) => {
222                    self.object_definitions[id.get()].description = Some(description);
223                }
224                DefinitionRecord::Interface(id) | DefinitionRecord::InterfaceExtension(id) => {
225                    self.interface_definitions[id.get()].description = Some(description);
226                }
227                DefinitionRecord::Union(id) | DefinitionRecord::UnionExtension(id) => {
228                    self.union_definitions[id.get()].description = Some(description);
229                }
230                DefinitionRecord::Enum(id) | DefinitionRecord::EnumExtension(id) => {
231                    self.enum_definitions[id.get()].description = Some(description);
232                }
233                DefinitionRecord::InputObject(id) | DefinitionRecord::InputObjectExtension(id) => {
234                    self.input_object_definitions[id.get()].description = Some(description);
235                }
236                DefinitionRecord::Directive(id) => {
237                    self.directive_definitions[id.get()].description = Some(description);
238                }
239            }
240        }
241    }
242
243    pub fn description(&mut self, description: DescriptionRecord) -> DescriptionId {
244        let id = DescriptionId::new(self.descriptions.len());
245        self.descriptions.push(description);
246        id
247    }
248
249    pub fn schema_definition(&mut self, definition: SchemaDefinitionRecord) -> DefinitionId {
250        let id = SchemaDefinitionId::new(self.schema_definitions.len());
251        self.schema_definitions.push(definition);
252
253        let definition_id = DefinitionId::new(self.definitions.len());
254        self.definitions.push(DefinitionRecord::Schema(id));
255
256        definition_id
257    }
258
259    pub fn root_operation_definitions(
260        &mut self,
261        definitions: Vec<RootOperationTypeDefinitionRecord>,
262    ) -> IdRange<RootOperationTypeDefinitionId> {
263        let start_id = RootOperationTypeDefinitionId::new(self.root_operation_definitions.len());
264
265        self.root_operation_definitions.extend(definitions);
266        let end_id = RootOperationTypeDefinitionId::new(self.root_operation_definitions.len());
267
268        IdRange::new(start_id, end_id)
269    }
270
271    pub fn scalar_definition(&mut self, definition: ScalarDefinitionRecord) -> DefinitionId {
272        let id = ScalarDefinitionId::new(self.scalar_definitions.len());
273        self.scalar_definitions.push(definition);
274
275        let definition_id = DefinitionId::new(self.definitions.len());
276        self.definitions.push(DefinitionRecord::Scalar(id));
277
278        definition_id
279    }
280
281    pub fn object_definition(&mut self, definition: ObjectDefinitionRecord) -> DefinitionId {
282        // TODO: Maybe assert in here too?
283
284        let id = ObjectDefinitionId::new(self.object_definitions.len());
285        self.object_definitions.push(definition);
286
287        let definition_id = DefinitionId::new(self.definitions.len());
288        self.definitions.push(DefinitionRecord::Object(id));
289
290        definition_id
291    }
292
293    pub fn field_definition(&mut self, definition: FieldDefinitionRecord) -> FieldDefinitionId {
294        let definition_id = FieldDefinitionId::new(self.field_definitions.len());
295        self.field_definitions.push(definition);
296
297        definition_id
298    }
299
300    pub fn field_definition_range(
301        &mut self,
302        expected_count: Option<usize>,
303    ) -> IdRange<FieldDefinitionId> {
304        let start = self.field_id_cursor;
305        let end = FieldDefinitionId::new(self.field_definitions.len());
306        self.field_id_cursor = end;
307        let range = IdRange::new(start, end);
308
309        if let Some(expected_count) = expected_count {
310            assert_eq!(range.len(), expected_count);
311        }
312
313        range
314    }
315
316    pub fn interface_definition(&mut self, definition: InterfaceDefinitionRecord) -> DefinitionId {
317        let id = InterfaceDefinitionId::new(self.interface_definitions.len());
318        self.interface_definitions.push(definition);
319
320        let definition_id = DefinitionId::new(self.definitions.len());
321        self.definitions.push(DefinitionRecord::Interface(id));
322
323        definition_id
324    }
325
326    pub fn union_definition(&mut self, definition: UnionDefinitionRecord) -> DefinitionId {
327        let id = UnionDefinitionId::new(self.union_definitions.len());
328        self.union_definitions.push(definition);
329
330        let definition_id = DefinitionId::new(self.definitions.len());
331        self.definitions.push(DefinitionRecord::Union(id));
332
333        definition_id
334    }
335
336    pub fn enum_definition(&mut self, definition: EnumDefinitionRecord) -> DefinitionId {
337        let id = EnumDefinitionId::new(self.enum_definitions.len());
338        self.enum_definitions.push(definition);
339
340        let definition_id = DefinitionId::new(self.definitions.len());
341        self.definitions.push(DefinitionRecord::Enum(id));
342
343        definition_id
344    }
345
346    pub fn enum_value_definition(
347        &mut self,
348        definition: EnumValueDefinitionRecord,
349    ) -> EnumValueDefinitionId {
350        let id = EnumValueDefinitionId::new(self.enum_value_definitions.len());
351        self.enum_value_definitions.push(definition);
352
353        id
354    }
355
356    pub fn enum_value_definition_range(
357        &mut self,
358        expected_count: Option<usize>,
359    ) -> IdRange<EnumValueDefinitionId> {
360        let start = self.enum_value_id_cursor;
361        let end = EnumValueDefinitionId::new(self.enum_value_definitions.len());
362        self.enum_value_id_cursor = end;
363        let range = IdRange::new(start, end);
364
365        assert_eq!(range.len(), expected_count.unwrap_or_default());
366
367        range
368    }
369
370    pub fn input_object_definition(
371        &mut self,
372        definition: InputObjectDefinitionRecord,
373    ) -> DefinitionId {
374        let id = InputObjectDefinitionId::new(self.input_object_definitions.len());
375        self.input_object_definitions.push(definition);
376
377        let definition_id = DefinitionId::new(self.definitions.len());
378        self.definitions.push(DefinitionRecord::InputObject(id));
379
380        definition_id
381    }
382
383    pub fn input_value_definition(
384        &mut self,
385        definition: InputValueDefinitionRecord,
386    ) -> InputValueDefinitionId {
387        let definition_id = InputValueDefinitionId::new(self.input_value_definitions.len());
388        self.input_value_definitions.push(definition);
389
390        definition_id
391    }
392
393    pub fn input_value_definition_range(
394        &mut self,
395        expected_count: Option<usize>,
396    ) -> IdRange<InputValueDefinitionId> {
397        let start = self.input_value_id_cursor;
398        let end = InputValueDefinitionId::new(self.input_value_definitions.len());
399        self.input_value_id_cursor = end;
400        let range = IdRange::new(start, end);
401
402        assert_eq!(range.len(), expected_count.unwrap_or_default());
403
404        range
405    }
406
407    pub fn schema_extension(&mut self, definition: SchemaDefinitionRecord) -> DefinitionId {
408        let id = SchemaDefinitionId::new(self.schema_definitions.len());
409        self.schema_definitions.push(definition);
410
411        let definition_id = DefinitionId::new(self.definitions.len());
412        self.definitions.push(DefinitionRecord::SchemaExtension(id));
413
414        definition_id
415    }
416
417    pub fn scalar_extension(&mut self, definition: ScalarDefinitionRecord) -> DefinitionId {
418        let id = ScalarDefinitionId::new(self.scalar_definitions.len());
419        self.scalar_definitions.push(definition);
420
421        let definition_id = DefinitionId::new(self.definitions.len());
422        self.definitions.push(DefinitionRecord::ScalarExtension(id));
423
424        definition_id
425    }
426
427    pub fn object_extension(&mut self, definition: ObjectDefinitionRecord) -> DefinitionId {
428        let id = ObjectDefinitionId::new(self.object_definitions.len());
429        self.object_definitions.push(definition);
430
431        let definition_id = DefinitionId::new(self.definitions.len());
432        self.definitions.push(DefinitionRecord::ObjectExtension(id));
433
434        definition_id
435    }
436
437    pub fn interface_extension(&mut self, definition: InterfaceDefinitionRecord) -> DefinitionId {
438        let id = InterfaceDefinitionId::new(self.interface_definitions.len());
439        self.interface_definitions.push(definition);
440
441        let definition_id = DefinitionId::new(self.definitions.len());
442        self.definitions
443            .push(DefinitionRecord::InterfaceExtension(id));
444
445        definition_id
446    }
447
448    pub fn union_member(&mut self, member: UnionMemberRecord) -> UnionMemberId {
449        let id = UnionMemberId::new(self.union_members.len());
450        self.union_members.push(member);
451        id
452    }
453
454    pub fn union_member_range(&mut self, expected_count: Option<usize>) -> IdRange<UnionMemberId> {
455        let start = self.union_member_id_cursor;
456        let end = UnionMemberId::new(self.union_members.len());
457        self.union_member_id_cursor = end;
458        let range = IdRange::new(start, end);
459
460        assert_eq!(range.len(), expected_count.unwrap_or_default());
461
462        range
463    }
464
465    pub fn union_extension(&mut self, definition: UnionDefinitionRecord) -> DefinitionId {
466        let id = UnionDefinitionId::new(self.union_definitions.len());
467        self.union_definitions.push(definition);
468
469        let definition_id = DefinitionId::new(self.definitions.len());
470        self.definitions.push(DefinitionRecord::UnionExtension(id));
471
472        definition_id
473    }
474
475    pub fn enum_extension(&mut self, definition: EnumDefinitionRecord) -> DefinitionId {
476        let id = EnumDefinitionId::new(self.enum_definitions.len());
477        self.enum_definitions.push(definition);
478
479        let definition_id = DefinitionId::new(self.definitions.len());
480        self.definitions.push(DefinitionRecord::EnumExtension(id));
481
482        definition_id
483    }
484
485    pub fn input_object_extension(
486        &mut self,
487        definition: InputObjectDefinitionRecord,
488    ) -> DefinitionId {
489        let id = InputObjectDefinitionId::new(self.input_object_definitions.len());
490        self.input_object_definitions.push(definition);
491
492        let definition_id = DefinitionId::new(self.definitions.len());
493        self.definitions
494            .push(DefinitionRecord::InputObjectExtension(id));
495
496        definition_id
497    }
498
499    pub fn directive_definition(&mut self, definition: DirectiveDefinitionRecord) -> DefinitionId {
500        let id = DirectiveDefinitionId::new(self.directive_definitions.len());
501        self.directive_definitions.push(definition);
502
503        let definition_id = DefinitionId::new(self.definitions.len());
504        self.definitions.push(DefinitionRecord::Directive(id));
505
506        definition_id
507    }
508
509    pub fn directive_range(&mut self, expected_count: Option<usize>) -> IdRange<DirectiveId> {
510        let start = self.directive_id_cursor;
511        let end = DirectiveId::new(self.directives.len());
512        self.directive_id_cursor = end;
513        let range = IdRange::new(start, end);
514
515        assert_eq!(range.len(), expected_count.unwrap_or_default());
516
517        range
518    }
519
520    pub fn type_reference(&mut self, ty: TypeRecord) -> TypeId {
521        let ty_id = TypeId::new(self.type_references.len());
522        self.type_references.push(ty);
523        ty_id
524    }
525
526    pub fn directive(&mut self, directive: DirectiveRecord) -> DirectiveId {
527        let id = DirectiveId::new(self.directives.len());
528        self.directives.push(directive);
529        id
530    }
531
532    pub fn argument(&mut self, argument: ArgumentRecord) -> ArgumentId {
533        let id = ArgumentId::new(self.arguments.len());
534        self.arguments.push(argument);
535        id
536    }
537
538    pub fn argument_range(&mut self, expected_count: Option<usize>) -> IdRange<ArgumentId> {
539        let start = self.argument_id_cursor;
540        let end = ArgumentId::new(self.arguments.len());
541        self.argument_id_cursor = end;
542        let range = IdRange::new(start, end);
543
544        assert_eq!(range.len(), expected_count.unwrap_or_default());
545
546        range
547    }
548
549    pub fn block_string(&mut self, string: &str) -> BlockStringLiteralId {
550        let literal_id = BlockStringLiteralId::new(self.block_strings.len());
551        self.block_strings.push(string.into());
552
553        literal_id
554    }
555
556    pub fn ident(&mut self, ident: &str) -> StringId {
557        self.intern_string(ident)
558    }
559
560    // TOOD: should this be pub? not sure...
561    pub fn intern_string(&mut self, string: &str) -> StringId {
562        let (id, _) = self.strings.insert_full(string.into());
563        StringId::new(id)
564    }
565
566    // TOOD: should this be pub? not sure...
567    pub fn intern_owned_string(&mut self, string: String) -> StringId {
568        let (id, _) = self.strings.insert_full(string.into());
569        StringId::new(id)
570    }
571}
572
573impl Default for TypeSystemAstWriter {
574    fn default() -> Self {
575        Self::new()
576    }
577}