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