Skip to main content

oxc_graphql_parser/
ast.rs

1use crate::Error;
2use crate::LimitTracker;
3use std::fmt;
4use std::slice::Iter;
5
6pub use oxc_allocator::{Box as AstBox, Vec as AstVec};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
9pub struct Span {
10    pub start: usize,
11    pub end: usize,
12}
13
14impl Span {
15    pub fn new(start: usize, end: usize) -> Self {
16        Self { start, end }
17    }
18}
19
20#[derive(Debug, PartialEq)]
21pub struct Ast<'a, T> {
22    source: &'a str,
23    root: T,
24    errors: Vec<Error>,
25    recursion_limit: LimitTracker,
26    token_limit: LimitTracker,
27}
28
29impl<'a, T> Ast<'a, T> {
30    pub(crate) fn new(
31        source: &'a str,
32        root: T,
33        errors: Vec<Error>,
34        recursion_limit: LimitTracker,
35        token_limit: LimitTracker,
36    ) -> Self {
37        Self { source, root, errors, recursion_limit, token_limit }
38    }
39
40    pub fn root(&self) -> &T {
41        &self.root
42    }
43
44    pub fn into_root(self) -> T {
45        self.root
46    }
47
48    pub fn source(&self) -> &str {
49        self.source
50    }
51
52    pub fn errors(&self) -> Iter<'_, Error> {
53        self.errors.iter()
54    }
55
56    pub fn recursion_limit(&self) -> LimitTracker {
57        self.recursion_limit
58    }
59
60    pub fn token_limit(&self) -> LimitTracker {
61        self.token_limit
62    }
63}
64
65impl<'a> Ast<'a, Document<'a>> {
66    pub fn document(&self) -> &Document<'a> {
67        self.root()
68    }
69}
70
71impl<'a> Ast<'a, SelectionSet<'a>> {
72    pub fn field_set(&self) -> &SelectionSet<'a> {
73        self.root()
74    }
75}
76
77impl<'a> Ast<'a, Type<'a>> {
78    pub fn ty(&self) -> &Type<'a> {
79        self.root()
80    }
81}
82
83#[derive(Debug, PartialEq)]
84pub struct Document<'a> {
85    pub definitions: AstVec<'a, Definition<'a>>,
86    pub span: Span,
87}
88
89#[derive(Debug, PartialEq)]
90pub enum Definition<'a> {
91    Operation(OperationDefinition<'a>),
92    Fragment(FragmentDefinition<'a>),
93    Directive(DirectiveDefinition<'a>),
94    Schema(SchemaDefinition<'a>),
95    SchemaExtension(SchemaExtension<'a>),
96    ScalarType(ScalarTypeDefinition<'a>),
97    ScalarTypeExtension(ScalarTypeExtension<'a>),
98    ObjectType(ObjectTypeDefinition<'a>),
99    ObjectTypeExtension(ObjectTypeExtension<'a>),
100    InterfaceType(InterfaceTypeDefinition<'a>),
101    InterfaceTypeExtension(InterfaceTypeExtension<'a>),
102    UnionType(UnionTypeDefinition<'a>),
103    UnionTypeExtension(UnionTypeExtension<'a>),
104    EnumType(EnumTypeDefinition<'a>),
105    EnumTypeExtension(EnumTypeExtension<'a>),
106    InputObjectType(InputObjectTypeDefinition<'a>),
107    InputObjectTypeExtension(InputObjectTypeExtension<'a>),
108}
109
110impl<'a> Definition<'a> {
111    pub fn name(&self) -> Option<&Name<'a>> {
112        match self {
113            Self::Operation(definition) => definition.name.as_ref(),
114            Self::Fragment(definition) => Some(&definition.name),
115            Self::Directive(definition) => Some(&definition.name),
116            Self::Schema(_) | Self::SchemaExtension(_) => None,
117            Self::ScalarType(definition) => Some(&definition.name),
118            Self::ScalarTypeExtension(definition) => Some(&definition.name),
119            Self::ObjectType(definition) => Some(&definition.name),
120            Self::ObjectTypeExtension(definition) => Some(&definition.name),
121            Self::InterfaceType(definition) => Some(&definition.name),
122            Self::InterfaceTypeExtension(definition) => Some(&definition.name),
123            Self::UnionType(definition) => Some(&definition.name),
124            Self::UnionTypeExtension(definition) => Some(&definition.name),
125            Self::EnumType(definition) => Some(&definition.name),
126            Self::EnumTypeExtension(definition) => Some(&definition.name),
127            Self::InputObjectType(definition) => Some(&definition.name),
128            Self::InputObjectTypeExtension(definition) => Some(&definition.name),
129        }
130    }
131}
132
133#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
134pub struct Name<'a> {
135    pub value: &'a str,
136    pub span: Span,
137}
138
139impl Name<'_> {
140    pub fn as_str(&self) -> &str {
141        self.value
142    }
143}
144
145impl fmt::Display for Name<'_> {
146    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147        f.write_str(self.value)
148    }
149}
150
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
152pub struct StringValue<'a> {
153    pub raw: &'a str,
154    pub value: &'a str,
155    pub block: bool,
156    pub span: Span,
157}
158
159#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
160pub enum OperationType {
161    Query,
162    Mutation,
163    Subscription,
164}
165
166#[derive(Debug, PartialEq)]
167pub struct OperationDefinition<'a> {
168    pub description: Option<StringValue<'a>>,
169    pub operation_type: OperationType,
170    pub name: Option<Name<'a>>,
171    pub variable_definitions: AstVec<'a, VariableDefinition<'a>>,
172    pub directives: AstVec<'a, Directive<'a>>,
173    pub selection_set: Option<SelectionSet<'a>>,
174    pub span: Span,
175}
176
177#[derive(Debug, PartialEq)]
178pub struct FragmentDefinition<'a> {
179    pub description: Option<StringValue<'a>>,
180    pub name: Name<'a>,
181    pub variable_definitions: AstVec<'a, VariableDefinition<'a>>,
182    pub type_condition: NamedType<'a>,
183    pub directives: AstVec<'a, Directive<'a>>,
184    pub selection_set: Option<SelectionSet<'a>>,
185    pub span: Span,
186}
187
188#[derive(Debug, PartialEq)]
189pub struct SelectionSet<'a> {
190    pub selections: AstVec<'a, Selection<'a>>,
191    pub span: Span,
192}
193
194#[derive(Debug, PartialEq)]
195pub enum Selection<'a> {
196    Field(Field<'a>),
197    FragmentSpread(FragmentSpread<'a>),
198    InlineFragment(InlineFragment<'a>),
199}
200
201#[derive(Debug, PartialEq)]
202pub struct Field<'a> {
203    pub alias: Option<Name<'a>>,
204    pub name: Name<'a>,
205    pub arguments: AstVec<'a, Argument<'a>>,
206    pub directives: AstVec<'a, Directive<'a>>,
207    pub selection_set: Option<SelectionSet<'a>>,
208    pub span: Span,
209}
210
211#[derive(Debug, PartialEq)]
212pub struct FragmentSpread<'a> {
213    pub name: Name<'a>,
214    pub directives: AstVec<'a, Directive<'a>>,
215    pub span: Span,
216}
217
218#[derive(Debug, PartialEq)]
219pub struct InlineFragment<'a> {
220    pub type_condition: Option<NamedType<'a>>,
221    pub directives: AstVec<'a, Directive<'a>>,
222    pub selection_set: Option<SelectionSet<'a>>,
223    pub span: Span,
224}
225
226#[derive(Debug, PartialEq)]
227pub struct VariableDefinition<'a> {
228    pub description: Option<StringValue<'a>>,
229    pub variable: Variable<'a>,
230    pub ty: Option<Type<'a>>,
231    pub default_value: Option<Value<'a>>,
232    pub directives: AstVec<'a, Directive<'a>>,
233    pub span: Span,
234}
235
236#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
237pub struct Variable<'a> {
238    pub name: Name<'a>,
239    pub span: Span,
240}
241
242#[derive(Debug, PartialEq)]
243pub struct Argument<'a> {
244    pub name: Name<'a>,
245    pub value: Option<Value<'a>>,
246    pub span: Span,
247}
248
249#[derive(Debug, PartialEq)]
250pub struct Directive<'a> {
251    pub name: Name<'a>,
252    pub arguments: AstVec<'a, Argument<'a>>,
253    pub span: Span,
254}
255
256#[derive(Debug, PartialEq)]
257pub enum Value<'a> {
258    Variable(Variable<'a>),
259    Int(IntValue<'a>),
260    Float(FloatValue<'a>),
261    String(StringValue<'a>),
262    Boolean(BooleanValue),
263    Null(NullValue),
264    Enum(EnumValue<'a>),
265    List(ListValue<'a>),
266    Object(ObjectValue<'a>),
267    Missing(Span),
268}
269
270impl Value<'_> {
271    pub fn span(&self) -> Span {
272        match self {
273            Self::Variable(value) => value.span,
274            Self::Int(value) => value.span,
275            Self::Float(value) => value.span,
276            Self::String(value) => value.span,
277            Self::Boolean(value) => value.span,
278            Self::Null(value) => value.span,
279            Self::Enum(value) => value.name.span,
280            Self::List(value) => value.span,
281            Self::Object(value) => value.span,
282            Self::Missing(span) => *span,
283        }
284    }
285}
286
287#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
288pub struct IntValue<'a> {
289    pub raw: &'a str,
290    pub span: Span,
291}
292
293#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
294pub struct FloatValue<'a> {
295    pub raw: &'a str,
296    pub span: Span,
297}
298
299#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
300pub struct BooleanValue {
301    pub value: bool,
302    pub span: Span,
303}
304
305#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
306pub struct NullValue {
307    pub span: Span,
308}
309
310#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
311pub struct EnumValue<'a> {
312    pub name: Name<'a>,
313}
314
315#[derive(Debug, PartialEq)]
316pub struct ListValue<'a> {
317    pub values: AstVec<'a, Value<'a>>,
318    pub span: Span,
319}
320
321#[derive(Debug, PartialEq)]
322pub struct ObjectValue<'a> {
323    pub fields: AstVec<'a, ObjectField<'a>>,
324    pub span: Span,
325}
326
327#[derive(Debug, PartialEq)]
328pub struct ObjectField<'a> {
329    pub name: Name<'a>,
330    pub value: Option<Value<'a>>,
331    pub span: Span,
332}
333
334#[derive(Debug, PartialEq)]
335pub enum Type<'a> {
336    Named(NamedType<'a>),
337    List(ListType<'a>),
338    NonNull(NonNullType<'a>),
339    Missing(Span),
340}
341
342impl Type<'_> {
343    pub fn span(&self) -> Span {
344        match self {
345            Self::Named(value) => value.name.span,
346            Self::List(value) => value.span,
347            Self::NonNull(value) => value.span,
348            Self::Missing(span) => *span,
349        }
350    }
351}
352
353#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
354pub struct NamedType<'a> {
355    pub name: Name<'a>,
356}
357
358#[derive(Debug)]
359pub struct ListType<'a> {
360    pub ty: AstBox<'a, Type<'a>>,
361    pub span: Span,
362}
363
364impl PartialEq for ListType<'_> {
365    fn eq(&self, other: &Self) -> bool {
366        self.ty.as_ref() == other.ty.as_ref() && self.span == other.span
367    }
368}
369
370#[derive(Debug)]
371pub struct NonNullType<'a> {
372    pub ty: AstBox<'a, Type<'a>>,
373    pub span: Span,
374}
375
376impl PartialEq for NonNullType<'_> {
377    fn eq(&self, other: &Self) -> bool {
378        self.ty.as_ref() == other.ty.as_ref() && self.span == other.span
379    }
380}
381
382#[derive(Debug, PartialEq)]
383pub struct SchemaDefinition<'a> {
384    pub description: Option<StringValue<'a>>,
385    pub directives: AstVec<'a, Directive<'a>>,
386    pub root_operations: AstVec<'a, RootOperationTypeDefinition<'a>>,
387    pub span: Span,
388}
389
390#[derive(Debug, PartialEq)]
391pub struct SchemaExtension<'a> {
392    pub directives: AstVec<'a, Directive<'a>>,
393    pub root_operations: AstVec<'a, RootOperationTypeDefinition<'a>>,
394    pub span: Span,
395}
396
397#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
398pub struct RootOperationTypeDefinition<'a> {
399    pub operation_type: OperationType,
400    pub named_type: NamedType<'a>,
401    pub span: Span,
402}
403
404#[derive(Debug, PartialEq)]
405pub struct DirectiveDefinition<'a> {
406    pub description: Option<StringValue<'a>>,
407    pub name: Name<'a>,
408    pub arguments: AstVec<'a, InputValueDefinition<'a>>,
409    pub repeatable: bool,
410    pub locations: AstVec<'a, DirectiveLocation<'a>>,
411    pub span: Span,
412}
413
414#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
415pub struct DirectiveLocation<'a> {
416    pub name: &'a str,
417    pub span: Span,
418}
419
420#[derive(Debug, PartialEq)]
421pub struct ScalarTypeDefinition<'a> {
422    pub description: Option<StringValue<'a>>,
423    pub name: Name<'a>,
424    pub directives: AstVec<'a, Directive<'a>>,
425    pub span: Span,
426}
427
428#[derive(Debug, PartialEq)]
429pub struct ScalarTypeExtension<'a> {
430    pub name: Name<'a>,
431    pub directives: AstVec<'a, Directive<'a>>,
432    pub span: Span,
433}
434
435#[derive(Debug, PartialEq)]
436pub struct ObjectTypeDefinition<'a> {
437    pub description: Option<StringValue<'a>>,
438    pub name: Name<'a>,
439    pub interfaces: AstVec<'a, NamedType<'a>>,
440    pub directives: AstVec<'a, Directive<'a>>,
441    pub fields: AstVec<'a, FieldDefinition<'a>>,
442    pub span: Span,
443}
444
445#[derive(Debug, PartialEq)]
446pub struct ObjectTypeExtension<'a> {
447    pub name: Name<'a>,
448    pub interfaces: AstVec<'a, NamedType<'a>>,
449    pub directives: AstVec<'a, Directive<'a>>,
450    pub fields: AstVec<'a, FieldDefinition<'a>>,
451    pub span: Span,
452}
453
454#[derive(Debug, PartialEq)]
455pub struct InterfaceTypeDefinition<'a> {
456    pub description: Option<StringValue<'a>>,
457    pub name: Name<'a>,
458    pub interfaces: AstVec<'a, NamedType<'a>>,
459    pub directives: AstVec<'a, Directive<'a>>,
460    pub fields: AstVec<'a, FieldDefinition<'a>>,
461    pub span: Span,
462}
463
464#[derive(Debug, PartialEq)]
465pub struct InterfaceTypeExtension<'a> {
466    pub name: Name<'a>,
467    pub interfaces: AstVec<'a, NamedType<'a>>,
468    pub directives: AstVec<'a, Directive<'a>>,
469    pub fields: AstVec<'a, FieldDefinition<'a>>,
470    pub span: Span,
471}
472
473#[derive(Debug, PartialEq)]
474pub struct UnionTypeDefinition<'a> {
475    pub description: Option<StringValue<'a>>,
476    pub name: Name<'a>,
477    pub directives: AstVec<'a, Directive<'a>>,
478    pub members: AstVec<'a, NamedType<'a>>,
479    pub span: Span,
480}
481
482#[derive(Debug, PartialEq)]
483pub struct UnionTypeExtension<'a> {
484    pub name: Name<'a>,
485    pub directives: AstVec<'a, Directive<'a>>,
486    pub members: AstVec<'a, NamedType<'a>>,
487    pub span: Span,
488}
489
490#[derive(Debug, PartialEq)]
491pub struct EnumTypeDefinition<'a> {
492    pub description: Option<StringValue<'a>>,
493    pub name: Name<'a>,
494    pub directives: AstVec<'a, Directive<'a>>,
495    pub values: AstVec<'a, EnumValueDefinition<'a>>,
496    pub span: Span,
497}
498
499#[derive(Debug, PartialEq)]
500pub struct EnumTypeExtension<'a> {
501    pub name: Name<'a>,
502    pub directives: AstVec<'a, Directive<'a>>,
503    pub values: AstVec<'a, EnumValueDefinition<'a>>,
504    pub span: Span,
505}
506
507#[derive(Debug, PartialEq)]
508pub struct EnumValueDefinition<'a> {
509    pub description: Option<StringValue<'a>>,
510    pub value: EnumValue<'a>,
511    pub directives: AstVec<'a, Directive<'a>>,
512    pub span: Span,
513}
514
515#[derive(Debug, PartialEq)]
516pub struct InputObjectTypeDefinition<'a> {
517    pub description: Option<StringValue<'a>>,
518    pub name: Name<'a>,
519    pub directives: AstVec<'a, Directive<'a>>,
520    pub fields: AstVec<'a, InputValueDefinition<'a>>,
521    pub span: Span,
522}
523
524#[derive(Debug, PartialEq)]
525pub struct InputObjectTypeExtension<'a> {
526    pub name: Name<'a>,
527    pub directives: AstVec<'a, Directive<'a>>,
528    pub fields: AstVec<'a, InputValueDefinition<'a>>,
529    pub span: Span,
530}
531
532#[derive(Debug, PartialEq)]
533pub struct FieldDefinition<'a> {
534    pub description: Option<StringValue<'a>>,
535    pub name: Name<'a>,
536    pub arguments: AstVec<'a, InputValueDefinition<'a>>,
537    pub ty: Option<Type<'a>>,
538    pub directives: AstVec<'a, Directive<'a>>,
539    pub span: Span,
540}
541
542#[derive(Debug, PartialEq)]
543pub struct InputValueDefinition<'a> {
544    pub description: Option<StringValue<'a>>,
545    pub name: Name<'a>,
546    pub ty: Option<Type<'a>>,
547    pub default_value: Option<Value<'a>>,
548    pub directives: AstVec<'a, Directive<'a>>,
549    pub span: Span,
550}