@@ -173,24 +173,45 @@ func parseDefinition(lexer: Lexer) throws -> Definition {
173
173
return try parseOperationDefinition ( lexer: lexer)
174
174
}
175
175
176
- if peek ( lexer: lexer, kind: . name) {
177
- guard let value = lexer. token. value else {
176
+ // Many definitions begin with a description and require a lookahead.
177
+ let hasDescription = peekDescription ( lexer: lexer)
178
+ let keywordToken = hasDescription
179
+ ? try lexer. lookahead ( )
180
+ : lexer. token
181
+
182
+ if keywordToken. kind == . name {
183
+ guard let value = keywordToken. value else {
178
184
throw GraphQLError ( message: " Expected name token to have value: \( lexer. token) " )
179
185
}
186
+
180
187
switch value {
181
- case " query " , " mutation " , " subscription " :
182
- return try parseOperationDefinition ( lexer: lexer)
183
- case " fragment " :
184
- return try parseFragmentDefinition ( lexer: lexer)
185
- // Note: the Type System IDL is an experimental non-spec addition.
186
- case " schema " , " scalar " , " type " , " interface " , " union " , " enum " , " input " , " extend " ,
187
- " directive " :
188
- return try parseTypeSystemDefinition ( lexer: lexer)
188
+ case " schema " : return try parseSchemaDefinition ( lexer : lexer )
189
+ case " scalar " : return try parseScalarTypeDefinition ( lexer: lexer)
190
+ case " type " : return try parseObjectTypeDefinition ( lexer : lexer )
191
+ case " interface " : return try parseInterfaceTypeDefinition ( lexer: lexer)
192
+ case " union " : return try parseUnionTypeDefinition ( lexer : lexer )
193
+ case " enum " : return try parseEnumTypeDefinition ( lexer : lexer )
194
+ case " input " : return try parseInputObjectTypeDefinition ( lexer : lexer )
195
+ case " directive " : return try parseDirectiveDefinition ( lexer: lexer)
189
196
default :
190
- break
197
+ if hasDescription {
198
+ throw syntaxError (
199
+ source: lexer. source,
200
+ position: lexer. token. start,
201
+ description: " Unexpected description, descriptions are supported only on type definitions. "
202
+ )
203
+ }
204
+ switch value {
205
+ case " query " , " mutation " , " subscription " :
206
+ return try parseOperationDefinition ( lexer: lexer)
207
+ case " fragment " :
208
+ return try parseFragmentDefinition ( lexer: lexer)
209
+ case " extend " :
210
+ return try parseExtensionDefinition ( lexer: lexer)
211
+ default :
212
+ break
213
+ }
191
214
}
192
- } else if peekDescription ( lexer: lexer) {
193
- return try parseTypeSystemDefinition ( lexer: lexer)
194
215
}
195
216
196
217
throw unexpected ( lexer: lexer)
@@ -675,47 +696,6 @@ func parseNamedType(lexer: Lexer) throws -> NamedType {
675
696
676
697
// Implements the parsing rules in the Type Definition section.
677
698
678
- /**
679
- * TypeSystemDefinition :
680
- * - SchemaDefinition
681
- * - TypeDefinition
682
- * - TypeExtensionDefinition
683
- * - DirectiveDefinition
684
- *
685
- * TypeDefinition :
686
- * - ScalarTypeDefinition
687
- * - ObjectTypeDefinition
688
- * - InterfaceTypeDefinition
689
- * - UnionTypeDefinition
690
- * - EnumTypeDefinition
691
- * - InputObjectTypeDefinition
692
- */
693
- func parseTypeSystemDefinition( lexer: Lexer ) throws -> TypeSystemDefinition {
694
- let keywordToken = peekDescription ( lexer: lexer)
695
- ? try lexer. lookahead ( )
696
- : lexer. token
697
-
698
- if keywordToken. kind == . name {
699
- guard let value = keywordToken. value else {
700
- throw GraphQLError ( message: " Expected keyword token to have value: \( keywordToken) " )
701
- }
702
- switch value {
703
- case " schema " : return try parseSchemaDefinition ( lexer: lexer)
704
- case " scalar " : return try parseScalarTypeDefinition ( lexer: lexer)
705
- case " type " : return try parseObjectTypeDefinition ( lexer: lexer)
706
- case " interface " : return try parseInterfaceTypeDefinition ( lexer: lexer)
707
- case " union " : return try parseUnionTypeDefinition ( lexer: lexer)
708
- case " enum " : return try parseEnumTypeDefinition ( lexer: lexer)
709
- case " input " : return try parseInputObjectTypeDefinition ( lexer: lexer)
710
- case " extend " : return try parseExtensionDefinition ( lexer: lexer)
711
- case " directive " : return try parseDirectiveDefinition ( lexer: lexer)
712
- default : break
713
- }
714
- }
715
-
716
- throw unexpected ( lexer: lexer, atToken: keywordToken)
717
- }
718
-
719
699
/**
720
700
* SchemaDefinition : schema Directives? { OperationTypeDefinition+ }
721
701
*
@@ -1025,10 +1005,31 @@ func parseExtensionDefinition(lexer: Lexer) throws -> TypeSystemDefinition {
1025
1005
func parseTypeExtensionDefinition( lexer: Lexer ) throws -> TypeExtensionDefinition {
1026
1006
let start = lexer. token
1027
1007
try expectKeyword ( lexer: lexer, value: " extend " )
1028
- let definition = try parseObjectTypeDefinition ( lexer: lexer)
1008
+ try expectKeyword ( lexer: lexer, value: " type " )
1009
+ let name = try parseName ( lexer: lexer)
1010
+ let interfaces = try parseImplementsInterfaces ( lexer: lexer)
1011
+ let directives = try parseDirectives ( lexer: lexer)
1012
+ let fields = try optionalMany (
1013
+ lexer: lexer,
1014
+ openKind: . openingBrace,
1015
+ closeKind: . closingBrace,
1016
+ parse: parseFieldDefinition
1017
+ )
1018
+ if
1019
+ interfaces. isEmpty,
1020
+ directives. isEmpty,
1021
+ fields. isEmpty
1022
+ {
1023
+ throw unexpected ( lexer: lexer)
1024
+ }
1029
1025
return TypeExtensionDefinition (
1030
1026
loc: loc ( lexer: lexer, startToken: start) ,
1031
- definition: definition
1027
+ definition: ObjectTypeDefinition (
1028
+ name: name,
1029
+ interfaces: interfaces,
1030
+ directives: directives,
1031
+ fields: fields
1032
+ )
1032
1033
)
1033
1034
}
1034
1035
@@ -1038,16 +1039,24 @@ func parseTypeExtensionDefinition(lexer: Lexer) throws -> TypeExtensionDefinitio
1038
1039
func parseSchemaExtensionDefinition( lexer: Lexer ) throws -> SchemaExtensionDefinition {
1039
1040
let start = lexer. token
1040
1041
try expectKeyword ( lexer: lexer, value: " extend " )
1041
- let description = try parseDescription ( lexer: lexer)
1042
1042
try expectKeyword ( lexer: lexer, value: " schema " )
1043
1043
let directives = try parseDirectives ( lexer: lexer)
1044
+ let operationTypes = try optionalMany (
1045
+ lexer: lexer,
1046
+ openKind: . openingBrace,
1047
+ closeKind: . closingBrace,
1048
+ parse: parseOperationTypeDefinition
1049
+ )
1050
+ if directives. isEmpty, operationTypes. isEmpty {
1051
+ throw unexpected ( lexer: lexer)
1052
+ }
1044
1053
return SchemaExtensionDefinition (
1045
1054
loc: loc ( lexer: lexer, startToken: start) ,
1046
1055
definition: SchemaDefinition (
1047
1056
loc: loc ( lexer: lexer, startToken: start) ,
1048
- description: description ,
1057
+ description: nil ,
1049
1058
directives: directives,
1050
- operationTypes: [ ]
1059
+ operationTypes: operationTypes
1051
1060
)
1052
1061
)
1053
1062
}
@@ -1058,10 +1067,31 @@ func parseSchemaExtensionDefinition(lexer: Lexer) throws -> SchemaExtensionDefin
1058
1067
func parseInterfaceExtensionDefinition( lexer: Lexer ) throws -> InterfaceExtensionDefinition {
1059
1068
let start = lexer. token
1060
1069
try expectKeyword ( lexer: lexer, value: " extend " )
1061
- let interfaceDefinition = try parseInterfaceTypeDefinition ( lexer: lexer)
1070
+ try expectKeyword ( lexer: lexer, value: " interface " )
1071
+ let name = try parseName ( lexer: lexer)
1072
+ let interfaces = try parseImplementsInterfaces ( lexer: lexer)
1073
+ let directives = try parseDirectives ( lexer: lexer)
1074
+ let fields = try optionalMany (
1075
+ lexer: lexer,
1076
+ openKind: . openingBrace,
1077
+ closeKind: . closingBrace,
1078
+ parse: parseFieldDefinition
1079
+ )
1080
+ if
1081
+ interfaces. isEmpty,
1082
+ directives. isEmpty,
1083
+ fields. isEmpty
1084
+ {
1085
+ throw unexpected ( lexer: lexer)
1086
+ }
1062
1087
return InterfaceExtensionDefinition (
1063
1088
loc: loc ( lexer: lexer, startToken: start) ,
1064
- definition: interfaceDefinition
1089
+ definition: InterfaceTypeDefinition (
1090
+ name: name,
1091
+ interfaces: interfaces,
1092
+ directives: directives,
1093
+ fields: fields
1094
+ )
1065
1095
)
1066
1096
}
1067
1097
@@ -1071,10 +1101,18 @@ func parseInterfaceExtensionDefinition(lexer: Lexer) throws -> InterfaceExtensio
1071
1101
func parseScalarExtensionDefinition( lexer: Lexer ) throws -> ScalarExtensionDefinition {
1072
1102
let start = lexer. token
1073
1103
try expectKeyword ( lexer: lexer, value: " extend " )
1074
- let scalarDefinition = try parseScalarTypeDefinition ( lexer: lexer)
1104
+ try expectKeyword ( lexer: lexer, value: " scalar " )
1105
+ let name = try parseName ( lexer: lexer)
1106
+ let directives = try parseDirectives ( lexer: lexer)
1107
+ if directives. isEmpty {
1108
+ throw unexpected ( lexer: lexer)
1109
+ }
1075
1110
return ScalarExtensionDefinition (
1076
1111
loc: loc ( lexer: lexer, startToken: start) ,
1077
- definition: scalarDefinition
1112
+ definition: ScalarTypeDefinition (
1113
+ name: name,
1114
+ directives: directives
1115
+ )
1078
1116
)
1079
1117
}
1080
1118
@@ -1084,10 +1122,24 @@ func parseScalarExtensionDefinition(lexer: Lexer) throws -> ScalarExtensionDefin
1084
1122
func parseUnionExtensionDefinition( lexer: Lexer ) throws -> UnionExtensionDefinition {
1085
1123
let start = lexer. token
1086
1124
try expectKeyword ( lexer: lexer, value: " extend " )
1087
- let definition = try parseUnionTypeDefinition ( lexer: lexer)
1125
+ try expectKeyword ( lexer: lexer, value: " union " )
1126
+ let name = try parseName ( lexer: lexer)
1127
+ let directives = try parseDirectives ( lexer: lexer)
1128
+ let types = try parseUnionMembers ( lexer: lexer)
1129
+ if
1130
+ directives. isEmpty,
1131
+ types. isEmpty
1132
+ {
1133
+ throw unexpected ( lexer: lexer)
1134
+ }
1088
1135
return UnionExtensionDefinition (
1089
1136
loc: loc ( lexer: lexer, startToken: start) ,
1090
- definition: definition
1137
+ definition: UnionTypeDefinition (
1138
+ loc: loc ( lexer: lexer, startToken: start) ,
1139
+ name: name,
1140
+ directives: directives,
1141
+ types: types
1142
+ )
1091
1143
)
1092
1144
}
1093
1145
@@ -1097,10 +1149,29 @@ func parseUnionExtensionDefinition(lexer: Lexer) throws -> UnionExtensionDefinit
1097
1149
func parseEnumExtensionDefinition( lexer: Lexer ) throws -> EnumExtensionDefinition {
1098
1150
let start = lexer. token
1099
1151
try expectKeyword ( lexer: lexer, value: " extend " )
1100
- let definition = try parseEnumTypeDefinition ( lexer: lexer)
1152
+ try expectKeyword ( lexer: lexer, value: " enum " )
1153
+ let name = try parseName ( lexer: lexer)
1154
+ let directives = try parseDirectives ( lexer: lexer)
1155
+ let values = try optionalMany (
1156
+ lexer: lexer,
1157
+ openKind: . openingBrace,
1158
+ closeKind: . closingBrace,
1159
+ parse: parseEnumValueDefinition
1160
+ )
1161
+ if
1162
+ directives. isEmpty,
1163
+ values. isEmpty
1164
+ {
1165
+ throw unexpected ( lexer: lexer)
1166
+ }
1101
1167
return EnumExtensionDefinition (
1102
1168
loc: loc ( lexer: lexer, startToken: start) ,
1103
- definition: definition
1169
+ definition: EnumTypeDefinition (
1170
+ loc: loc ( lexer: lexer, startToken: start) ,
1171
+ name: name,
1172
+ directives: directives,
1173
+ values: values
1174
+ )
1104
1175
)
1105
1176
}
1106
1177
@@ -1110,10 +1181,29 @@ func parseEnumExtensionDefinition(lexer: Lexer) throws -> EnumExtensionDefinitio
1110
1181
func parseInputObjectExtensionDefinition( lexer: Lexer ) throws -> InputObjectExtensionDefinition {
1111
1182
let start = lexer. token
1112
1183
try expectKeyword ( lexer: lexer, value: " extend " )
1113
- let definition = try parseInputObjectTypeDefinition ( lexer: lexer)
1184
+ try expectKeyword ( lexer: lexer, value: " input " )
1185
+ let name = try parseName ( lexer: lexer)
1186
+ let directives = try parseDirectives ( lexer: lexer)
1187
+ let fields = try optionalMany (
1188
+ lexer: lexer,
1189
+ openKind: . openingBrace,
1190
+ closeKind: . closingBrace,
1191
+ parse: parseInputValueDef
1192
+ )
1193
+ if
1194
+ directives. isEmpty,
1195
+ fields. isEmpty
1196
+ {
1197
+ throw unexpected ( lexer: lexer)
1198
+ }
1114
1199
return InputObjectExtensionDefinition (
1115
1200
loc: loc ( lexer: lexer, startToken: start) ,
1116
- definition: definition
1201
+ definition: InputObjectTypeDefinition (
1202
+ loc: loc ( lexer: lexer, startToken: start) ,
1203
+ name: name,
1204
+ directives: directives,
1205
+ fields: fields
1206
+ )
1117
1207
)
1118
1208
}
1119
1209
0 commit comments