// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// This is an X-macro header. It does not use `#include` guards, and instead is
// designed to be `#include`ed after the x-macro is defined in order for its
// inclusion to expand to the desired output. Macro definitions are cleaned up
// at the end of this file.
//
// Supported x-macros are:
// - CARBON_PARSE_NODE_KIND(Name)
//   Used as a fallback if other macros are missing. Also, used directly
//   when none of the below category-oriented macros apply.
//   - CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name)
//     Defines a parse node for a prefix operator, with the Name as token.
//   - CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Name)
//     Defines a parse node for an infix operator, with the Name as token.
//   - CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Name)
//     Defines a parse node for a postfix operator, with the Name as token.
//   - CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(Name, LexTokenKind)
//     Defines a parse node that corresponds to a token that is a single-token
//     literal. The token is wrapped for LexTokenKinds.
//   - CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Name)
//     A token-based modifier. The Name is the TokenKind, and will be appended
//     with "Modifier" for the parse kind.
//
// LexTokenKind indicates the token kind required on a valid node.
//
// Parse nodes are clustered based on language feature. See typed_nodes.h for
// the expected tree structure under each node kind.

#if !defined(CARBON_PARSE_NODE_KIND)
#error "Must define CARBON_PARSE_NODE_KIND family x-macros to use this file."
#endif

// This is expected to be used with something like:
//
//   // Use x-macros to handle modifier cases.
//   #define CARBON_PARSE_NODE_KIND(...)
//   #define CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name, ...) <code>
#ifndef CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR
#define CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name) \
  CARBON_PARSE_NODE_KIND(PrefixOperator##Name)
#endif

// This is expected to be used with something like:
//
//   // Use x-macros to handle modifier cases.
//   #define CARBON_PARSE_NODE_KIND(...)
//   #define CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Name, ...) <code>
#ifndef CARBON_PARSE_NODE_KIND_INFIX_OPERATOR
#define CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Name) \
  CARBON_PARSE_NODE_KIND(InfixOperator##Name)
#endif

// This is expected to be used with something like:
//
//   // Use x-macros to handle modifier cases.
//   #define CARBON_PARSE_NODE_KIND(...)
//   #define CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Name, ...) <code>
#ifndef CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR
#define CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Name) \
  CARBON_PARSE_NODE_KIND(PostfixOperator##Name)
#endif

// This is expected to be used with something like:
//
//   // Use x-macros to handle literal cases.
//   #define CARBON_PARSE_NODE_KIND(...)
//   #define CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(Name, ...) <code>
#ifndef CARBON_PARSE_NODE_KIND_TOKEN_LITERAL
#define CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(Name, LexTokenKinds) \
  CARBON_PARSE_NODE_KIND(Name)
#endif

// This is expected to be used with something like:
//
//   // Use x-macros to handle modifier cases.
//   #define CARBON_PARSE_NODE_KIND(...)
//   #define CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Name, ...) <code>
#ifndef CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER
#define CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Name) \
  CARBON_PARSE_NODE_KIND(Name##Modifier)
#endif

CARBON_PARSE_NODE_KIND(FileStart)
CARBON_PARSE_NODE_KIND(FileEnd)

CARBON_PARSE_NODE_KIND(InvalidParse)
CARBON_PARSE_NODE_KIND(InvalidParseStart)
CARBON_PARSE_NODE_KIND(InvalidParseSubtree)

CARBON_PARSE_NODE_KIND(Placeholder)

CARBON_PARSE_NODE_KIND(EmptyDecl)

CARBON_PARSE_NODE_KIND(IdentifierName)

CARBON_PARSE_NODE_KIND(IdentifierNameExpr)

CARBON_PARSE_NODE_KIND(SelfValueName)
CARBON_PARSE_NODE_KIND(SelfValueNameExpr)
CARBON_PARSE_NODE_KIND(SelfTypeNameExpr)

CARBON_PARSE_NODE_KIND(BaseName)
CARBON_PARSE_NODE_KIND(PackageExpr)
CARBON_PARSE_NODE_KIND(PackageName)
CARBON_PARSE_NODE_KIND(LibraryName)

CARBON_PARSE_NODE_KIND(PackageIntroducer)
CARBON_PARSE_NODE_KIND(PackageDecl)

CARBON_PARSE_NODE_KIND(ImportIntroducer)
CARBON_PARSE_NODE_KIND(ImportDecl)

CARBON_PARSE_NODE_KIND(DefaultLibrary)
CARBON_PARSE_NODE_KIND(LibraryIntroducer)
CARBON_PARSE_NODE_KIND(LibraryDecl)

CARBON_PARSE_NODE_KIND(LibrarySpecifier)

CARBON_PARSE_NODE_KIND(NameQualifier)

CARBON_PARSE_NODE_KIND(ExportIntroducer)
CARBON_PARSE_NODE_KIND(ExportDecl)

CARBON_PARSE_NODE_KIND(NamespaceStart)
CARBON_PARSE_NODE_KIND(Namespace)

CARBON_PARSE_NODE_KIND(CodeBlockStart)
CARBON_PARSE_NODE_KIND(CodeBlock)

CARBON_PARSE_NODE_KIND(FunctionIntroducer)
CARBON_PARSE_NODE_KIND(ReturnType)
CARBON_PARSE_NODE_KIND(FunctionDefinitionStart)
CARBON_PARSE_NODE_KIND(FunctionDefinition)
CARBON_PARSE_NODE_KIND(FunctionDecl)
CARBON_PARSE_NODE_KIND(BuiltinFunctionDefinitionStart)
CARBON_PARSE_NODE_KIND(BuiltinName)
CARBON_PARSE_NODE_KIND(BuiltinFunctionDefinition)

CARBON_PARSE_NODE_KIND(AliasIntroducer)
CARBON_PARSE_NODE_KIND(AliasInitializer)
CARBON_PARSE_NODE_KIND(Alias)

CARBON_PARSE_NODE_KIND(TuplePatternStart)
CARBON_PARSE_NODE_KIND(PatternListComma)
CARBON_PARSE_NODE_KIND(TuplePattern)

CARBON_PARSE_NODE_KIND(ImplicitParamListStart)
CARBON_PARSE_NODE_KIND(ImplicitParamList)

CARBON_PARSE_NODE_KIND(ArrayExprStart)
CARBON_PARSE_NODE_KIND(ArrayExprSemi)
CARBON_PARSE_NODE_KIND(ArrayExpr)

CARBON_PARSE_NODE_KIND(BindingPattern)
CARBON_PARSE_NODE_KIND(CompileTimeBindingPattern)
CARBON_PARSE_NODE_KIND(Addr)
CARBON_PARSE_NODE_KIND(Template)

CARBON_PARSE_NODE_KIND(LetIntroducer)
CARBON_PARSE_NODE_KIND(LetInitializer)
CARBON_PARSE_NODE_KIND(LetDecl)

CARBON_PARSE_NODE_KIND(VariableIntroducer)
CARBON_PARSE_NODE_KIND(ReturnedModifier)
CARBON_PARSE_NODE_KIND(VariableInitializer)
CARBON_PARSE_NODE_KIND(VariableDecl)

CARBON_PARSE_NODE_KIND(ExprStatement)

CARBON_PARSE_NODE_KIND(BreakStatementStart)
CARBON_PARSE_NODE_KIND(BreakStatement)

CARBON_PARSE_NODE_KIND(ContinueStatementStart)
CARBON_PARSE_NODE_KIND(ContinueStatement)

CARBON_PARSE_NODE_KIND(ReturnStatementStart)
CARBON_PARSE_NODE_KIND(ReturnVarModifier)
CARBON_PARSE_NODE_KIND(ReturnStatement)

CARBON_PARSE_NODE_KIND(ForHeaderStart)
CARBON_PARSE_NODE_KIND(ForIn)
CARBON_PARSE_NODE_KIND(ForHeader)
CARBON_PARSE_NODE_KIND(ForStatement)

CARBON_PARSE_NODE_KIND(IfConditionStart)
CARBON_PARSE_NODE_KIND(IfCondition)
CARBON_PARSE_NODE_KIND(IfStatementElse)
CARBON_PARSE_NODE_KIND(IfStatement)

CARBON_PARSE_NODE_KIND(WhileConditionStart)
CARBON_PARSE_NODE_KIND(WhileCondition)
CARBON_PARSE_NODE_KIND(WhileStatement)

CARBON_PARSE_NODE_KIND(IndexExprStart)
CARBON_PARSE_NODE_KIND(IndexExpr)

CARBON_PARSE_NODE_KIND(ParenExprStart)
CARBON_PARSE_NODE_KIND(ParenExpr)

CARBON_PARSE_NODE_KIND(TupleLiteralStart)
CARBON_PARSE_NODE_KIND(TupleLiteralComma)
CARBON_PARSE_NODE_KIND(TupleLiteral)

CARBON_PARSE_NODE_KIND(CallExprStart)
CARBON_PARSE_NODE_KIND(CallExprComma)
CARBON_PARSE_NODE_KIND(CallExpr)

CARBON_PARSE_NODE_KIND(MemberAccessExpr)

CARBON_PARSE_NODE_KIND(PointerMemberAccessExpr)

CARBON_PARSE_NODE_KIND(IntLiteral)

CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(BoolLiteralFalse, False)
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(BoolLiteralTrue, True)
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(RealLiteral, RealLiteral)
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(StringLiteral, StringLiteral)

CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(BoolTypeLiteral, Bool)
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(IntTypeLiteral, IntTypeLiteral)
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(UnsignedIntTypeLiteral,
                                     UnsignedIntTypeLiteral)
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(FloatTypeLiteral, FloatTypeLiteral)
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(StringTypeLiteral, StringTypeLiteral)
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(TypeTypeLiteral, Type)
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(AutoTypeLiteral, Auto)

CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Amp)
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Caret)
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Const)
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Not)
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Minus)
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(MinusMinus)
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(PlusPlus)
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Star)

CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Amp)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(AmpEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(As)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Caret)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(CaretEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Equal)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(EqualEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(ExclaimEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Greater)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(GreaterEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(GreaterGreater)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(GreaterGreaterEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Less)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(LessEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(LessEqualGreater)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(LessLess)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(LessLessEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Minus)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(MinusEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Percent)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(PercentEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Pipe)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(PipeEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Plus)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(PlusEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Slash)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(SlashEqual)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Star)
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(StarEqual)

CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Star)

CARBON_PARSE_NODE_KIND(ShortCircuitOperandAnd)
CARBON_PARSE_NODE_KIND(ShortCircuitOperandOr)
CARBON_PARSE_NODE_KIND(ShortCircuitOperatorAnd)
CARBON_PARSE_NODE_KIND(ShortCircuitOperatorOr)

CARBON_PARSE_NODE_KIND(DesignatorExpr)
CARBON_PARSE_NODE_KIND(SelfTypeName)
CARBON_PARSE_NODE_KIND(RequirementAnd)
CARBON_PARSE_NODE_KIND(RequirementEqual)
CARBON_PARSE_NODE_KIND(RequirementEqualEqual)
CARBON_PARSE_NODE_KIND(RequirementImpls)
CARBON_PARSE_NODE_KIND(WhereExpr)
CARBON_PARSE_NODE_KIND(WhereOperand)

CARBON_PARSE_NODE_KIND(IfExprIf)
CARBON_PARSE_NODE_KIND(IfExprThen)
CARBON_PARSE_NODE_KIND(IfExprElse)

CARBON_PARSE_NODE_KIND(StructFieldDesignator)

CARBON_PARSE_NODE_KIND(StructLiteralStart)
CARBON_PARSE_NODE_KIND(StructLiteralField)
CARBON_PARSE_NODE_KIND(StructLiteralComma)
CARBON_PARSE_NODE_KIND(StructLiteral)

CARBON_PARSE_NODE_KIND(StructTypeLiteralStart)
CARBON_PARSE_NODE_KIND(StructTypeLiteralField)
CARBON_PARSE_NODE_KIND(StructTypeLiteralComma)
CARBON_PARSE_NODE_KIND(StructTypeLiteral)

CARBON_PARSE_NODE_KIND(ExternModifierWithLibrary)
CARBON_PARSE_NODE_KIND(ExternModifier)

CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Abstract)
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Base)
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Default)
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Export)
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Extend)
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Final)
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Impl)
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Private)
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Protected)
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Virtual)

CARBON_PARSE_NODE_KIND(ClassIntroducer)
CARBON_PARSE_NODE_KIND(ClassDefinitionStart)
CARBON_PARSE_NODE_KIND(ClassDefinition)
CARBON_PARSE_NODE_KIND(ClassDecl)

CARBON_PARSE_NODE_KIND(AdaptIntroducer)
CARBON_PARSE_NODE_KIND(AdaptDecl)

CARBON_PARSE_NODE_KIND(BaseIntroducer)
CARBON_PARSE_NODE_KIND(BaseColon)
CARBON_PARSE_NODE_KIND(BaseDecl)

CARBON_PARSE_NODE_KIND(InterfaceIntroducer)
CARBON_PARSE_NODE_KIND(InterfaceDefinitionStart)
CARBON_PARSE_NODE_KIND(InterfaceDefinition)
CARBON_PARSE_NODE_KIND(InterfaceDecl)

CARBON_PARSE_NODE_KIND(ImplIntroducer)
CARBON_PARSE_NODE_KIND(ImplDefinitionStart)
CARBON_PARSE_NODE_KIND(ImplDefinition)
CARBON_PARSE_NODE_KIND(ImplDecl)
CARBON_PARSE_NODE_KIND(ImplForall)
CARBON_PARSE_NODE_KIND(TypeImplAs)
CARBON_PARSE_NODE_KIND(DefaultSelfImplAs)

CARBON_PARSE_NODE_KIND(NamedConstraintIntroducer)
CARBON_PARSE_NODE_KIND(NamedConstraintDefinitionStart)
CARBON_PARSE_NODE_KIND(NamedConstraintDefinition)
CARBON_PARSE_NODE_KIND(NamedConstraintDecl)

CARBON_PARSE_NODE_KIND(ChoiceIntroducer)
CARBON_PARSE_NODE_KIND(ChoiceDefinitionStart)
CARBON_PARSE_NODE_KIND(ChoiceDefinition)
CARBON_PARSE_NODE_KIND(ChoiceAlternativeListComma)

CARBON_PARSE_NODE_KIND(MatchIntroducer)
CARBON_PARSE_NODE_KIND(MatchConditionStart)
CARBON_PARSE_NODE_KIND(MatchCondition)
CARBON_PARSE_NODE_KIND(MatchStatementStart)
CARBON_PARSE_NODE_KIND(MatchStatement)
CARBON_PARSE_NODE_KIND(MatchCaseIntroducer)
CARBON_PARSE_NODE_KIND(MatchCaseGuardIntroducer)
CARBON_PARSE_NODE_KIND(MatchCaseGuardStart)
CARBON_PARSE_NODE_KIND(MatchCaseGuard)
CARBON_PARSE_NODE_KIND(MatchCaseEqualGreater)
CARBON_PARSE_NODE_KIND(MatchCaseStart)
CARBON_PARSE_NODE_KIND(MatchCase)
CARBON_PARSE_NODE_KIND(MatchDefaultIntroducer)
CARBON_PARSE_NODE_KIND(MatchDefaultEqualGreater)
CARBON_PARSE_NODE_KIND(MatchDefaultStart)
CARBON_PARSE_NODE_KIND(MatchDefault)

#undef CARBON_PARSE_NODE_KIND
#undef CARBON_PARSE_NODE_KIND_INFIX_OPERATOR
#undef CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR
#undef CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR
#undef CARBON_PARSE_NODE_KIND_TOKEN_LITERAL
#undef CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER
