Passed
Push — master ( da4ce9...54c779 )
by Christoffer
02:24
created

NodeBuilder::buildSchemaExtension()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
// TODO: Move this file under the Node namespace
4
5
namespace Digia\GraphQL\Language;
6
7
use Digia\GraphQL\Error\LanguageException;
8
use Digia\GraphQL\Language\Node\ArgumentNode;
9
use Digia\GraphQL\Language\Node\BooleanValueNode;
10
use Digia\GraphQL\Language\Node\DirectiveDefinitionNode;
11
use Digia\GraphQL\Language\Node\DirectiveNode;
12
use Digia\GraphQL\Language\Node\DocumentNode;
13
use Digia\GraphQL\Language\Node\EnumTypeDefinitionNode;
14
use Digia\GraphQL\Language\Node\EnumTypeExtensionNode;
15
use Digia\GraphQL\Language\Node\EnumValueDefinitionNode;
16
use Digia\GraphQL\Language\Node\EnumValueNode;
17
use Digia\GraphQL\Language\Node\FieldDefinitionNode;
18
use Digia\GraphQL\Language\Node\FieldNode;
19
use Digia\GraphQL\Language\Node\FloatValueNode;
20
use Digia\GraphQL\Language\Node\FragmentDefinitionNode;
21
use Digia\GraphQL\Language\Node\FragmentSpreadNode;
22
use Digia\GraphQL\Language\Node\InlineFragmentNode;
23
use Digia\GraphQL\Language\Node\InputObjectTypeDefinitionNode;
24
use Digia\GraphQL\Language\Node\InputObjectTypeExtensionNode;
25
use Digia\GraphQL\Language\Node\InputValueDefinitionNode;
26
use Digia\GraphQL\Language\Node\InterfaceTypeDefinitionNode;
27
use Digia\GraphQL\Language\Node\InterfaceTypeExtensionNode;
28
use Digia\GraphQL\Language\Node\IntValueNode;
29
use Digia\GraphQL\Language\Node\ListTypeNode;
30
use Digia\GraphQL\Language\Node\ListValueNode;
31
use Digia\GraphQL\Language\Node\NamedTypeNode;
32
use Digia\GraphQL\Language\Node\NameNode;
33
use Digia\GraphQL\Language\Node\NodeInterface;
34
use Digia\GraphQL\Language\Node\NodeKindEnum;
35
use Digia\GraphQL\Language\Node\NonNullTypeNode;
36
use Digia\GraphQL\Language\Node\NullValueNode;
37
use Digia\GraphQL\Language\Node\ObjectFieldNode;
38
use Digia\GraphQL\Language\Node\ObjectTypeDefinitionNode;
39
use Digia\GraphQL\Language\Node\ObjectTypeExtensionNode;
40
use Digia\GraphQL\Language\Node\ObjectValueNode;
41
use Digia\GraphQL\Language\Node\OperationDefinitionNode;
42
use Digia\GraphQL\Language\Node\OperationTypeDefinitionNode;
43
use Digia\GraphQL\Language\Node\ScalarTypeDefinitionNode;
44
use Digia\GraphQL\Language\Node\ScalarTypeExtensionNode;
45
use Digia\GraphQL\Language\Node\SchemaDefinitionNode;
46
use Digia\GraphQL\Language\Node\SchemaExtensionNode;
47
use Digia\GraphQL\Language\Node\SelectionSetNode;
48
use Digia\GraphQL\Language\Node\StringValueNode;
49
use Digia\GraphQL\Language\Node\UnionTypeDefinitionNode;
50
use Digia\GraphQL\Language\Node\UnionTypeExtensionNode;
51
use Digia\GraphQL\Language\Node\VariableDefinitionNode;
52
use Digia\GraphQL\Language\Node\VariableNode;
53
54
class NodeBuilder implements NodeBuilderInterface
55
{
56
    /**
57
     * @param array $ast
58
     * @return NodeInterface
59
     * @throws LanguageException
60
     */
61
    public function build(array $ast): NodeInterface
62
    {
63
        if (!isset($ast['kind'])) {
64
            /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
65
            throw new LanguageException(\sprintf('Nodes must specify a kind, got %s', \json_encode($ast)));
66
        }
67
68
        ['kind' => $kind] = $ast;
69
70
        switch ($kind) {
71
            case NodeKindEnum::ARGUMENT:
72
                return $this->buildArgument($ast);
73
            case NodeKindEnum::BOOLEAN:
74
                return $this->buildBoolean($ast);
75
            case NodeKindEnum::DIRECTIVE_DEFINITION:
76
                return $this->buildDirectiveDefinition($ast);
77
            case NodeKindEnum::DIRECTIVE:
78
                return $this->buildDirective($ast);
79
            case NodeKindEnum::DOCUMENT:
80
                return $this->buildDocument($ast);
81
            case NodeKindEnum::ENUM:
82
                return $this->buildEnum($ast);
83
            case NodeKindEnum::ENUM_TYPE_DEFINITION:
84
                return $this->buildEnumTypeDefinition($ast);
85
            case NodeKindEnum::ENUM_TYPE_EXTENSION:
86
                return $this->buildEnumTypeExtension($ast);
87
            case NodeKindEnum::ENUM_VALUE_DEFINITION:
88
                return $this->buildEnumValueDefinition($ast);
89
            case NodeKindEnum::FIELD:
90
                return $this->buildField($ast);
91
            case NodeKindEnum::FIELD_DEFINITION:
92
                return $this->buildFieldDefinition($ast);
93
            case NodeKindEnum::FLOAT:
94
                return $this->buildFloat($ast);
95
            case NodeKindEnum::FRAGMENT_DEFINITION:
96
                return $this->buildFragmentDefinition($ast);
97
            case NodeKindEnum::FRAGMENT_SPREAD:
98
                return $this->buildFragmentSpread($ast);
99
            case NodeKindEnum::INLINE_FRAGMENT:
100
                return $this->buildInlineFragment($ast);
101
            case NodeKindEnum::INPUT_OBJECT_TYPE_DEFINITION:
102
                return $this->buildInputObjectTypeDefinition($ast);
103
            case NodeKindEnum::INPUT_OBJECT_TYPE_EXTENSION:
104
                return $this->buildInputObjectTypeExtension($ast);
105
            case NodeKindEnum::INPUT_VALUE_DEFINITION:
106
                return $this->buildInputValueDefinition($ast);
107
            case NodeKindEnum::INTERFACE_TYPE_DEFINITION:
108
                return $this->buildInterfaceTypeDefinition($ast);
109
            case NodeKindEnum::INTERFACE_TYPE_EXTENSION:
110
                return $this->buildInterfaceTypeExtension($ast);
111
            case NodeKindEnum::INT:
112
                return $this->buildInt($ast);
113
            case NodeKindEnum::LIST_TYPE:
114
                return $this->buildListType($ast);
115
            case NodeKindEnum::LIST:
116
                return $this->buildList($ast);
117
            case NodeKindEnum::NAMED_TYPE:
118
                return $this->buildNamedType($ast);
119
            case NodeKindEnum::NAME:
120
                return $this->buildName($ast);
121
            case NodeKindEnum::NON_NULL_TYPE:
122
                return $this->buildNonNullType($ast);
123
            case NodeKindEnum::NULL:
124
                return $this->buildNull($ast);
125
            case NodeKindEnum::OBJECT_FIELD:
126
                return $this->buildObjectField($ast);
127
            case NodeKindEnum::OBJECT_TYPE_DEFINITION:
128
                return $this->buildObjectTypeDefinition($ast);
129
            case NodeKindEnum::OBJECT_TYPE_EXTENSION:
130
                return $this->buildObjectTypeExtension($ast);
131
            case NodeKindEnum::OBJECT:
132
                return $this->buildObject($ast);
133
            case NodeKindEnum::OPERATION_DEFINITION:
134
                return $this->buildOperationDefinition($ast);
135
            case NodeKindEnum::OPERATION_TYPE_DEFINITION:
136
                return $this->buildOperationTypeDefinition($ast);
137
            case NodeKindEnum::SCALAR_TYPE_DEFINITION:
138
                return $this->buildScalarTypeDefinition($ast);
139
            case NodeKindEnum::SCALAR_TYPE_EXTENSION:
140
                return $this->buildScalarTypeExtension($ast);
141
            case NodeKindEnum::SCHEMA_DEFINITION:
142
                return $this->buildSchemaDefinition($ast);
143
            case NodeKindEnum::SCHEMA_EXTENSION:
144
                return $this->buildSchemaExtension($ast);
145
            case NodeKindEnum::SELECTION_SET:
146
                return $this->buildSelectionSet($ast);
147
            case NodeKindEnum::STRING:
148
                return $this->buildString($ast);
149
            case NodeKindEnum::UNION_TYPE_DEFINITION:
150
                return $this->buildUnionTypeDefinition($ast);
151
            case NodeKindEnum::UNION_TYPE_EXTENSION:
152
                return $this->buildUnionTypeExtension($ast);
153
            case NodeKindEnum::VARIABLE_DEFINITION:
154
                return $this->buildVariableDefinition($ast);
155
            case NodeKindEnum::VARIABLE:
156
                return $this->buildVariable($ast);
157
        }
158
159
        /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
160
        throw new LanguageException(\sprintf('Node of kind "%s" not supported.', $kind));
161
    }
162
163
    /**
164
     * @param array $ast
165
     * @return ArgumentNode
166
     * @throws LanguageException
167
     */
168
    protected function buildArgument(array $ast): ArgumentNode
169
    {
170
        return new ArgumentNode(
171
            $this->buildNode($ast, 'name'),
172
            $this->buildNode($ast, 'value'),
173
            $this->createLocation($ast)
174
        );
175
    }
176
177
    /**
178
     * @param array $ast
179
     * @return BooleanValueNode
180
     */
181
    protected function buildBoolean(array $ast): BooleanValueNode
182
    {
183
        return new BooleanValueNode(
184
            $this->getValue($ast, 'value'),
185
            $this->createLocation($ast)
186
        );
187
    }
188
189
    /**
190
     * @param array $ast
191
     * @return DirectiveDefinitionNode
192
     * @throws LanguageException
193
     */
194
    protected function buildDirectiveDefinition(array $ast): DirectiveDefinitionNode
195
    {
196
        return new DirectiveDefinitionNode(
197
            $this->buildNode($ast, 'description'),
198
            $this->buildNode($ast, 'name'),
199
            $this->buildNodes($ast, 'arguments'),
200
            $this->buildNodes($ast, 'locations'),
201
            $this->createLocation($ast)
202
        );
203
    }
204
205
    /**
206
     * @param array $ast
207
     * @return DirectiveNode
208
     * @throws LanguageException
209
     */
210
    protected function buildDirective(array $ast): DirectiveNode
211
    {
212
        return new DirectiveNode(
213
            $this->buildNode($ast, 'name'),
214
            $this->buildNodes($ast, 'arguments'),
215
            $this->createLocation($ast)
216
        );
217
    }
218
219
    /**
220
     * @param array $ast
221
     * @return DocumentNode
222
     * @throws LanguageException
223
     */
224
    protected function buildDocument(array $ast): DocumentNode
225
    {
226
        return new DocumentNode(
227
            $this->buildNodes($ast, 'definitions'),
228
            $this->createLocation($ast)
229
        );
230
    }
231
232
    /**
233
     * @param array $ast
234
     * @return EnumValueNode
235
     */
236
    protected function buildEnum(array $ast): EnumValueNode
237
    {
238
        return new EnumValueNode(
239
            $this->getValue($ast, 'value'),
240
            $this->createLocation($ast)
241
        );
242
    }
243
244
    /**
245
     * @param array $ast
246
     * @return EnumTypeDefinitionNode
247
     * @throws LanguageException
248
     */
249
    protected function buildEnumTypeDefinition(array $ast): EnumTypeDefinitionNode
250
    {
251
        return new EnumTypeDefinitionNode(
252
            $this->buildNode($ast, 'description'),
253
            $this->buildNode($ast, 'name'),
254
            $this->buildNodes($ast, 'directives'),
255
            $this->buildNodes($ast, 'values'),
256
            $this->createLocation($ast)
257
        );
258
    }
259
260
    /**
261
     * @param array $ast
262
     * @return EnumTypeExtensionNode
263
     * @throws LanguageException
264
     */
265
    protected function buildEnumTypeExtension(array $ast): EnumTypeExtensionNode
266
    {
267
        return new EnumTypeExtensionNode(
268
            $this->buildNode($ast, 'name'),
269
            $this->buildNodes($ast, 'directives'),
270
            $this->buildNodes($ast, 'values'),
271
            $this->createLocation($ast)
272
        );
273
    }
274
275
    /**
276
     * @param array $ast
277
     * @return EnumValueDefinitionNode
278
     * @throws LanguageException
279
     */
280
    protected function buildEnumValueDefinition(array $ast): EnumValueDefinitionNode
281
    {
282
        return new EnumValueDefinitionNode(
283
            $this->buildNode($ast, 'description'),
284
            $this->buildNode($ast, 'name'),
285
            $this->buildNodes($ast, 'directives'),
286
            $this->createLocation($ast)
287
        );
288
    }
289
290
    /**
291
     * @param array $ast
292
     * @return FieldDefinitionNode
293
     * @throws LanguageException
294
     */
295
    protected function buildFieldDefinition(array $ast): FieldDefinitionNode
296
    {
297
        return new FieldDefinitionNode(
298
            $this->buildNode($ast, 'description'),
299
            $this->buildNode($ast, 'name'),
300
            $this->buildNodes($ast, 'arguments'),
301
            $this->buildNode($ast, 'type'),
302
            $this->buildNodes($ast, 'directives'),
303
            $this->createLocation($ast)
304
        );
305
    }
306
307
    /**
308
     * @param array $ast
309
     * @return FieldNode
310
     * @throws LanguageException
311
     */
312
    protected function buildField(array $ast): FieldNode
313
    {
314
        return new FieldNode(
315
            $this->buildNode($ast, 'alias'),
316
            $this->buildNode($ast, 'name'),
317
            $this->buildNodes($ast, 'arguments'),
318
            $this->buildNodes($ast, 'directives'),
319
            $this->buildNode($ast, 'selectionSet'),
320
            $this->createLocation($ast)
321
        );
322
    }
323
324
    /**
325
     * @param array $ast
326
     * @return FloatValueNode
327
     */
328
    protected function buildFloat(array $ast): FloatValueNode
329
    {
330
        return new FloatValueNode(
331
            $this->getValue($ast, 'value'),
332
            $this->createLocation($ast)
333
        );
334
    }
335
336
    /**
337
     * @param array $ast
338
     * @return FragmentDefinitionNode
339
     * @throws LanguageException
340
     */
341
    protected function buildFragmentDefinition(array $ast): FragmentDefinitionNode
342
    {
343
        return new FragmentDefinitionNode(
344
            $this->buildNode($ast, 'name'),
345
            $this->buildNodes($ast, 'variableDefinitions'),
346
            $this->buildNode($ast, 'typeCondition'),
347
            $this->buildNodes($ast, 'directives'),
348
            $this->buildNode($ast, 'selectionSet'),
349
            $this->createLocation($ast)
350
        );
351
    }
352
353
    /**
354
     * @param array $ast
355
     * @return FragmentSpreadNode
356
     * @throws LanguageException
357
     */
358
    protected function buildFragmentSpread(array $ast): FragmentSpreadNode
359
    {
360
        return new FragmentSpreadNode(
361
            $this->buildNode($ast, 'name'),
362
            $this->buildNodes($ast, 'directives'),
363
            $this->buildNode($ast, 'selectionSet'),
364
            $this->createLocation($ast)
365
        );
366
    }
367
368
    /**
369
     * @param array $ast
370
     * @return InlineFragmentNode
371
     * @throws LanguageException
372
     */
373
    protected function buildInlineFragment(array $ast): InlineFragmentNode
374
    {
375
        return new InlineFragmentNode(
376
            $this->buildNode($ast, 'typeCondition'),
377
            $this->buildNodes($ast, 'directives'),
378
            $this->buildNode($ast, 'selectionSet'),
379
            $this->createLocation($ast)
380
        );
381
    }
382
383
    /**
384
     * @param array $ast
385
     * @return InputObjectTypeDefinitionNode
386
     * @throws LanguageException
387
     */
388
    protected function buildInputObjectTypeDefinition(array $ast): InputObjectTypeDefinitionNode
389
    {
390
        return new InputObjectTypeDefinitionNode(
391
            $this->buildNode($ast, 'description'),
392
            $this->buildNode($ast, 'name'),
393
            $this->buildNodes($ast, 'directives'),
394
            $this->buildNodes($ast, 'fields'),
395
            $this->createLocation($ast)
396
        );
397
    }
398
399
    /**
400
     * @param array $ast
401
     * @return InputObjectTypeExtensionNode
402
     * @throws LanguageException
403
     */
404
    protected function buildInputObjectTypeExtension(array $ast): InputObjectTypeExtensionNode
405
    {
406
        return new InputObjectTypeExtensionNode(
407
            $this->buildNode($ast, 'name'),
408
            $this->buildNodes($ast, 'directives'),
409
            $this->buildNodes($ast, 'fields'),
410
            $this->createLocation($ast)
411
        );
412
    }
413
414
    /**
415
     * @param array $ast
416
     * @return InputValueDefinitionNode
417
     * @throws LanguageException
418
     */
419
    protected function buildInputValueDefinition(array $ast): InputValueDefinitionNode
420
    {
421
        return new InputValueDefinitionNode(
422
            $this->buildNode($ast, 'description'),
423
            $this->buildNode($ast, 'name'),
424
            $this->buildNode($ast, 'type'),
425
            $this->buildNode($ast, 'defaultValue'),
426
            $this->buildNodes($ast, 'directives'),
427
            $this->createLocation($ast)
428
        );
429
    }
430
431
    /**
432
     * @param array $ast
433
     * @return InterfaceTypeDefinitionNode
434
     * @throws LanguageException
435
     */
436
    protected function buildInterfaceTypeDefinition(array $ast): InterfaceTypeDefinitionNode
437
    {
438
        return new InterfaceTypeDefinitionNode(
439
            $this->buildNode($ast, 'description'),
440
            $this->buildNode($ast, 'name'),
441
            $this->buildNodes($ast, 'directives'),
442
            $this->buildNodes($ast, 'fields'),
443
            $this->createLocation($ast)
444
        );
445
    }
446
447
    /**
448
     * @param array $ast
449
     * @return InterfaceTypeExtensionNode
450
     * @throws LanguageException
451
     */
452
    protected function buildInterfaceTypeExtension(array $ast): InterfaceTypeExtensionNode
453
    {
454
        return new InterfaceTypeExtensionNode(
455
            $this->buildNode($ast, 'name'),
456
            $this->buildNodes($ast, 'directives'),
457
            $this->buildNodes($ast, 'fields'),
458
            $this->createLocation($ast)
459
        );
460
    }
461
462
    /**
463
     * @param array $ast
464
     * @return IntValueNode
465
     */
466
    protected function buildInt(array $ast): IntValueNode
467
    {
468
        return new IntValueNode(
469
            $this->getValue($ast, 'value'),
470
            $this->createLocation($ast)
471
        );
472
    }
473
474
    /**
475
     * @param array $ast
476
     * @return ListTypeNode
477
     * @throws LanguageException
478
     */
479
    protected function buildListType(array $ast): ListTypeNode
480
    {
481
        return new ListTypeNode(
482
            $this->buildNode($ast, 'type'),
483
            $this->createLocation($ast)
484
        );
485
    }
486
487
    /**
488
     * @param array $ast
489
     * @return ListValueNode
490
     * @throws LanguageException
491
     */
492
    protected function buildList(array $ast): ListValueNode
493
    {
494
        return new ListValueNode(
495
            $this->buildNodes($ast, 'values'),
496
            $this->createLocation($ast)
497
        );
498
    }
499
500
    /**
501
     * @param array $ast
502
     * @return NamedTypeNode
503
     * @throws LanguageException
504
     */
505
    protected function buildNamedType(array $ast): NamedTypeNode
506
    {
507
        return new NamedTypeNode(
508
            $this->buildNode($ast, 'name'),
509
            $this->createLocation($ast)
510
        );
511
    }
512
513
    /**
514
     * @param array $ast
515
     * @return NameNode
516
     */
517
    protected function buildName(array $ast): NameNode
518
    {
519
        return new NameNode(
520
            $this->getValue($ast, 'value'),
521
            $this->createLocation($ast)
522
        );
523
    }
524
525
    /**
526
     * @param array $ast
527
     * @return NonNullTypeNode
528
     * @throws LanguageException
529
     */
530
    protected function buildNonNullType(array $ast): NonNullTypeNode
531
    {
532
        return new NonNullTypeNode(
533
            $this->buildNode($ast, 'type'),
534
            $this->createLocation($ast)
535
        );
536
    }
537
538
    /**
539
     * @param array $ast
540
     * @return NullValueNode
541
     */
542
    protected function buildNull(array $ast): NullValueNode
543
    {
544
        return new NullValueNode($this->createLocation($ast));
545
    }
546
547
    /**
548
     * @param array $ast
549
     * @return ObjectFieldNode
550
     * @throws LanguageException
551
     */
552
    protected function buildObjectField(array $ast): ObjectFieldNode
553
    {
554
        return new ObjectFieldNode(
555
            $this->buildNode($ast, 'name'),
556
            $this->buildNode($ast, 'value'),
557
            $this->createLocation($ast)
558
        );
559
    }
560
561
    /**
562
     * @param array $ast
563
     * @return ObjectTypeDefinitionNode
564
     * @throws LanguageException
565
     */
566
    protected function buildObjectTypeDefinition(array $ast): ObjectTypeDefinitionNode
567
    {
568
        return new ObjectTypeDefinitionNode(
569
            $this->buildNode($ast, 'description'),
570
            $this->buildNode($ast, 'name'),
571
            $this->buildNodes($ast, 'interfaces'),
572
            $this->buildNodes($ast, 'directives'),
573
            $this->buildNodes($ast, 'fields'),
574
            $this->createLocation($ast)
575
        );
576
    }
577
578
    /**
579
     * @param array $ast
580
     * @return ObjectTypeExtensionNode
581
     * @throws LanguageException
582
     */
583
    protected function buildObjectTypeExtension(array $ast): ObjectTypeExtensionNode
584
    {
585
        return new ObjectTypeExtensionNode(
586
            $this->buildNode($ast, 'name'),
587
            $this->buildNodes($ast, 'interfaces'),
588
            $this->buildNodes($ast, 'directives'),
589
            $this->buildNodes($ast, 'fields'),
590
            $this->createLocation($ast)
591
        );
592
    }
593
594
    /**
595
     * @param array $ast
596
     * @return ObjectValueNode
597
     * @throws LanguageException
598
     */
599
    protected function buildObject(array $ast): ObjectValueNode
600
    {
601
        return new ObjectValueNode(
602
            $this->buildNodes($ast, 'fields'),
603
            $this->createLocation($ast)
604
        );
605
    }
606
607
    /**
608
     * @param array $ast
609
     * @return OperationDefinitionNode
610
     * @throws LanguageException
611
     */
612
    protected function buildOperationDefinition(array $ast): OperationDefinitionNode
613
    {
614
        return new OperationDefinitionNode(
615
            $this->getValue($ast, 'operation'),
616
            $this->buildNode($ast, 'name'),
617
            $this->buildNodes($ast, 'variableDefinitions'),
618
            $this->buildNodes($ast, 'directives'),
619
            $this->buildNode($ast, 'selectionSet'),
620
            $this->createLocation($ast)
621
        );
622
    }
623
624
    /**
625
     * @param array $ast
626
     * @return OperationTypeDefinitionNode
627
     * @throws LanguageException
628
     */
629
    protected function buildOperationTypeDefinition(array $ast): OperationTypeDefinitionNode
630
    {
631
        return new OperationTypeDefinitionNode(
632
            $this->getValue($ast, 'operation'),
633
            $this->buildNode($ast, 'type'),
634
            $this->createLocation($ast)
635
        );
636
    }
637
638
    /**
639
     * @param array $ast
640
     * @return ScalarTypeDefinitionNode
641
     * @throws LanguageException
642
     */
643
    protected function buildScalarTypeDefinition(array $ast): ScalarTypeDefinitionNode
644
    {
645
        return new ScalarTypeDefinitionNode(
646
            $this->buildNode($ast, 'description'),
647
            $this->buildNode($ast, 'name'),
648
            $this->buildNodes($ast, 'directives'),
649
            $this->createLocation($ast)
650
        );
651
    }
652
653
    /**
654
     * @param array $ast
655
     * @return ScalarTypeExtensionNode
656
     * @throws LanguageException
657
     */
658
    protected function buildScalarTypeExtension(array $ast): ScalarTypeExtensionNode
659
    {
660
        return new ScalarTypeExtensionNode(
661
            $this->buildNode($ast, 'name'),
662
            $this->buildNodes($ast, 'directives'),
663
            $this->createLocation($ast)
664
        );
665
    }
666
667
    /**
668
     * @param array $ast
669
     * @return SchemaDefinitionNode
670
     * @throws LanguageException
671
     */
672
    protected function buildSchemaDefinition(array $ast): SchemaDefinitionNode
673
    {
674
        return new SchemaDefinitionNode(
675
            $this->buildNodes($ast, 'directives'),
676
            $this->buildNodes($ast, 'operationTypes'),
677
            $this->createLocation($ast)
678
        );
679
    }
680
681
    /**
682
     * @param array $ast
683
     * @return SchemaExtensionNode
684
     * @throws LanguageException
685
     */
686
    protected function buildSchemaExtension(array $ast): SchemaExtensionNode
687
    {
688
        return new SchemaExtensionNode(
689
            $this->buildNodes($ast, 'directives'),
690
            $this->buildNodes($ast, 'operationTypes'),
691
            $this->createLocation($ast)
692
        );
693
    }
694
695
    /**
696
     * @param array $ast
697
     * @return SelectionSetNode
698
     * @throws LanguageException
699
     */
700
    protected function buildSelectionSet(array $ast): SelectionSetNode
701
    {
702
        return new SelectionSetNode(
703
            $this->buildNodes($ast, 'selections'),
704
            $this->createLocation($ast)
705
        );
706
    }
707
708
    /**
709
     * @param array $ast
710
     * @return StringValueNode
711
     */
712
    protected function buildString(array $ast): StringValueNode
713
    {
714
        return new StringValueNode(
715
            $this->getValue($ast, 'value'),
716
            $this->getValue($ast, 'block', false),
717
            $this->createLocation($ast)
718
        );
719
    }
720
721
    /**
722
     * @param array $ast
723
     * @return UnionTypeDefinitionNode
724
     * @throws LanguageException
725
     */
726
    protected function buildUnionTypeDefinition(array $ast): UnionTypeDefinitionNode
727
    {
728
        return new UnionTypeDefinitionNode(
729
            $this->buildNode($ast, 'description'),
730
            $this->buildNode($ast, 'name'),
731
            $this->buildNodes($ast, 'directives'),
732
            $this->buildNodes($ast, 'types'),
733
            $this->createLocation($ast)
734
        );
735
    }
736
737
    /**
738
     * @param array $ast
739
     * @return UnionTypeExtensionNode
740
     * @throws LanguageException
741
     */
742
    protected function buildUnionTypeExtension(array $ast): UnionTypeExtensionNode
743
    {
744
        return new UnionTypeExtensionNode(
745
            $this->buildNode($ast, 'name'),
746
            $this->buildNodes($ast, 'directives'),
747
            $this->buildNodes($ast, 'types'),
748
            $this->createLocation($ast)
749
        );
750
    }
751
752
    /**
753
     * @param array $ast
754
     * @return VariableDefinitionNode
755
     * @throws LanguageException
756
     */
757
    protected function buildVariableDefinition(array $ast): VariableDefinitionNode
758
    {
759
        return new VariableDefinitionNode(
760
            $this->buildNode($ast, 'variable'),
761
            $this->buildNode($ast, 'type'),
762
            $this->buildNode($ast, 'defaultValue'),
763
            $this->createLocation($ast)
764
        );
765
    }
766
767
    /**
768
     * @param array $ast
769
     * @return VariableNode
770
     * @throws LanguageException
771
     */
772
    protected function buildVariable(array $ast): VariableNode
773
    {
774
        return new VariableNode(
775
            $this->buildNode($ast, 'name'),
776
            $this->createLocation($ast)
777
        );
778
    }
779
780
    /**
781
     * Creates a location object.
782
     *
783
     * @param array $ast
784
     * @return Location|null
785
     */
786
    protected function createLocation(array $ast): ?Location
787
    {
788
        return isset($ast['loc']['start'], $ast['loc']['end'])
789
            ? new Location($ast['loc']['start'], $ast['loc']['end'], $ast['loc']['source'] ?? null)
790
            : null;
791
    }
792
793
    /**
794
     * Returns the value of a single property in the given AST.
795
     *
796
     * @param array  $ast
797
     * @param string $propertyName
798
     * @param mixed  $defaultValue
799
     * @return mixed|null
800
     */
801
    protected function getValue(array $ast, string $propertyName, $defaultValue = null)
802
    {
803
        return $ast[$propertyName] ?? $defaultValue;
804
    }
805
806
    /**
807
     * Builds a single item from the given AST.
808
     *
809
     * @param array  $ast
810
     * @param string $propertyName
811
     * @return NodeInterface|null
812
     * @throws LanguageException
813
     */
814
    protected function buildNode(array $ast, string $propertyName): ?NodeInterface
815
    {
816
        return isset($ast[$propertyName]) ? $this->build($ast[$propertyName]) : null;
817
    }
818
819
    /**
820
     * Builds many items from the given AST.
821
     *
822
     * @param array  $ast
823
     * @param string $propertyName
824
     * @return NodeInterface[]
825
     * @throws LanguageException
826
     */
827
    protected function buildNodes(array $ast, string $propertyName): array
828
    {
829
        $array = [];
830
831
        if (isset($ast[$propertyName]) && \is_array($ast[$propertyName])) {
832
            foreach ($ast[$propertyName] as $subAst) {
833
                $array[] = $this->build($subAst);
834
            }
835
        }
836
837
        return $array;
838
    }
839
}
840