#ifndef NODE_KIND
#define NODE_KIND(NAME, EXTERNAL_NAME)
#endif

#ifndef NODE_ANNOTATION
#define NODE_ANNOTATION(NAME)
#endif

#ifndef NODE_ANNOTATION_CHANGE_KIND
#define NODE_ANNOTATION_CHANGE_KIND(NAME) NODE_ANNOTATION(NAME)
#endif

#ifndef KEY
#define KEY(NAME)
#endif

#ifndef KNOWN_TYPE
#define KNOWN_TYPE(NAME)
#endif

#ifndef KNOWN_PROTOCOL
#define KNOWN_PROTOCOL(NAME)
#endif

#ifndef DIFF_ITEM_KIND
#define DIFF_ITEM_KIND(NAME)
#endif

#ifndef DIFF_ITEM_KEY_KIND
#define DIFF_ITEM_KEY_KIND(NAME)
#endif

#ifndef SPECIAL_CASE_ID
#define SPECIAL_CASE_ID(NAME)
#endif

NODE_KIND(Root, Root)
NODE_KIND(TypeNominal, TypeNominal)
NODE_KIND(TypeFunc, TypeFunc)
NODE_KIND(TypeAlias, TypeNameAlias)
NODE_KIND(DeclType, TypeDecl)
NODE_KIND(DeclFunction, Function)
NODE_KIND(DeclConstructor, Constructor)
NODE_KIND(DeclGetter, Getter)
NODE_KIND(DeclSetter, Setter)
NODE_KIND(DeclVar, Var)
NODE_KIND(DeclTypeAlias, TypeAlias)

NODE_ANNOTATION(Added)
NODE_ANNOTATION(Removed)
NODE_ANNOTATION(Updated)
NODE_ANNOTATION(PropertyName)
NODE_ANNOTATION(TypeRewrittenLeft)
NODE_ANNOTATION(TypeRewrittenRight)
NODE_ANNOTATION(RemovedDecl)
NODE_ANNOTATION(RenameOldName)
NODE_ANNOTATION(RenameNewName)
NODE_ANNOTATION(NowThrowing)
NODE_ANNOTATION(NowMutating)
NODE_ANNOTATION(StaticChange)
NODE_ANNOTATION(OwnershipChange)
NODE_ANNOTATION(ChangeObjC)
NODE_ANNOTATION(ChangeFixedLayout)
NODE_ANNOTATION(ChangeFrozen)
NODE_ANNOTATION(ChangeDynamic)
NODE_ANNOTATION(ChangeGenericSignature)
NODE_ANNOTATION(RawTypeLeft)
NODE_ANNOTATION(RawTypeRight)

NODE_ANNOTATION_CHANGE_KIND(ImplicitOptionalToOptional)
NODE_ANNOTATION_CHANGE_KIND(OptionalToImplicitOptional)
NODE_ANNOTATION_CHANGE_KIND(WrapOptional)
NODE_ANNOTATION_CHANGE_KIND(WrapImplicitOptional)
NODE_ANNOTATION_CHANGE_KIND(UnwrapOptional)
NODE_ANNOTATION_CHANGE_KIND(GetterToProperty)
NODE_ANNOTATION_CHANGE_KIND(SetterToProperty)
NODE_ANNOTATION_CHANGE_KIND(DictionaryKeyUpdate)
NODE_ANNOTATION_CHANGE_KIND(OptionalDictionaryKeyUpdate)
NODE_ANNOTATION_CHANGE_KIND(ArrayMemberUpdate)
NODE_ANNOTATION_CHANGE_KIND(OptionalArrayMemberUpdate)
NODE_ANNOTATION_CHANGE_KIND(SimpleStringRepresentableUpdate)
NODE_ANNOTATION_CHANGE_KIND(SimpleOptionalStringRepresentableUpdate)
NODE_ANNOTATION_CHANGE_KIND(TypeAliasDeclToRawRepresentable)
NODE_ANNOTATION_CHANGE_KIND(RevertTypeAliasDeclToRawRepresentable)

NODE_ANNOTATION_CHANGE_KIND(RevertDictionaryKeyUpdate)
NODE_ANNOTATION_CHANGE_KIND(RevertOptionalDictionaryKeyUpdate)
NODE_ANNOTATION_CHANGE_KIND(RevertArrayMemberUpdate)
NODE_ANNOTATION_CHANGE_KIND(RevertOptionalArrayMemberUpdate)
NODE_ANNOTATION_CHANGE_KIND(RevertSimpleStringRepresentableUpdate)
NODE_ANNOTATION_CHANGE_KIND(RevertSimpleOptionalStringRepresentableUpdate)

NODE_ANNOTATION_CHANGE_KIND(ModernizeEnum)
NODE_ANNOTATION_CHANGE_KIND(UnwrapUnmanaged)
NODE_ANNOTATION_CHANGE_KIND(Rename)

// Keep type rewritten the last one.
NODE_ANNOTATION_CHANGE_KIND(TypeRewritten)

KEY(kind)
KEY(name)
KEY(selfIndex)
KEY(usr)
KEY(location)
KEY(children)
KEY(printedName)
KEY(moduleName)
KEY(throwing)
KEY(mutating)
KEY(static)
KEY(deprecated)
KEY(typeAttributes)
KEY(declAttributes)
KEY(declKind)
KEY(ownership)
KEY(superclassUsr)
KEY(hasDefaultArg)
KEY(conformingProtocols)
KEY(enumRawTypeName)
KEY(genericSig)

KNOWN_TYPE(Optional)
KNOWN_TYPE(ImplicitlyUnwrappedOptional)
KNOWN_TYPE(Void)
KNOWN_TYPE(Unmanaged)
KNOWN_TYPE(Function)
KNOWN_TYPE(Dictionary)
KNOWN_TYPE(String)
KNOWN_TYPE(Array)
KNOWN_TYPE(Int)

KNOWN_PROTOCOL(RawRepresentable)

DIFF_ITEM_KIND(CommonDiffItem)
DIFF_ITEM_KIND(TypeMemberDiffItem)
DIFF_ITEM_KIND(SpecialCaseDiffItem)
DIFF_ITEM_KIND(NoEscapeFuncParam)
DIFF_ITEM_KIND(OverloadedFuncInfo)

#ifndef DIFF_ITEM_KEY_KIND_STRING
#define DIFF_ITEM_KEY_KIND_STRING(NAME) DIFF_ITEM_KEY_KIND(NAME)
#endif

#ifndef DIFF_ITEM_KEY_KIND_INT
#define DIFF_ITEM_KEY_KIND_INT(NAME) DIFF_ITEM_KEY_KIND(NAME)
#endif

DIFF_ITEM_KEY_KIND_STRING(DiffItemKind)
DIFF_ITEM_KEY_KIND_STRING(NodeKind)
DIFF_ITEM_KEY_KIND_STRING(NodeAnnotation)
DIFF_ITEM_KEY_KIND_STRING(Usr)
DIFF_ITEM_KEY_KIND_STRING(ChildIndex)
DIFF_ITEM_KEY_KIND_STRING(LeftUsr)
DIFF_ITEM_KEY_KIND_STRING(LeftComment)
DIFF_ITEM_KEY_KIND_STRING(RightUsr)
DIFF_ITEM_KEY_KIND_STRING(RightComment)
DIFF_ITEM_KEY_KIND_STRING(ModuleName)
DIFF_ITEM_KEY_KIND_STRING(NewTypeName)
DIFF_ITEM_KEY_KIND_STRING(NewPrintedName)
DIFF_ITEM_KEY_KIND_STRING(OldTypeName)
DIFF_ITEM_KEY_KIND_STRING(OldPrintedName)
DIFF_ITEM_KEY_KIND_STRING(SpecialCaseId)

DIFF_ITEM_KEY_KIND_INT(SelfIndex)
DIFF_ITEM_KEY_KIND_INT(RemovedIndex)
DIFF_ITEM_KEY_KIND_INT(Index)

SPECIAL_CASE_ID(NSOpenGLSetOption)
SPECIAL_CASE_ID(NSOpenGLGetOption)
SPECIAL_CASE_ID(StaticAbsToSwiftAbs)
SPECIAL_CASE_ID(NSOpenGLGetVersion)
SPECIAL_CASE_ID(ToIntMax)
SPECIAL_CASE_ID(ToUIntMax)
SPECIAL_CASE_ID(UIApplicationMain)

#undef SPECIAL_CASE_ID
#undef DIFF_ITEM_KEY_KIND_INT
#undef DIFF_ITEM_KEY_KIND_STRING

#undef DIFF_ITEM_KEY_KIND
#undef DIFF_ITEM_KIND
#undef KNOWN_TYPE
#undef KNOWN_PROTOCOL
#undef KEY
#undef NODE_ANNOTATION_CHANGE_KIND
#undef NODE_ANNOTATION
#undef NODE_KIND
