#ifndef SEMANTIC_TOKEN_TYPE
#define SEMANTIC_TOKEN_TYPE(...)
#endif

#ifndef SEMANTIC_TOKEN_MODIFIER
#define SEMANTIC_TOKEN_MODIFIER(...)
#endif

/// comment.
SEMANTIC_TOKEN_TYPE(Comment, "comment")

/// character literal.
SEMANTIC_TOKEN_TYPE(Character, "character")

/// number literal(int, float, hex, binary).
SEMANTIC_TOKEN_TYPE(Number, "number")

/// string literal.
SEMANTIC_TOKEN_TYPE(String, "string")

/// C/C++ keyword (e.g. `if`, `else`, `while`, `for`).
SEMANTIC_TOKEN_TYPE(Keyword, "keyword")

/// compiler builtin macro, function or keyword (e.g. `__FILE__`, `__LINE__`, `__attribute__`).
SEMANTIC_TOKEN_TYPE(Builtin, "builtin")

/// preprocessor directive (e.g. `#include`, `#define`, `#ifdef`).
SEMANTIC_TOKEN_TYPE(Directives, "directive")

/// header file (e.g. `"foo.h"` and `<vector>`).
SEMANTIC_TOKEN_TYPE(Header, "header")

/// C/C++ macro name, both in definition and invocation.
SEMANTIC_TOKEN_TYPE(Macro, "macro")

/// C/C++ macro parameter, both in definition and invocation.
SEMANTIC_TOKEN_TYPE(MacroParameter, "macroParameter")

/// C++ namespace.
SEMANTIC_TOKEN_TYPE(Namespace, "namespace")

/// C/C++ type name (e.g. `std::string`).
SEMANTIC_TOKEN_TYPE(Type, "type")

/// C/C++ struct name.
SEMANTIC_TOKEN_TYPE(Struct, "struct")

/// C/C++ union name.
SEMANTIC_TOKEN_TYPE(Union, "union")

/// C/C++ class name.
SEMANTIC_TOKEN_TYPE(Class, "class")

/// C/C++ field name.
SEMANTIC_TOKEN_TYPE(Field, "field")

/// C/C++ enum name.
SEMANTIC_TOKEN_TYPE(Enum, "enum")

/// C/C++ enum member name.
SEMANTIC_TOKEN_TYPE(EnumMember, "enumMember")

/// C/C++ variable name.
SEMANTIC_TOKEN_TYPE(Variable, "variable")

/// C/C++ function name.
SEMANTIC_TOKEN_TYPE(Function, "function")

/// C/C++ method name.
SEMANTIC_TOKEN_TYPE(Method, "method")

/// C/C++ function/method parameter name.
SEMANTIC_TOKEN_TYPE(Parameter, "parameter")

/// C++ attribute name(e.g., `nodiscard`, `likely`, `fallthrough`).
SEMANTIC_TOKEN_TYPE(Attribute, "attribute")

/// C++20 module name.
SEMANTIC_TOKEN_TYPE(Module, "module")

/// C++20 concept name.
SEMANTIC_TOKEN_TYPE(Concept, "concept")

/// parentheses `()`.
SEMANTIC_TOKEN_TYPE(Paren, "paren")

/// brackets `[]`.
SEMANTIC_TOKEN_TYPE(Bracket, "bracket")

/// braces `{}`.
SEMANTIC_TOKEN_TYPE(Brace, "brace")

/// angle brackets `<>`.
SEMANTIC_TOKEN_TYPE(Angle, "angle")

/// operators (e.g. `+`, `==`, `<<`).
SEMANTIC_TOKEN_TYPE(Operator, "operator")

/// for name in declaration.
SEMANTIC_TOKEN_MODIFIER(Declaration, "declaration")

/// for name in definition.
SEMANTIC_TOKEN_MODIFIER(Definition, "definition")

/// for `(`, `[`, `{`, `<`.
SEMANTIC_TOKEN_MODIFIER(Left, "left")

/// for `)`, `]`, `}`, `>`.
SEMANTIC_TOKEN_MODIFIER(Right, "right")

/// for punctuation in type, e.g `*` in `int*` and `&` in `int&`.
SEMANTIC_TOKEN_MODIFIER(InType, "inType")

/// for overloaded function or operator.
SEMANTIC_TOKEN_MODIFIER(Overloaded, "overloaded")

/// for name around template arguments(e.g., `foo` in `foo<int>`).
SEMANTIC_TOKEN_MODIFIER(Templated, "templated")

/// C++ dependent name in a template context (e.g., `name` in `auto y = T::name`
/// where T is a template parameter).
/// Note: This includes `T::template name(...)`; it's not possible to distinguish whether a name
/// is a function or a functor in a dependent context.

/// C++ dependent type name (e.g., `type` in `typename std::vector<T>::type` where
/// T is a template parameter).
/// Note: This includes `typename T::template type<...>`.
SEMANTIC_TOKEN_MODIFIER(Dependent, "dependent")

#undef SEMANTIC_TOKEN_TYPE
#undef SEMANTIC_TOKEN_MODIFIER
