1use std::sync::Arc;
2
3use indexmap::IndexSet;
4
5use crate::common::IdRange;
6
7use super::{ExecutableDocument, ids::*, storage::*};
8
9pub struct ExecutableAstWriter {
10 pub values: crate::values::writer::ValueWriter,
11
12 strings: IndexSet<Box<str>>,
13 block_strings: Vec<Box<str>>,
14
15 definitions: Vec<ExecutableDefinitionRecord>,
16 operations: Vec<OperationDefinitionRecord>,
17 fragments: Vec<FragmentDefinitionRecord>,
18
19 selections: Vec<SelectionRecord>,
20 field_selections: Vec<FieldSelectionRecord>,
21 inline_fragments: Vec<InlineFragmentRecord>,
22 fragment_spreads: Vec<FragmentSpreadRecord>,
23
24 directives: Vec<DirectiveRecord>,
25 arguments: Vec<ArgumentRecord>,
26 variables: Vec<VariableDefinitionRecord>,
27 descriptions: Vec<DescriptionRecord>,
28
29 types: Vec<TypeRecord>,
30
31 directive_cursor: DirectiveId,
32 variable_definition_cursor: VariableDefinitionId,
33}
34
35impl Default for ExecutableAstWriter {
36 fn default() -> Self {
37 Self {
38 strings: Default::default(),
39 block_strings: Default::default(),
40 definitions: Default::default(),
41 operations: Default::default(),
42 fragments: Default::default(),
43 selections: Default::default(),
44 field_selections: Default::default(),
45 inline_fragments: Default::default(),
46 fragment_spreads: Default::default(),
47 directives: Default::default(),
48 arguments: Default::default(),
49 variables: Default::default(),
50 descriptions: Default::default(),
51 types: Default::default(),
52 values: Default::default(),
53 directive_cursor: DirectiveId::new(0),
54 variable_definition_cursor: VariableDefinitionId::new(0),
55 }
56 }
57}
58
59impl ExecutableAstWriter {
60 pub fn new() -> Self {
61 Self::default()
62 }
63
64 pub fn finish(self) -> ExecutableDocument {
65 let ExecutableAstWriter {
67 strings,
68 block_strings,
69 definitions,
70 operations,
71 fragments,
72 selections,
73 field_selections,
74 inline_fragments,
75 fragment_spreads,
76 directives,
77 arguments,
78 variables,
79 descriptions,
80 types,
81 values,
82 directive_cursor: _,
83 variable_definition_cursor: _,
84 } = self;
85
86 let strings = Arc::new(strings);
87 let values = values.finish(Arc::clone(&strings));
88
89 ExecutableDocument {
90 strings,
91 block_strings,
92 definitions,
93 operations,
94 fragments,
95 selections,
96 field_selections,
97 inline_fragments,
98 fragment_spreads,
99 directives,
100 arguments,
101 variables,
102 descriptions,
103 types,
104 values,
105 }
106 }
107
108 pub fn operation_definition(
109 &mut self,
110 definition: OperationDefinitionRecord,
111 ) -> ExecutableDefinitionId {
112 let id = OperationDefinitionId::new(self.operations.len());
113 self.operations.push(definition);
114
115 let definition_id = ExecutableDefinitionId::new(self.definitions.len());
116 self.definitions
117 .push(ExecutableDefinitionRecord::Operation(id));
118
119 definition_id
120 }
121
122 pub fn fragment_definition(
123 &mut self,
124 definition: FragmentDefinitionRecord,
125 ) -> ExecutableDefinitionId {
126 let id = FragmentDefinitionId::new(self.fragments.len());
127 self.fragments.push(definition);
128
129 let definition_id = ExecutableDefinitionId::new(self.definitions.len());
130 self.definitions
131 .push(ExecutableDefinitionRecord::Fragment(id));
132
133 definition_id
134 }
135
136 pub fn description(&mut self, description: DescriptionRecord) -> DescriptionId {
137 let id = DescriptionId::new(self.descriptions.len());
138 self.descriptions.push(description);
139 id
140 }
141
142 pub fn variable_definition(
143 &mut self,
144 record: VariableDefinitionRecord,
145 ) -> VariableDefinitionId {
146 let id = VariableDefinitionId::new(self.variables.len());
147 self.variables.push(record);
148 id
149 }
150
151 pub fn variable_definition_range(
152 &mut self,
153 expected_count: Option<usize>,
154 ) -> IdRange<VariableDefinitionId> {
155 let start = self.variable_definition_cursor;
156 let end = VariableDefinitionId::new(self.variables.len());
157 self.variable_definition_cursor = end;
158 let range = IdRange::new(start, end);
159
160 assert_eq!(range.len(), expected_count.unwrap_or_default());
161
162 range
163 }
164
165 pub fn type_reference(&mut self, ty: TypeRecord) -> TypeId {
166 let ty_id = TypeId::new(self.types.len());
167 self.types.push(ty);
168 ty_id
169 }
170
171 pub fn selection_set(
172 &mut self,
173 mut selection_set: Vec<SelectionRecord>,
174 ) -> IdRange<SelectionId> {
175 let start_range = SelectionId::new(self.selections.len());
176 self.selections.append(&mut selection_set);
177 let end_range = SelectionId::new(self.selections.len());
178
179 IdRange::new(start_range, end_range)
180 }
181
182 pub fn field_selection(&mut self, record: FieldSelectionRecord) -> FieldSelectionId {
183 let id = FieldSelectionId::new(self.field_selections.len());
184 self.field_selections.push(record);
185 id
186 }
187
188 pub fn fragment_spread(&mut self, record: FragmentSpreadRecord) -> FragmentSpreadId {
189 let id = FragmentSpreadId::new(self.fragment_spreads.len());
190 self.fragment_spreads.push(record);
191 id
192 }
193
194 pub fn inline_fragment(&mut self, record: InlineFragmentRecord) -> InlineFragmentId {
195 let id = InlineFragmentId::new(self.inline_fragments.len());
196 self.inline_fragments.push(record);
197 id
198 }
199
200 pub fn arguments(&mut self, mut records: Vec<ArgumentRecord>) -> IdRange<ArgumentId> {
201 let start = ArgumentId::new(self.arguments.len());
202 self.arguments.append(&mut records);
203 let end = ArgumentId::new(self.arguments.len());
204
205 IdRange::new(start, end)
206 }
207
208 pub fn directive(&mut self, directive: DirectiveRecord) -> DirectiveId {
209 let id = DirectiveId::new(self.directives.len());
210 self.directives.push(directive);
211 id
212 }
213
214 pub fn directive_range(&mut self, expected_count: Option<usize>) -> IdRange<DirectiveId> {
215 let start = self.directive_cursor;
216 let end = DirectiveId::new(self.directives.len());
217 self.directive_cursor = end;
218 let range = IdRange::new(start, end);
219
220 assert_eq!(range.len(), expected_count.unwrap_or_default());
221
222 range
223 }
224
225 pub fn block_string(&mut self, string: &str) -> BlockStringLiteralId {
226 let literal_id = BlockStringLiteralId::new(self.block_strings.len());
227 self.block_strings.push(string.into());
228
229 literal_id
230 }
231
232 pub fn ident(&mut self, ident: &str) -> StringId {
233 self.intern_string(ident)
234 }
235
236 pub fn intern_string(&mut self, string: &str) -> StringId {
238 let (id, _) = self.strings.insert_full(string.into());
239 StringId::new(id)
240 }
241
242 pub fn intern_owned_string(&mut self, string: String) -> StringId {
244 let (id, _) = self.strings.insert_full(string.into());
245 StringId::new(id)
246 }
247}