/// <summary> /// Parse schema definition extension. /// <see cref="SchemaExtensionNode" />: /// * - extend schema Directives[Const]? { OperationTypeDefinition+ } /// * - extend schema Directives[Const] /// </summary> /// <param name="context">The parser context.</param> private SchemaExtensionNode ParseSchemaExtension(ParserContext context) { SyntaxToken start = context.Current; context.ExpectExtendKeyword(); context.ExpectSchemaKeyword(); List <DirectiveNode> directives = ParseDirectives(context, true); List <OperationTypeDefinitionNode> operationTypeDefinitions = ParseOperationTypeDefinitions(context); if (directives.Count == 0 && operationTypeDefinitions.Count == 0) { throw context.Unexpected(start); } Location location = context.CreateLocation(start); return(new SchemaExtensionNode ( location, directives, operationTypeDefinitions )); }
private ITypeExtensionNode ParseTypeExtension(ParserContext context) { SyntaxToken keywordToken = context.Current.Peek(); if (keywordToken.Kind == TokenKind.Name) { switch (keywordToken.Value) { case Keywords.Schema: return(ParseSchemaExtension(context)); case Keywords.Scalar: return(ParseScalarTypeExtension(context)); case Keywords.Type: return(ParseObjectTypeExtension(context)); case Keywords.Interface: return(ParseInterfaceTypeExtension(context)); case Keywords.Union: return(ParseUnionTypeExtension(context)); case Keywords.Enum: return(ParseEnumTypeExtension(context)); case Keywords.Input: return(ParseInputObjectTypeExtension(context)); } } throw context.Unexpected(keywordToken); }
private EnumTypeExtensionNode ParseEnumTypeExtension(ParserContext context) { SyntaxToken start = context.Current; context.ExpectExtendKeyword(); context.ExpectEnumKeyword(); NameNode name = context.ParseName(); List <DirectiveNode> directives = ParseDirectives(context, true); List <EnumValueDefinitionNode> values = ParseEnumValuesDefinition(context); Location location = context.CreateLocation(start); if (directives.Count == 0 && values.Count == 0) { throw context.Unexpected(start); } return(new EnumTypeExtensionNode ( location, name, directives, values )); }
private InputObjectTypeExtensionNode ParseInputObjectTypeExtension(ParserContext context) { SyntaxToken start = context.Current; context.ExpectExtendKeyword(); context.ExpectInputKeyword(); NameNode name = context.ParseName(); List <DirectiveNode> directives = ParseDirectives(context, true); List <InputValueDefinitionNode> fields = ParseInputFieldsDefinition(context); Location location = context.CreateLocation(start); if (directives.Count == 0 && fields.Count == 0) { throw context.Unexpected(start); } return(new InputObjectTypeExtensionNode ( location, name, directives, fields )); }
private ObjectTypeExtensionNode ParseObjectTypeExtension(ParserContext context) { SyntaxToken start = context.Current; context.ExpectExtendKeyword(); context.ExpectTypeKeyword(); NameNode name = context.ParseName(); List <NamedTypeNode> interfaces = ParseImplementsInterfaces(context); List <DirectiveNode> directives = ParseDirectives(context, true); List <FieldDefinitionNode> fields = ParseFieldsDefinition(context); Location location = context.CreateLocation(start); if (interfaces.Count == 0 && directives.Count == 0 && fields.Count == 0) { throw context.Unexpected(start); } return(new ObjectTypeExtensionNode ( location, name, directives, interfaces, fields )); }
private UnionTypeExtensionNode ParseUnionTypeExtension(ParserContext context) { SyntaxToken start = context.Current; context.ExpectExtendKeyword(); context.ExpectUnionKeyword(); NameNode name = context.ParseName(); List <DirectiveNode> directives = ParseDirectives(context, true); List <NamedTypeNode> types = ParseUnionMemberTypes(context); Location location = context.CreateLocation(start); if (directives.Count == 0 && types.Count == 0) { throw context.Unexpected(start); } return(new UnionTypeExtensionNode ( location, name, directives, types )); }
/// <summary> /// Parses a value. /// <see cref="IValueNode" />: /// - Variable [only if isConstant is <c>false</c>] /// - IntValue /// - FloatValue /// - StringValue /// - BooleanValue /// - NullValue /// - EnumValue /// - ListValue[isConstant] /// - ObjectValue[isConstant] /// <see cref="BooleanValueNode" />: true or false. /// <see cref="NullValueNode" />: null /// <see cref="EnumValueNode" />: Name but not true, false or null. /// </summary> /// <param name="context">The parser context.</param> /// <param name="isConstant"> /// Defines if only constant values are allowed; /// otherwise, variables are allowed. /// </param> internal static IValueNode ParseValueLiteral( ParserContext context, bool isConstant) { SyntaxToken start = context.Current; if (start.Kind == TokenKind.LeftBracket) { return(ParseList(context, isConstant)); } if (start.Kind == TokenKind.LeftBrace) { return(ParseObject(context, isConstant)); } if (start.IsScalarValue()) { return(ParseScalarValue(context)); } if (start.IsName()) { return(ParseEnumValue(context)); } if (start.IsDollar() && !isConstant) { return(ParseVariable(context)); } throw context.Unexpected(start); }
private static IValueNode ParseScalarValue(ParserContext context) { if (context.Current.IsString()) { return(ParseStringLiteral(context)); } SyntaxToken start = context.ExpectScalarValue(); Location location = context.CreateLocation(start); if (start.Kind == TokenKind.Float) { return(new FloatValueNode ( location, start.Value )); } if (start.Kind == TokenKind.Integer) { return(new IntValueNode ( location, start.Value )); } throw context.Unexpected(start); }
/// <summary> /// Parses a type reference. /// <see cref="ITypeNode" />: /// - NamedType /// - ListType /// - NonNullType /// </summary> /// <param name="context">The parser context.</param> private ITypeNode ParseTypeReference(ParserContext context) { SyntaxToken start = context.Current; ITypeNode type; Location location; if (context.Skip(TokenKind.LeftBracket)) { type = ParseTypeReference(context); context.ExpectRightBracket(); location = context.CreateLocation(start); type = new ListTypeNode(location, type); } else { type = ParseNamedType(context); } if (context.Skip(TokenKind.Bang)) { if (type is INullableType nt) { return(new NonNullTypeNode ( context.CreateLocation(start), nt )); } context.Unexpected(context.Current.Previous); } return(type); }
/// <summary> /// Parse fragment name. /// <see cref="NameNode" />: /// Name /// </summary> /// <param name="context">The parser context.</param> private static NameNode ParseFragmentName(ParserContext context) { if (context.Current.IsOnKeyword()) { throw context.Unexpected(context.Current); } return(ParseName(context)); }
private NameNode ParseDirectiveLocation(ParserContext context) { SyntaxToken start = context.Current; NameNode name = context.ParseName(); if (DirectiveLocation.IsValidName(name.Value)) { return(name); } throw context.Unexpected(start); }
/// <summary> /// Parses a type definition. /// <see cref="ITypeSystemDefinitionNode" />: /// TypeSystemDefinition: /// - SchemaDefinition /// - TypeDefinition /// - TypeExtension /// - DirectiveDefinition /// /// TypeDefinition: /// - ScalarTypeDefinition /// - ObjectTypeDefinition /// - InterfaceTypeDefinition /// - UnionTypeDefinition /// - EnumTypeDefinition /// - InputObjectTypeDefinition /// </summary> /// <param name="context">The parser context.</param> private static ITypeSystemDefinitionNode ParseTypeSystemDefinition( ParserContext context) { // Many definitions begin with a description and require a lookahead. SyntaxToken keywordToken = context.Current; if (keywordToken.IsDescription()) { keywordToken = keywordToken.Peek(); } if (keywordToken.IsName()) { switch (keywordToken.Value) { case Keywords.Schema: return(ParseSchemaDefinition(context)); case Keywords.Scalar: return(ParseScalarTypeDefinition(context)); case Keywords.Type: return(ParseObjectTypeDefinition(context)); case Keywords.Interface: return(ParseInterfaceTypeDefinition(context)); case Keywords.Union: return(ParseUnionTypeDefinition(context)); case Keywords.Enum: return(ParseEnumTypeDefinition(context)); case Keywords.Input: return(ParseInputObjectTypeDefinition(context)); case Keywords.Extend: return(ParseTypeExtension(context)); case Keywords.Directive: return(ParseDirectiveDefinition(context)); } } throw context.Unexpected(keywordToken); }
/// <summary> /// Parses the <see cref="OperationType" />. /// </summary> /// <param name="context">The parser context.</param> private static OperationType ParseOperationType(ParserContext context) { SyntaxToken token = context.ExpectName(); switch (token.Value) { case Keywords.Query: return(OperationType.Query); case Keywords.Mutation: return(OperationType.Mutation); case Keywords.Subscription: return(OperationType.Subscription); } throw context.Unexpected(token); }
private static IDefinitionNode ParseDefinition(ParserContext context) { SyntaxToken token = context.Current; if (token.IsDescription()) { token = token.Peek(); } if (token.IsName()) { switch (token.Value) { case Keywords.Query: case Keywords.Mutation: case Keywords.Subscription: case Keywords.Fragment: return(ParseExecutableDefinition(context)); case Keywords.Schema: case Keywords.Scalar: case Keywords.Type: case Keywords.Interface: case Keywords.Union: case Keywords.Enum: case Keywords.Input: case Keywords.Extend: case Keywords.Directive: return(ParseTypeSystemDefinition(context)); } } else if (token.IsLeftBrace()) { return(ParseExecutableDefinition(context)); } else if (token.IsDescription()) { return(ParseTypeSystemDefinition(context)); } throw context.Unexpected(token); }
private IExecutableDefinitionNode ParseExecutableDefinition(ParserContext context) { if (context.Current.IsName()) { switch (context.Current.Value) { case Keywords.Query: case Keywords.Mutation: case Keywords.Subscription: return(ParseOperationDefinition(context)); case Keywords.Fragment: return(ParseFragmentDefinition(context)); } } else if (context.Current.IsLeftBrace()) { return(ParseOperationDefinition(context)); } throw context.Unexpected(context.Current); }
private ScalarTypeExtensionNode ParseScalarTypeExtension( ParserContext context) { SyntaxToken start = context.Current; context.ExpectExtendKeyword(); context.ExpectScalarKeyword(); NameNode name = context.ParseName(); List <DirectiveNode> directives = ParseDirectives(context, true); if (directives.Count == 0) { throw context.Unexpected(start); } Location location = context.CreateLocation(start); return(new ScalarTypeExtensionNode ( location, name, directives )); }