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