// This file was autogenerated by binjs_generate_spidermonkey,
// please DO NOT EDIT BY HAND.
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// To generate this file, see the documentation in
// js/src/frontend/binast/README.md.

#ifndef frontend_BinASTToken_h
#define frontend_BinASTToken_h

#include <stddef.h>

#include "jstypes.h"

/**
 * Definition of Binary AST tokens.
 *
 * In the Binary AST world, an AST is composed of nodes, where a node is
 * defined by:
 * - a Kind (see `BinASTKind`);
 * - a list of fields, where each field is:
 *    - a Name (see `BinASTField`);
 *    - a Value, which may be either a node or a primitive value.
 *
 * The mapping between Kind and list of fields is determined entirely by
 * the grammar of Binary AST. The mapping between (Kind, Name) and the
 * structure of Value is also determined entirely by the grammar of
 * Binary AST.
 *
 * As per the specifications of Binary AST, kinds may be added as the
 * language grows, but never removed. The mapping between Kind and list
 * of fields may also change to add new fields or make some fields optional,
 * but may never remove a field. Finally, the mapping between (Kind, Name)
 * and the structure of Value may be modified to add new possible values,
 * but never to remove a value.
 *
 * A Binary AST parser must be able to fail gracefully when confronted with
 * unknown Kinds or Names.
 */

namespace js {
namespace frontend {

/**
 * The different kinds of Binary AST nodes, as per the specifications of
 * Binary AST.
 *
 * These kinds match roughly with the `ParseNodeKind` used internally.
 *
 * Usage:
 *
 * ```c++
 * #define WITH_KIND(CPP_NAME, SPEC_NAME) ...
 * FOR_EACH_BIN_KIND(WITH_KIND)
 * ```
 *
 *
 * (sorted by alphabetical order)
 */
#define FOR_EACH_BIN_KIND(F)                                                  \
  F(_Uninitialized, "Uninitialized", UNINITIALIZED)                           \
  F(_Null, "", NULL)                                                          \
  F(ArrayAssignmentTarget, "ArrayAssignmentTarget", ARRAY_ASSIGNMENT_TARGET)  \
  F(ArrayBinding, "ArrayBinding", ARRAY_BINDING)                              \
  F(ArrayExpression, "ArrayExpression", ARRAY_EXPRESSION)                     \
  F(ArrowExpressionContentsWithExpression,                                    \
    "ArrowExpressionContentsWithExpression",                                  \
    ARROW_EXPRESSION_CONTENTS_WITH_EXPRESSION)                                \
  F(ArrowExpressionContentsWithFunctionBody,                                  \
    "ArrowExpressionContentsWithFunctionBody",                                \
    ARROW_EXPRESSION_CONTENTS_WITH_FUNCTION_BODY)                             \
  F(AssertedBlockScope, "AssertedBlockScope", ASSERTED_BLOCK_SCOPE)           \
  F(AssertedBoundName, "AssertedBoundName", ASSERTED_BOUND_NAME)              \
  F(AssertedBoundNamesScope, "AssertedBoundNamesScope",                       \
    ASSERTED_BOUND_NAMES_SCOPE)                                               \
  F(AssertedDeclaredName, "AssertedDeclaredName", ASSERTED_DECLARED_NAME)     \
  F(AssertedParameterName, "AssertedParameterName", ASSERTED_PARAMETER_NAME)  \
  F(AssertedParameterScope, "AssertedParameterScope",                         \
    ASSERTED_PARAMETER_SCOPE)                                                 \
  F(AssertedPositionalParameterName, "AssertedPositionalParameterName",       \
    ASSERTED_POSITIONAL_PARAMETER_NAME)                                       \
  F(AssertedRestParameterName, "AssertedRestParameterName",                   \
    ASSERTED_REST_PARAMETER_NAME)                                             \
  F(AssertedScriptGlobalScope, "AssertedScriptGlobalScope",                   \
    ASSERTED_SCRIPT_GLOBAL_SCOPE)                                             \
  F(AssertedVarScope, "AssertedVarScope", ASSERTED_VAR_SCOPE)                 \
  F(AssignmentExpression, "AssignmentExpression", ASSIGNMENT_EXPRESSION)      \
  F(AssignmentTargetIdentifier, "AssignmentTargetIdentifier",                 \
    ASSIGNMENT_TARGET_IDENTIFIER)                                             \
  F(AssignmentTargetPropertyIdentifier, "AssignmentTargetPropertyIdentifier", \
    ASSIGNMENT_TARGET_PROPERTY_IDENTIFIER)                                    \
  F(AssignmentTargetPropertyProperty, "AssignmentTargetPropertyProperty",     \
    ASSIGNMENT_TARGET_PROPERTY_PROPERTY)                                      \
  F(AssignmentTargetWithInitializer, "AssignmentTargetWithInitializer",       \
    ASSIGNMENT_TARGET_WITH_INITIALIZER)                                       \
  F(AwaitExpression, "AwaitExpression", AWAIT_EXPRESSION)                     \
  F(BinaryExpression, "BinaryExpression", BINARY_EXPRESSION)                  \
  F(BindingIdentifier, "BindingIdentifier", BINDING_IDENTIFIER)               \
  F(BindingPropertyIdentifier, "BindingPropertyIdentifier",                   \
    BINDING_PROPERTY_IDENTIFIER)                                              \
  F(BindingPropertyProperty, "BindingPropertyProperty",                       \
    BINDING_PROPERTY_PROPERTY)                                                \
  F(BindingWithInitializer, "BindingWithInitializer",                         \
    BINDING_WITH_INITIALIZER)                                                 \
  F(Block, "Block", BLOCK)                                                    \
  F(BreakStatement, "BreakStatement", BREAK_STATEMENT)                        \
  F(CallExpression, "CallExpression", CALL_EXPRESSION)                        \
  F(CatchClause, "CatchClause", CATCH_CLAUSE)                                 \
  F(ClassDeclaration, "ClassDeclaration", CLASS_DECLARATION)                  \
  F(ClassElement, "ClassElement", CLASS_ELEMENT)                              \
  F(ClassExpression, "ClassExpression", CLASS_EXPRESSION)                     \
  F(CompoundAssignmentExpression, "CompoundAssignmentExpression",             \
    COMPOUND_ASSIGNMENT_EXPRESSION)                                           \
  F(ComputedMemberAssignmentTarget, "ComputedMemberAssignmentTarget",         \
    COMPUTED_MEMBER_ASSIGNMENT_TARGET)                                        \
  F(ComputedMemberExpression, "ComputedMemberExpression",                     \
    COMPUTED_MEMBER_EXPRESSION)                                               \
  F(ComputedPropertyName, "ComputedPropertyName", COMPUTED_PROPERTY_NAME)     \
  F(ConditionalExpression, "ConditionalExpression", CONDITIONAL_EXPRESSION)   \
  F(ContinueStatement, "ContinueStatement", CONTINUE_STATEMENT)               \
  F(DataProperty, "DataProperty", DATA_PROPERTY)                              \
  F(DebuggerStatement, "DebuggerStatement", DEBUGGER_STATEMENT)               \
  F(Directive, "Directive", DIRECTIVE)                                        \
  F(DoWhileStatement, "DoWhileStatement", DO_WHILE_STATEMENT)                 \
  F(EagerArrowExpressionWithExpression, "EagerArrowExpressionWithExpression", \
    EAGER_ARROW_EXPRESSION_WITH_EXPRESSION)                                   \
  F(EagerArrowExpressionWithFunctionBody,                                     \
    "EagerArrowExpressionWithFunctionBody",                                   \
    EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY)                                \
  F(EagerFunctionDeclaration, "EagerFunctionDeclaration",                     \
    EAGER_FUNCTION_DECLARATION)                                               \
  F(EagerFunctionExpression, "EagerFunctionExpression",                       \
    EAGER_FUNCTION_EXPRESSION)                                                \
  F(EagerGetter, "EagerGetter", EAGER_GETTER)                                 \
  F(EagerMethod, "EagerMethod", EAGER_METHOD)                                 \
  F(EagerSetter, "EagerSetter", EAGER_SETTER)                                 \
  F(EmptyStatement, "EmptyStatement", EMPTY_STATEMENT)                        \
  F(Export, "Export", EXPORT)                                                 \
  F(ExportAllFrom, "ExportAllFrom", EXPORT_ALL_FROM)                          \
  F(ExportDefault, "ExportDefault", EXPORT_DEFAULT)                           \
  F(ExportFrom, "ExportFrom", EXPORT_FROM)                                    \
  F(ExportFromSpecifier, "ExportFromSpecifier", EXPORT_FROM_SPECIFIER)        \
  F(ExportLocalSpecifier, "ExportLocalSpecifier", EXPORT_LOCAL_SPECIFIER)     \
  F(ExportLocals, "ExportLocals", EXPORT_LOCALS)                              \
  F(ExpressionStatement, "ExpressionStatement", EXPRESSION_STATEMENT)         \
  F(ForInOfBinding, "ForInOfBinding", FOR_IN_OF_BINDING)                      \
  F(ForInStatement, "ForInStatement", FOR_IN_STATEMENT)                       \
  F(ForOfStatement, "ForOfStatement", FOR_OF_STATEMENT)                       \
  F(ForStatement, "ForStatement", FOR_STATEMENT)                              \
  F(FormalParameters, "FormalParameters", FORMAL_PARAMETERS)                  \
  F(FunctionExpressionContents, "FunctionExpressionContents",                 \
    FUNCTION_EXPRESSION_CONTENTS)                                             \
  F(FunctionOrMethodContents, "FunctionOrMethodContents",                     \
    FUNCTION_OR_METHOD_CONTENTS)                                              \
  F(GetterContents, "GetterContents", GETTER_CONTENTS)                        \
  F(IdentifierExpression, "IdentifierExpression", IDENTIFIER_EXPRESSION)      \
  F(IfStatement, "IfStatement", IF_STATEMENT)                                 \
  F(Import, "Import", IMPORT)                                                 \
  F(ImportNamespace, "ImportNamespace", IMPORT_NAMESPACE)                     \
  F(ImportSpecifier, "ImportSpecifier", IMPORT_SPECIFIER)                     \
  F(LabelledStatement, "LabelledStatement", LABELLED_STATEMENT)               \
  F(LazyArrowExpressionWithExpression, "LazyArrowExpressionWithExpression",   \
    LAZY_ARROW_EXPRESSION_WITH_EXPRESSION)                                    \
  F(LazyArrowExpressionWithFunctionBody,                                      \
    "LazyArrowExpressionWithFunctionBody",                                    \
    LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY)                                 \
  F(LazyFunctionDeclaration, "LazyFunctionDeclaration",                       \
    LAZY_FUNCTION_DECLARATION)                                                \
  F(LazyFunctionExpression, "LazyFunctionExpression",                         \
    LAZY_FUNCTION_EXPRESSION)                                                 \
  F(LazyGetter, "LazyGetter", LAZY_GETTER)                                    \
  F(LazyMethod, "LazyMethod", LAZY_METHOD)                                    \
  F(LazySetter, "LazySetter", LAZY_SETTER)                                    \
  F(LiteralBooleanExpression, "LiteralBooleanExpression",                     \
    LITERAL_BOOLEAN_EXPRESSION)                                               \
  F(LiteralInfinityExpression, "LiteralInfinityExpression",                   \
    LITERAL_INFINITY_EXPRESSION)                                              \
  F(LiteralNullExpression, "LiteralNullExpression", LITERAL_NULL_EXPRESSION)  \
  F(LiteralNumericExpression, "LiteralNumericExpression",                     \
    LITERAL_NUMERIC_EXPRESSION)                                               \
  F(LiteralPropertyName, "LiteralPropertyName", LITERAL_PROPERTY_NAME)        \
  F(LiteralRegExpExpression, "LiteralRegExpExpression",                       \
    LITERAL_REG_EXP_EXPRESSION)                                               \
  F(LiteralStringExpression, "LiteralStringExpression",                       \
    LITERAL_STRING_EXPRESSION)                                                \
  F(Module, "Module", MODULE)                                                 \
  F(NewExpression, "NewExpression", NEW_EXPRESSION)                           \
  F(NewTargetExpression, "NewTargetExpression", NEW_TARGET_EXPRESSION)        \
  F(ObjectAssignmentTarget, "ObjectAssignmentTarget",                         \
    OBJECT_ASSIGNMENT_TARGET)                                                 \
  F(ObjectBinding, "ObjectBinding", OBJECT_BINDING)                           \
  F(ObjectExpression, "ObjectExpression", OBJECT_EXPRESSION)                  \
  F(ReturnStatement, "ReturnStatement", RETURN_STATEMENT)                     \
  F(Script, "Script", SCRIPT)                                                 \
  F(SetterContents, "SetterContents", SETTER_CONTENTS)                        \
  F(ShorthandProperty, "ShorthandProperty", SHORTHAND_PROPERTY)               \
  F(SpreadElement, "SpreadElement", SPREAD_ELEMENT)                           \
  F(StaticMemberAssignmentTarget, "StaticMemberAssignmentTarget",             \
    STATIC_MEMBER_ASSIGNMENT_TARGET)                                          \
  F(StaticMemberExpression, "StaticMemberExpression",                         \
    STATIC_MEMBER_EXPRESSION)                                                 \
  F(Super, "Super", SUPER)                                                    \
  F(SwitchCase, "SwitchCase", SWITCH_CASE)                                    \
  F(SwitchDefault, "SwitchDefault", SWITCH_DEFAULT)                           \
  F(SwitchStatement, "SwitchStatement", SWITCH_STATEMENT)                     \
  F(SwitchStatementWithDefault, "SwitchStatementWithDefault",                 \
    SWITCH_STATEMENT_WITH_DEFAULT)                                            \
  F(TemplateElement, "TemplateElement", TEMPLATE_ELEMENT)                     \
  F(TemplateExpression, "TemplateExpression", TEMPLATE_EXPRESSION)            \
  F(ThisExpression, "ThisExpression", THIS_EXPRESSION)                        \
  F(ThrowStatement, "ThrowStatement", THROW_STATEMENT)                        \
  F(TryCatchStatement, "TryCatchStatement", TRY_CATCH_STATEMENT)              \
  F(TryFinallyStatement, "TryFinallyStatement", TRY_FINALLY_STATEMENT)        \
  F(UnaryExpression, "UnaryExpression", UNARY_EXPRESSION)                     \
  F(UpdateExpression, "UpdateExpression", UPDATE_EXPRESSION)                  \
  F(VariableDeclaration, "VariableDeclaration", VARIABLE_DECLARATION)         \
  F(VariableDeclarator, "VariableDeclarator", VARIABLE_DECLARATOR)            \
  F(WhileStatement, "WhileStatement", WHILE_STATEMENT)                        \
  F(WithStatement, "WithStatement", WITH_STATEMENT)                           \
  F(YieldExpression, "YieldExpression", YIELD_EXPRESSION)                     \
  F(YieldStarExpression, "YieldStarExpression", YIELD_STAR_EXPRESSION)

enum class BinASTKind : uint16_t {
#define EMIT_ENUM(name, _1, _2) name,
  FOR_EACH_BIN_KIND(EMIT_ENUM)
#undef EMIT_ENUM
};

// The number of distinct values of BinASTKind.
const size_t BINASTKIND_LIMIT = 120;

/**
 * The different fields of Binary AST nodes, as per the specifications of
 * Binary AST.
 *
 * Usage:
 *
 * ```c++
 * #define WITH_FIELD(CPP_NAME, SPEC_NAME) ...
 * FOR_EACH_BIN_FIELD(WITH_FIELD)
 * ```
 *
 * (sorted by alphabetical order)
 */
#define FOR_EACH_BIN_FIELD(F)                         \
  F(Alternate, "alternate")                           \
  F(Arguments, "arguments")                           \
  F(Binding, "binding")                               \
  F(BindingScope, "bindingScope")                     \
  F(Body, "body")                                     \
  F(BodyScope, "bodyScope")                           \
  F(BoundNames, "boundNames")                         \
  F(Callee, "callee")                                 \
  F(Cases, "cases")                                   \
  F(CatchClause, "catchClause")                       \
  F(Consequent, "consequent")                         \
  F(Contents, "contents")                             \
  F(ContentsSkip, "contents_skip")                    \
  F(Declaration, "declaration")                       \
  F(Declarators, "declarators")                       \
  F(DeclaredNames, "declaredNames")                   \
  F(DefaultBinding, "defaultBinding")                 \
  F(DefaultCase, "defaultCase")                       \
  F(Directives, "directives")                         \
  F(Discriminant, "discriminant")                     \
  F(Elements, "elements")                             \
  F(ExportedName, "exportedName")                     \
  F(Expression, "expression")                         \
  F(Finalizer, "finalizer")                           \
  F(Flags, "flags")                                   \
  F(HasDirectEval, "hasDirectEval")                   \
  F(Index, "index")                                   \
  F(Init, "init")                                     \
  F(IsAsync, "isAsync")                               \
  F(IsCaptured, "isCaptured")                         \
  F(IsFunctionNameCaptured, "isFunctionNameCaptured") \
  F(IsGenerator, "isGenerator")                       \
  F(IsPrefix, "isPrefix")                             \
  F(IsSimpleParameterList, "isSimpleParameterList")   \
  F(IsStatic, "isStatic")                             \
  F(IsThisCaptured, "isThisCaptured")                 \
  F(Items, "items")                                   \
  F(Kind, "kind")                                     \
  F(Label, "label")                                   \
  F(Left, "left")                                     \
  F(Length, "length")                                 \
  F(Method, "method")                                 \
  F(ModuleSpecifier, "moduleSpecifier")               \
  F(Name, "name")                                     \
  F(NamedExports, "namedExports")                     \
  F(NamedImports, "namedImports")                     \
  F(NamespaceBinding, "namespaceBinding")             \
  F(Object, "object")                                 \
  F(Operand, "operand")                               \
  F(Operator, "operator")                             \
  F(Param, "param")                                   \
  F(ParamNames, "paramNames")                         \
  F(ParameterScope, "parameterScope")                 \
  F(Params, "params")                                 \
  F(Pattern, "pattern")                               \
  F(PostDefaultCases, "postDefaultCases")             \
  F(PreDefaultCases, "preDefaultCases")               \
  F(Properties, "properties")                         \
  F(Property, "property")                             \
  F(RawValue, "rawValue")                             \
  F(Rest, "rest")                                     \
  F(Right, "right")                                   \
  F(Scope, "scope")                                   \
  F(Statements, "statements")                         \
  F(Super, "super")                                   \
  F(Tag, "tag")                                       \
  F(Test, "test")                                     \
  F(Update, "update")                                 \
  F(Value, "value")

enum class BinASTField : uint16_t {
#define EMIT_ENUM(name, _) name,
  FOR_EACH_BIN_FIELD(EMIT_ENUM)
#undef EMIT_ENUM
};

// The number of distinct values of BinASTField.
const size_t BINASTFIELD_LIMIT = 69;

#define FOR_EACH_BIN_INTERFACE_AND_FIELD(F)                                   \
  F(ArrayAssignmentTarget__Elements, "ArrayAssignmentTarget::elements")       \
  F(ArrayAssignmentTarget__Rest, "ArrayAssignmentTarget::rest")               \
  F(ArrayBinding__Elements, "ArrayBinding::elements")                         \
  F(ArrayBinding__Rest, "ArrayBinding::rest")                                 \
  F(ArrayExpression__Elements, "ArrayExpression::elements")                   \
  F(ArrowExpressionContentsWithExpression__ParameterScope,                    \
    "ArrowExpressionContentsWithExpression::parameterScope")                  \
  F(ArrowExpressionContentsWithExpression__Params,                            \
    "ArrowExpressionContentsWithExpression::params")                          \
  F(ArrowExpressionContentsWithExpression__BodyScope,                         \
    "ArrowExpressionContentsWithExpression::bodyScope")                       \
  F(ArrowExpressionContentsWithExpression__Body,                              \
    "ArrowExpressionContentsWithExpression::body")                            \
  F(ArrowExpressionContentsWithFunctionBody__ParameterScope,                  \
    "ArrowExpressionContentsWithFunctionBody::parameterScope")                \
  F(ArrowExpressionContentsWithFunctionBody__Params,                          \
    "ArrowExpressionContentsWithFunctionBody::params")                        \
  F(ArrowExpressionContentsWithFunctionBody__BodyScope,                       \
    "ArrowExpressionContentsWithFunctionBody::bodyScope")                     \
  F(ArrowExpressionContentsWithFunctionBody__Body,                            \
    "ArrowExpressionContentsWithFunctionBody::body")                          \
  F(AssertedBlockScope__DeclaredNames, "AssertedBlockScope::declaredNames")   \
  F(AssertedBlockScope__HasDirectEval, "AssertedBlockScope::hasDirectEval")   \
  F(AssertedBoundName__Name, "AssertedBoundName::name")                       \
  F(AssertedBoundName__IsCaptured, "AssertedBoundName::isCaptured")           \
  F(AssertedBoundNamesScope__BoundNames,                                      \
    "AssertedBoundNamesScope::boundNames")                                    \
  F(AssertedBoundNamesScope__HasDirectEval,                                   \
    "AssertedBoundNamesScope::hasDirectEval")                                 \
  F(AssertedDeclaredName__Name, "AssertedDeclaredName::name")                 \
  F(AssertedDeclaredName__Kind, "AssertedDeclaredName::kind")                 \
  F(AssertedDeclaredName__IsCaptured, "AssertedDeclaredName::isCaptured")     \
  F(AssertedParameterName__Name, "AssertedParameterName::name")               \
  F(AssertedParameterName__IsCaptured, "AssertedParameterName::isCaptured")   \
  F(AssertedParameterScope__ParamNames, "AssertedParameterScope::paramNames") \
  F(AssertedParameterScope__HasDirectEval,                                    \
    "AssertedParameterScope::hasDirectEval")                                  \
  F(AssertedParameterScope__IsSimpleParameterList,                            \
    "AssertedParameterScope::isSimpleParameterList")                          \
  F(AssertedPositionalParameterName__Index,                                   \
    "AssertedPositionalParameterName::index")                                 \
  F(AssertedPositionalParameterName__Name,                                    \
    "AssertedPositionalParameterName::name")                                  \
  F(AssertedPositionalParameterName__IsCaptured,                              \
    "AssertedPositionalParameterName::isCaptured")                            \
  F(AssertedRestParameterName__Name, "AssertedRestParameterName::name")       \
  F(AssertedRestParameterName__IsCaptured,                                    \
    "AssertedRestParameterName::isCaptured")                                  \
  F(AssertedScriptGlobalScope__DeclaredNames,                                 \
    "AssertedScriptGlobalScope::declaredNames")                               \
  F(AssertedScriptGlobalScope__HasDirectEval,                                 \
    "AssertedScriptGlobalScope::hasDirectEval")                               \
  F(AssertedVarScope__DeclaredNames, "AssertedVarScope::declaredNames")       \
  F(AssertedVarScope__HasDirectEval, "AssertedVarScope::hasDirectEval")       \
  F(AssignmentExpression__Binding, "AssignmentExpression::binding")           \
  F(AssignmentExpression__Expression, "AssignmentExpression::expression")     \
  F(AssignmentTargetIdentifier__Name, "AssignmentTargetIdentifier::name")     \
  F(AssignmentTargetPropertyIdentifier__Binding,                              \
    "AssignmentTargetPropertyIdentifier::binding")                            \
  F(AssignmentTargetPropertyIdentifier__Init,                                 \
    "AssignmentTargetPropertyIdentifier::init")                               \
  F(AssignmentTargetPropertyProperty__Name,                                   \
    "AssignmentTargetPropertyProperty::name")                                 \
  F(AssignmentTargetPropertyProperty__Binding,                                \
    "AssignmentTargetPropertyProperty::binding")                              \
  F(AssignmentTargetWithInitializer__Binding,                                 \
    "AssignmentTargetWithInitializer::binding")                               \
  F(AssignmentTargetWithInitializer__Init,                                    \
    "AssignmentTargetWithInitializer::init")                                  \
  F(AwaitExpression__Expression, "AwaitExpression::expression")               \
  F(BinaryExpression__Operator, "BinaryExpression::operator")                 \
  F(BinaryExpression__Left, "BinaryExpression::left")                         \
  F(BinaryExpression__Right, "BinaryExpression::right")                       \
  F(BindingIdentifier__Name, "BindingIdentifier::name")                       \
  F(BindingPropertyIdentifier__Binding, "BindingPropertyIdentifier::binding") \
  F(BindingPropertyIdentifier__Init, "BindingPropertyIdentifier::init")       \
  F(BindingPropertyProperty__Name, "BindingPropertyProperty::name")           \
  F(BindingPropertyProperty__Binding, "BindingPropertyProperty::binding")     \
  F(BindingWithInitializer__Binding, "BindingWithInitializer::binding")       \
  F(BindingWithInitializer__Init, "BindingWithInitializer::init")             \
  F(Block__Scope, "Block::scope")                                             \
  F(Block__Statements, "Block::statements")                                   \
  F(BreakStatement__Label, "BreakStatement::label")                           \
  F(CallExpression__Callee, "CallExpression::callee")                         \
  F(CallExpression__Arguments, "CallExpression::arguments")                   \
  F(CatchClause__BindingScope, "CatchClause::bindingScope")                   \
  F(CatchClause__Binding, "CatchClause::binding")                             \
  F(CatchClause__Body, "CatchClause::body")                                   \
  F(ClassDeclaration__Name, "ClassDeclaration::name")                         \
  F(ClassDeclaration__Super, "ClassDeclaration::super")                       \
  F(ClassDeclaration__Elements, "ClassDeclaration::elements")                 \
  F(ClassElement__IsStatic, "ClassElement::isStatic")                         \
  F(ClassElement__Method, "ClassElement::method")                             \
  F(ClassExpression__Name, "ClassExpression::name")                           \
  F(ClassExpression__Super, "ClassExpression::super")                         \
  F(ClassExpression__Elements, "ClassExpression::elements")                   \
  F(CompoundAssignmentExpression__Operator,                                   \
    "CompoundAssignmentExpression::operator")                                 \
  F(CompoundAssignmentExpression__Binding,                                    \
    "CompoundAssignmentExpression::binding")                                  \
  F(CompoundAssignmentExpression__Expression,                                 \
    "CompoundAssignmentExpression::expression")                               \
  F(ComputedMemberAssignmentTarget__Object,                                   \
    "ComputedMemberAssignmentTarget::object")                                 \
  F(ComputedMemberAssignmentTarget__Expression,                               \
    "ComputedMemberAssignmentTarget::expression")                             \
  F(ComputedMemberExpression__Object, "ComputedMemberExpression::object")     \
  F(ComputedMemberExpression__Expression,                                     \
    "ComputedMemberExpression::expression")                                   \
  F(ComputedPropertyName__Expression, "ComputedPropertyName::expression")     \
  F(ConditionalExpression__Test, "ConditionalExpression::test")               \
  F(ConditionalExpression__Consequent, "ConditionalExpression::consequent")   \
  F(ConditionalExpression__Alternate, "ConditionalExpression::alternate")     \
  F(ContinueStatement__Label, "ContinueStatement::label")                     \
  F(DataProperty__Name, "DataProperty::name")                                 \
  F(DataProperty__Expression, "DataProperty::expression")                     \
  F(Directive__RawValue, "Directive::rawValue")                               \
  F(DoWhileStatement__Test, "DoWhileStatement::test")                         \
  F(DoWhileStatement__Body, "DoWhileStatement::body")                         \
  F(EagerArrowExpressionWithExpression__IsAsync,                              \
    "EagerArrowExpressionWithExpression::isAsync")                            \
  F(EagerArrowExpressionWithExpression__Length,                               \
    "EagerArrowExpressionWithExpression::length")                             \
  F(EagerArrowExpressionWithExpression__Contents,                             \
    "EagerArrowExpressionWithExpression::contents")                           \
  F(EagerArrowExpressionWithFunctionBody__IsAsync,                            \
    "EagerArrowExpressionWithFunctionBody::isAsync")                          \
  F(EagerArrowExpressionWithFunctionBody__Length,                             \
    "EagerArrowExpressionWithFunctionBody::length")                           \
  F(EagerArrowExpressionWithFunctionBody__Directives,                         \
    "EagerArrowExpressionWithFunctionBody::directives")                       \
  F(EagerArrowExpressionWithFunctionBody__Contents,                           \
    "EagerArrowExpressionWithFunctionBody::contents")                         \
  F(EagerFunctionDeclaration__IsAsync, "EagerFunctionDeclaration::isAsync")   \
  F(EagerFunctionDeclaration__IsGenerator,                                    \
    "EagerFunctionDeclaration::isGenerator")                                  \
  F(EagerFunctionDeclaration__Name, "EagerFunctionDeclaration::name")         \
  F(EagerFunctionDeclaration__Length, "EagerFunctionDeclaration::length")     \
  F(EagerFunctionDeclaration__Directives,                                     \
    "EagerFunctionDeclaration::directives")                                   \
  F(EagerFunctionDeclaration__Contents, "EagerFunctionDeclaration::contents") \
  F(EagerFunctionExpression__IsAsync, "EagerFunctionExpression::isAsync")     \
  F(EagerFunctionExpression__IsGenerator,                                     \
    "EagerFunctionExpression::isGenerator")                                   \
  F(EagerFunctionExpression__Name, "EagerFunctionExpression::name")           \
  F(EagerFunctionExpression__Length, "EagerFunctionExpression::length")       \
  F(EagerFunctionExpression__Directives,                                      \
    "EagerFunctionExpression::directives")                                    \
  F(EagerFunctionExpression__Contents, "EagerFunctionExpression::contents")   \
  F(EagerGetter__Name, "EagerGetter::name")                                   \
  F(EagerGetter__Directives, "EagerGetter::directives")                       \
  F(EagerGetter__Contents, "EagerGetter::contents")                           \
  F(EagerMethod__IsAsync, "EagerMethod::isAsync")                             \
  F(EagerMethod__IsGenerator, "EagerMethod::isGenerator")                     \
  F(EagerMethod__Name, "EagerMethod::name")                                   \
  F(EagerMethod__Length, "EagerMethod::length")                               \
  F(EagerMethod__Directives, "EagerMethod::directives")                       \
  F(EagerMethod__Contents, "EagerMethod::contents")                           \
  F(EagerSetter__Name, "EagerSetter::name")                                   \
  F(EagerSetter__Length, "EagerSetter::length")                               \
  F(EagerSetter__Directives, "EagerSetter::directives")                       \
  F(EagerSetter__Contents, "EagerSetter::contents")                           \
  F(Export__Declaration, "Export::declaration")                               \
  F(ExportAllFrom__ModuleSpecifier, "ExportAllFrom::moduleSpecifier")         \
  F(ExportDefault__Body, "ExportDefault::body")                               \
  F(ExportFrom__NamedExports, "ExportFrom::namedExports")                     \
  F(ExportFrom__ModuleSpecifier, "ExportFrom::moduleSpecifier")               \
  F(ExportFromSpecifier__Name, "ExportFromSpecifier::name")                   \
  F(ExportFromSpecifier__ExportedName, "ExportFromSpecifier::exportedName")   \
  F(ExportLocalSpecifier__Name, "ExportLocalSpecifier::name")                 \
  F(ExportLocalSpecifier__ExportedName, "ExportLocalSpecifier::exportedName") \
  F(ExportLocals__NamedExports, "ExportLocals::namedExports")                 \
  F(ExpressionStatement__Expression, "ExpressionStatement::expression")       \
  F(ForInOfBinding__Kind, "ForInOfBinding::kind")                             \
  F(ForInOfBinding__Binding, "ForInOfBinding::binding")                       \
  F(ForInStatement__Left, "ForInStatement::left")                             \
  F(ForInStatement__Right, "ForInStatement::right")                           \
  F(ForInStatement__Body, "ForInStatement::body")                             \
  F(ForOfStatement__Left, "ForOfStatement::left")                             \
  F(ForOfStatement__Right, "ForOfStatement::right")                           \
  F(ForOfStatement__Body, "ForOfStatement::body")                             \
  F(ForStatement__Init, "ForStatement::init")                                 \
  F(ForStatement__Test, "ForStatement::test")                                 \
  F(ForStatement__Update, "ForStatement::update")                             \
  F(ForStatement__Body, "ForStatement::body")                                 \
  F(FormalParameters__Items, "FormalParameters::items")                       \
  F(FormalParameters__Rest, "FormalParameters::rest")                         \
  F(FunctionExpressionContents__IsFunctionNameCaptured,                       \
    "FunctionExpressionContents::isFunctionNameCaptured")                     \
  F(FunctionExpressionContents__IsThisCaptured,                               \
    "FunctionExpressionContents::isThisCaptured")                             \
  F(FunctionExpressionContents__ParameterScope,                               \
    "FunctionExpressionContents::parameterScope")                             \
  F(FunctionExpressionContents__Params, "FunctionExpressionContents::params") \
  F(FunctionExpressionContents__BodyScope,                                    \
    "FunctionExpressionContents::bodyScope")                                  \
  F(FunctionExpressionContents__Body, "FunctionExpressionContents::body")     \
  F(FunctionOrMethodContents__IsThisCaptured,                                 \
    "FunctionOrMethodContents::isThisCaptured")                               \
  F(FunctionOrMethodContents__ParameterScope,                                 \
    "FunctionOrMethodContents::parameterScope")                               \
  F(FunctionOrMethodContents__Params, "FunctionOrMethodContents::params")     \
  F(FunctionOrMethodContents__BodyScope,                                      \
    "FunctionOrMethodContents::bodyScope")                                    \
  F(FunctionOrMethodContents__Body, "FunctionOrMethodContents::body")         \
  F(GetterContents__IsThisCaptured, "GetterContents::isThisCaptured")         \
  F(GetterContents__BodyScope, "GetterContents::bodyScope")                   \
  F(GetterContents__Body, "GetterContents::body")                             \
  F(IdentifierExpression__Name, "IdentifierExpression::name")                 \
  F(IfStatement__Test, "IfStatement::test")                                   \
  F(IfStatement__Consequent, "IfStatement::consequent")                       \
  F(IfStatement__Alternate, "IfStatement::alternate")                         \
  F(Import__ModuleSpecifier, "Import::moduleSpecifier")                       \
  F(Import__DefaultBinding, "Import::defaultBinding")                         \
  F(Import__NamedImports, "Import::namedImports")                             \
  F(ImportNamespace__ModuleSpecifier, "ImportNamespace::moduleSpecifier")     \
  F(ImportNamespace__DefaultBinding, "ImportNamespace::defaultBinding")       \
  F(ImportNamespace__NamespaceBinding, "ImportNamespace::namespaceBinding")   \
  F(ImportSpecifier__Name, "ImportSpecifier::name")                           \
  F(ImportSpecifier__Binding, "ImportSpecifier::binding")                     \
  F(LabelledStatement__Label, "LabelledStatement::label")                     \
  F(LabelledStatement__Body, "LabelledStatement::body")                       \
  F(LazyArrowExpressionWithExpression__IsAsync,                               \
    "LazyArrowExpressionWithExpression::isAsync")                             \
  F(LazyArrowExpressionWithExpression__Length,                                \
    "LazyArrowExpressionWithExpression::length")                              \
  F(LazyArrowExpressionWithExpression__ContentsSkip,                          \
    "LazyArrowExpressionWithExpression::contents_skip")                       \
  F(LazyArrowExpressionWithExpression__Contents,                              \
    "LazyArrowExpressionWithExpression::contents")                            \
  F(LazyArrowExpressionWithFunctionBody__IsAsync,                             \
    "LazyArrowExpressionWithFunctionBody::isAsync")                           \
  F(LazyArrowExpressionWithFunctionBody__Length,                              \
    "LazyArrowExpressionWithFunctionBody::length")                            \
  F(LazyArrowExpressionWithFunctionBody__Directives,                          \
    "LazyArrowExpressionWithFunctionBody::directives")                        \
  F(LazyArrowExpressionWithFunctionBody__ContentsSkip,                        \
    "LazyArrowExpressionWithFunctionBody::contents_skip")                     \
  F(LazyArrowExpressionWithFunctionBody__Contents,                            \
    "LazyArrowExpressionWithFunctionBody::contents")                          \
  F(LazyFunctionDeclaration__IsAsync, "LazyFunctionDeclaration::isAsync")     \
  F(LazyFunctionDeclaration__IsGenerator,                                     \
    "LazyFunctionDeclaration::isGenerator")                                   \
  F(LazyFunctionDeclaration__Name, "LazyFunctionDeclaration::name")           \
  F(LazyFunctionDeclaration__Length, "LazyFunctionDeclaration::length")       \
  F(LazyFunctionDeclaration__Directives,                                      \
    "LazyFunctionDeclaration::directives")                                    \
  F(LazyFunctionDeclaration__ContentsSkip,                                    \
    "LazyFunctionDeclaration::contents_skip")                                 \
  F(LazyFunctionDeclaration__Contents, "LazyFunctionDeclaration::contents")   \
  F(LazyFunctionExpression__IsAsync, "LazyFunctionExpression::isAsync")       \
  F(LazyFunctionExpression__IsGenerator,                                      \
    "LazyFunctionExpression::isGenerator")                                    \
  F(LazyFunctionExpression__Name, "LazyFunctionExpression::name")             \
  F(LazyFunctionExpression__Length, "LazyFunctionExpression::length")         \
  F(LazyFunctionExpression__Directives, "LazyFunctionExpression::directives") \
  F(LazyFunctionExpression__ContentsSkip,                                     \
    "LazyFunctionExpression::contents_skip")                                  \
  F(LazyFunctionExpression__Contents, "LazyFunctionExpression::contents")     \
  F(LazyGetter__Name, "LazyGetter::name")                                     \
  F(LazyGetter__Directives, "LazyGetter::directives")                         \
  F(LazyGetter__ContentsSkip, "LazyGetter::contents_skip")                    \
  F(LazyGetter__Contents, "LazyGetter::contents")                             \
  F(LazyMethod__IsAsync, "LazyMethod::isAsync")                               \
  F(LazyMethod__IsGenerator, "LazyMethod::isGenerator")                       \
  F(LazyMethod__Name, "LazyMethod::name")                                     \
  F(LazyMethod__Length, "LazyMethod::length")                                 \
  F(LazyMethod__Directives, "LazyMethod::directives")                         \
  F(LazyMethod__ContentsSkip, "LazyMethod::contents_skip")                    \
  F(LazyMethod__Contents, "LazyMethod::contents")                             \
  F(LazySetter__Name, "LazySetter::name")                                     \
  F(LazySetter__Length, "LazySetter::length")                                 \
  F(LazySetter__Directives, "LazySetter::directives")                         \
  F(LazySetter__ContentsSkip, "LazySetter::contents_skip")                    \
  F(LazySetter__Contents, "LazySetter::contents")                             \
  F(LiteralBooleanExpression__Value, "LiteralBooleanExpression::value")       \
  F(LiteralNumericExpression__Value, "LiteralNumericExpression::value")       \
  F(LiteralPropertyName__Value, "LiteralPropertyName::value")                 \
  F(LiteralRegExpExpression__Pattern, "LiteralRegExpExpression::pattern")     \
  F(LiteralRegExpExpression__Flags, "LiteralRegExpExpression::flags")         \
  F(LiteralStringExpression__Value, "LiteralStringExpression::value")         \
  F(Module__Scope, "Module::scope")                                           \
  F(Module__Directives, "Module::directives")                                 \
  F(Module__Items, "Module::items")                                           \
  F(NewExpression__Callee, "NewExpression::callee")                           \
  F(NewExpression__Arguments, "NewExpression::arguments")                     \
  F(ObjectAssignmentTarget__Properties, "ObjectAssignmentTarget::properties") \
  F(ObjectBinding__Properties, "ObjectBinding::properties")                   \
  F(ObjectExpression__Properties, "ObjectExpression::properties")             \
  F(ReturnStatement__Expression, "ReturnStatement::expression")               \
  F(Script__Scope, "Script::scope")                                           \
  F(Script__Directives, "Script::directives")                                 \
  F(Script__Statements, "Script::statements")                                 \
  F(SetterContents__IsThisCaptured, "SetterContents::isThisCaptured")         \
  F(SetterContents__ParameterScope, "SetterContents::parameterScope")         \
  F(SetterContents__Param, "SetterContents::param")                           \
  F(SetterContents__BodyScope, "SetterContents::bodyScope")                   \
  F(SetterContents__Body, "SetterContents::body")                             \
  F(ShorthandProperty__Name, "ShorthandProperty::name")                       \
  F(SpreadElement__Expression, "SpreadElement::expression")                   \
  F(StaticMemberAssignmentTarget__Object,                                     \
    "StaticMemberAssignmentTarget::object")                                   \
  F(StaticMemberAssignmentTarget__Property,                                   \
    "StaticMemberAssignmentTarget::property")                                 \
  F(StaticMemberExpression__Object, "StaticMemberExpression::object")         \
  F(StaticMemberExpression__Property, "StaticMemberExpression::property")     \
  F(SwitchCase__Test, "SwitchCase::test")                                     \
  F(SwitchCase__Consequent, "SwitchCase::consequent")                         \
  F(SwitchDefault__Consequent, "SwitchDefault::consequent")                   \
  F(SwitchStatement__Discriminant, "SwitchStatement::discriminant")           \
  F(SwitchStatement__Cases, "SwitchStatement::cases")                         \
  F(SwitchStatementWithDefault__Discriminant,                                 \
    "SwitchStatementWithDefault::discriminant")                               \
  F(SwitchStatementWithDefault__PreDefaultCases,                              \
    "SwitchStatementWithDefault::preDefaultCases")                            \
  F(SwitchStatementWithDefault__DefaultCase,                                  \
    "SwitchStatementWithDefault::defaultCase")                                \
  F(SwitchStatementWithDefault__PostDefaultCases,                             \
    "SwitchStatementWithDefault::postDefaultCases")                           \
  F(TemplateElement__RawValue, "TemplateElement::rawValue")                   \
  F(TemplateExpression__Tag, "TemplateExpression::tag")                       \
  F(TemplateExpression__Elements, "TemplateExpression::elements")             \
  F(ThrowStatement__Expression, "ThrowStatement::expression")                 \
  F(TryCatchStatement__Body, "TryCatchStatement::body")                       \
  F(TryCatchStatement__CatchClause, "TryCatchStatement::catchClause")         \
  F(TryFinallyStatement__Body, "TryFinallyStatement::body")                   \
  F(TryFinallyStatement__CatchClause, "TryFinallyStatement::catchClause")     \
  F(TryFinallyStatement__Finalizer, "TryFinallyStatement::finalizer")         \
  F(UnaryExpression__Operator, "UnaryExpression::operator")                   \
  F(UnaryExpression__Operand, "UnaryExpression::operand")                     \
  F(UpdateExpression__IsPrefix, "UpdateExpression::isPrefix")                 \
  F(UpdateExpression__Operator, "UpdateExpression::operator")                 \
  F(UpdateExpression__Operand, "UpdateExpression::operand")                   \
  F(VariableDeclaration__Kind, "VariableDeclaration::kind")                   \
  F(VariableDeclaration__Declarators, "VariableDeclaration::declarators")     \
  F(VariableDeclarator__Binding, "VariableDeclarator::binding")               \
  F(VariableDeclarator__Init, "VariableDeclarator::init")                     \
  F(WhileStatement__Test, "WhileStatement::test")                             \
  F(WhileStatement__Body, "WhileStatement::body")                             \
  F(WithStatement__Object, "WithStatement::object")                           \
  F(WithStatement__Body, "WithStatement::body")                               \
  F(YieldExpression__Expression, "YieldExpression::expression")               \
  F(YieldStarExpression__Expression, "YieldStarExpression::expression")

enum class BinASTInterfaceAndField : uint16_t {
#define EMIT_ENUM(name, _) name,
  FOR_EACH_BIN_INTERFACE_AND_FIELD(EMIT_ENUM)
#undef EMIT_ENUM
};

// Iteration through the interfaces of sum ArrowExpression
#define FOR_EACH_BIN_INTERFACE_IN_SUM_ARROW_EXPRESSION(F)     \
  F(ArrowExpression, 0, EagerArrowExpressionWithExpression,   \
    EAGER_ARROW_EXPRESSION_WITH_EXPRESSION,                   \
    "ArrowExpression::EagerArrowExpressionWithExpression")    \
  F(ArrowExpression, 1, EagerArrowExpressionWithFunctionBody, \
    EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                \
    "ArrowExpression::EagerArrowExpressionWithFunctionBody")  \
  F(ArrowExpression, 2, LazyArrowExpressionWithExpression,    \
    LAZY_ARROW_EXPRESSION_WITH_EXPRESSION,                    \
    "ArrowExpression::LazyArrowExpressionWithExpression")     \
  F(ArrowExpression, 3, LazyArrowExpressionWithFunctionBody,  \
    LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                 \
    "ArrowExpression::LazyArrowExpressionWithFunctionBody")

const size_t BINAST_SUM_ARROW_EXPRESSION_LIMIT = 4;

// Iteration through the interfaces of sum AssertedMaybePositionalParameterName
#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSERTED_MAYBE_POSITIONAL_PARAMETER_NAME( \
    F)                                                                          \
  F(AssertedMaybePositionalParameterName, 0, AssertedParameterName,             \
    ASSERTED_PARAMETER_NAME,                                                    \
    "AssertedMaybePositionalParameterName::AssertedParameterName")              \
  F(AssertedMaybePositionalParameterName, 1, AssertedPositionalParameterName,   \
    ASSERTED_POSITIONAL_PARAMETER_NAME,                                         \
    "AssertedMaybePositionalParameterName::AssertedPositionalParameterName")    \
  F(AssertedMaybePositionalParameterName, 2, AssertedRestParameterName,         \
    ASSERTED_REST_PARAMETER_NAME,                                               \
    "AssertedMaybePositionalParameterName::AssertedRestParameterName")

const size_t BINAST_SUM_ASSERTED_MAYBE_POSITIONAL_PARAMETER_NAME_LIMIT = 3;

// Iteration through the interfaces of sum AssignmentTarget
#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSIGNMENT_TARGET(F)                 \
  F(AssignmentTarget, 0, ArrayAssignmentTarget, ARRAY_ASSIGNMENT_TARGET,   \
    "AssignmentTarget::ArrayAssignmentTarget")                             \
  F(AssignmentTarget, 1, AssignmentTargetIdentifier,                       \
    ASSIGNMENT_TARGET_IDENTIFIER,                                          \
    "AssignmentTarget::AssignmentTargetIdentifier")                        \
  F(AssignmentTarget, 2, ComputedMemberAssignmentTarget,                   \
    COMPUTED_MEMBER_ASSIGNMENT_TARGET,                                     \
    "AssignmentTarget::ComputedMemberAssignmentTarget")                    \
  F(AssignmentTarget, 3, ObjectAssignmentTarget, OBJECT_ASSIGNMENT_TARGET, \
    "AssignmentTarget::ObjectAssignmentTarget")                            \
  F(AssignmentTarget, 4, StaticMemberAssignmentTarget,                     \
    STATIC_MEMBER_ASSIGNMENT_TARGET,                                       \
    "AssignmentTarget::StaticMemberAssignmentTarget")

const size_t BINAST_SUM_ASSIGNMENT_TARGET_LIMIT = 5;

// Iteration through the interfaces of sum
// AssignmentTargetOrAssignmentTargetWithInitializer
#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSIGNMENT_TARGET_OR_ASSIGNMENT_TARGET_WITH_INITIALIZER( \
    F)                                                                                         \
  F(AssignmentTargetOrAssignmentTargetWithInitializer, 0,                                      \
    ArrayAssignmentTarget, ARRAY_ASSIGNMENT_TARGET,                                            \
    "AssignmentTargetOrAssignmentTargetWithInitializer::"                                      \
    "ArrayAssignmentTarget")                                                                   \
  F(AssignmentTargetOrAssignmentTargetWithInitializer, 1,                                      \
    AssignmentTargetIdentifier, ASSIGNMENT_TARGET_IDENTIFIER,                                  \
    "AssignmentTargetOrAssignmentTargetWithInitializer::"                                      \
    "AssignmentTargetIdentifier")                                                              \
  F(AssignmentTargetOrAssignmentTargetWithInitializer, 2,                                      \
    AssignmentTargetWithInitializer, ASSIGNMENT_TARGET_WITH_INITIALIZER,                       \
    "AssignmentTargetOrAssignmentTargetWithInitializer::"                                      \
    "AssignmentTargetWithInitializer")                                                         \
  F(AssignmentTargetOrAssignmentTargetWithInitializer, 3,                                      \
    ComputedMemberAssignmentTarget, COMPUTED_MEMBER_ASSIGNMENT_TARGET,                         \
    "AssignmentTargetOrAssignmentTargetWithInitializer::"                                      \
    "ComputedMemberAssignmentTarget")                                                          \
  F(AssignmentTargetOrAssignmentTargetWithInitializer, 4,                                      \
    ObjectAssignmentTarget, OBJECT_ASSIGNMENT_TARGET,                                          \
    "AssignmentTargetOrAssignmentTargetWithInitializer::"                                      \
    "ObjectAssignmentTarget")                                                                  \
  F(AssignmentTargetOrAssignmentTargetWithInitializer, 5,                                      \
    StaticMemberAssignmentTarget, STATIC_MEMBER_ASSIGNMENT_TARGET,                             \
    "AssignmentTargetOrAssignmentTargetWithInitializer::"                                      \
    "StaticMemberAssignmentTarget")

const size_t
    BINAST_SUM_ASSIGNMENT_TARGET_OR_ASSIGNMENT_TARGET_WITH_INITIALIZER_LIMIT =
        6;

// Iteration through the interfaces of sum AssignmentTargetOrForInOfBinding
#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSIGNMENT_TARGET_OR_FOR_IN_OF_BINDING( \
    F)                                                                        \
  F(AssignmentTargetOrForInOfBinding, 0, ArrayAssignmentTarget,               \
    ARRAY_ASSIGNMENT_TARGET,                                                  \
    "AssignmentTargetOrForInOfBinding::ArrayAssignmentTarget")                \
  F(AssignmentTargetOrForInOfBinding, 1, AssignmentTargetIdentifier,          \
    ASSIGNMENT_TARGET_IDENTIFIER,                                             \
    "AssignmentTargetOrForInOfBinding::AssignmentTargetIdentifier")           \
  F(AssignmentTargetOrForInOfBinding, 2, ComputedMemberAssignmentTarget,      \
    COMPUTED_MEMBER_ASSIGNMENT_TARGET,                                        \
    "AssignmentTargetOrForInOfBinding::ComputedMemberAssignmentTarget")       \
  F(AssignmentTargetOrForInOfBinding, 3, ForInOfBinding, FOR_IN_OF_BINDING,   \
    "AssignmentTargetOrForInOfBinding::ForInOfBinding")                       \
  F(AssignmentTargetOrForInOfBinding, 4, ObjectAssignmentTarget,              \
    OBJECT_ASSIGNMENT_TARGET,                                                 \
    "AssignmentTargetOrForInOfBinding::ObjectAssignmentTarget")               \
  F(AssignmentTargetOrForInOfBinding, 5, StaticMemberAssignmentTarget,        \
    STATIC_MEMBER_ASSIGNMENT_TARGET,                                          \
    "AssignmentTargetOrForInOfBinding::StaticMemberAssignmentTarget")

const size_t BINAST_SUM_ASSIGNMENT_TARGET_OR_FOR_IN_OF_BINDING_LIMIT = 6;

// Iteration through the interfaces of sum AssignmentTargetPattern
#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSIGNMENT_TARGET_PATTERN(F)             \
  F(AssignmentTargetPattern, 0, ArrayAssignmentTarget,                         \
    ARRAY_ASSIGNMENT_TARGET, "AssignmentTargetPattern::ArrayAssignmentTarget") \
  F(AssignmentTargetPattern, 1, ObjectAssignmentTarget,                        \
    OBJECT_ASSIGNMENT_TARGET,                                                  \
    "AssignmentTargetPattern::ObjectAssignmentTarget")

const size_t BINAST_SUM_ASSIGNMENT_TARGET_PATTERN_LIMIT = 2;

// Iteration through the interfaces of sum AssignmentTargetProperty
#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSIGNMENT_TARGET_PROPERTY(F)  \
  F(AssignmentTargetProperty, 0, AssignmentTargetPropertyIdentifier, \
    ASSIGNMENT_TARGET_PROPERTY_IDENTIFIER,                           \
    "AssignmentTargetProperty::AssignmentTargetPropertyIdentifier")  \
  F(AssignmentTargetProperty, 1, AssignmentTargetPropertyProperty,   \
    ASSIGNMENT_TARGET_PROPERTY_PROPERTY,                             \
    "AssignmentTargetProperty::AssignmentTargetPropertyProperty")

const size_t BINAST_SUM_ASSIGNMENT_TARGET_PROPERTY_LIMIT = 2;

// Iteration through the interfaces of sum Binding
#define FOR_EACH_BIN_INTERFACE_IN_SUM_BINDING(F)                      \
  F(Binding, 0, ArrayBinding, ARRAY_BINDING, "Binding::ArrayBinding") \
  F(Binding, 1, BindingIdentifier, BINDING_IDENTIFIER,                \
    "Binding::BindingIdentifier")                                     \
  F(Binding, 2, ObjectBinding, OBJECT_BINDING, "Binding::ObjectBinding")

const size_t BINAST_SUM_BINDING_LIMIT = 3;

// Iteration through the interfaces of sum BindingOrBindingWithInitializer
#define FOR_EACH_BIN_INTERFACE_IN_SUM_BINDING_OR_BINDING_WITH_INITIALIZER(F)   \
  F(BindingOrBindingWithInitializer, 0, ArrayBinding, ARRAY_BINDING,           \
    "BindingOrBindingWithInitializer::ArrayBinding")                           \
  F(BindingOrBindingWithInitializer, 1, BindingIdentifier, BINDING_IDENTIFIER, \
    "BindingOrBindingWithInitializer::BindingIdentifier")                      \
  F(BindingOrBindingWithInitializer, 2, BindingWithInitializer,                \
    BINDING_WITH_INITIALIZER,                                                  \
    "BindingOrBindingWithInitializer::BindingWithInitializer")                 \
  F(BindingOrBindingWithInitializer, 3, ObjectBinding, OBJECT_BINDING,         \
    "BindingOrBindingWithInitializer::ObjectBinding")

const size_t BINAST_SUM_BINDING_OR_BINDING_WITH_INITIALIZER_LIMIT = 4;

// Iteration through the interfaces of sum BindingPattern
#define FOR_EACH_BIN_INTERFACE_IN_SUM_BINDING_PATTERN(F) \
  F(BindingPattern, 0, ArrayBinding, ARRAY_BINDING,      \
    "BindingPattern::ArrayBinding")                      \
  F(BindingPattern, 1, ObjectBinding, OBJECT_BINDING,    \
    "BindingPattern::ObjectBinding")

const size_t BINAST_SUM_BINDING_PATTERN_LIMIT = 2;

// Iteration through the interfaces of sum BindingProperty
#define FOR_EACH_BIN_INTERFACE_IN_SUM_BINDING_PROPERTY(F)                      \
  F(BindingProperty, 0, BindingPropertyIdentifier,                             \
    BINDING_PROPERTY_IDENTIFIER, "BindingProperty::BindingPropertyIdentifier") \
  F(BindingProperty, 1, BindingPropertyProperty, BINDING_PROPERTY_PROPERTY,    \
    "BindingProperty::BindingPropertyProperty")

const size_t BINAST_SUM_BINDING_PROPERTY_LIMIT = 2;

// Iteration through the interfaces of sum
// ClassDeclarationOrExpressionOrFunctionDeclaration
#define FOR_EACH_BIN_INTERFACE_IN_SUM_CLASS_DECLARATION_OR_EXPRESSION_OR_FUNCTION_DECLARATION( \
    F)                                                                                         \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 0, ArrayExpression,                     \
    ARRAY_EXPRESSION,                                                                          \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::ArrayExpression")                      \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 1,                                      \
    AssignmentExpression, ASSIGNMENT_EXPRESSION,                                               \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::AssignmentExpression")                 \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 2, AwaitExpression,                     \
    AWAIT_EXPRESSION,                                                                          \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::AwaitExpression")                      \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 3, BinaryExpression,                    \
    BINARY_EXPRESSION,                                                                         \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::BinaryExpression")                     \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 4, CallExpression,                      \
    CALL_EXPRESSION,                                                                           \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::CallExpression")                       \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 5, ClassDeclaration,                    \
    CLASS_DECLARATION,                                                                         \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::ClassDeclaration")                     \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 6, ClassExpression,                     \
    CLASS_EXPRESSION,                                                                          \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::ClassExpression")                      \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 7,                                      \
    CompoundAssignmentExpression, COMPOUND_ASSIGNMENT_EXPRESSION,                              \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "CompoundAssignmentExpression")                                                            \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 8,                                      \
    ComputedMemberExpression, COMPUTED_MEMBER_EXPRESSION,                                      \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "ComputedMemberExpression")                                                                \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 9,                                      \
    ConditionalExpression, CONDITIONAL_EXPRESSION,                                             \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "ConditionalExpression")                                                                   \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 10,                                     \
    EagerArrowExpressionWithExpression,                                                        \
    EAGER_ARROW_EXPRESSION_WITH_EXPRESSION,                                                    \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "EagerArrowExpressionWithExpression")                                                      \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 11,                                     \
    EagerArrowExpressionWithFunctionBody,                                                      \
    EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                                                 \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "EagerArrowExpressionWithFunctionBody")                                                    \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 12,                                     \
    EagerFunctionDeclaration, EAGER_FUNCTION_DECLARATION,                                      \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "EagerFunctionDeclaration")                                                                \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 13,                                     \
    EagerFunctionExpression, EAGER_FUNCTION_EXPRESSION,                                        \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "EagerFunctionExpression")                                                                 \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 14,                                     \
    IdentifierExpression, IDENTIFIER_EXPRESSION,                                               \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::IdentifierExpression")                 \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 15,                                     \
    LazyArrowExpressionWithExpression, LAZY_ARROW_EXPRESSION_WITH_EXPRESSION,                  \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "LazyArrowExpressionWithExpression")                                                       \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 16,                                     \
    LazyArrowExpressionWithFunctionBody,                                                       \
    LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                                                  \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "LazyArrowExpressionWithFunctionBody")                                                     \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 17,                                     \
    LazyFunctionDeclaration, LAZY_FUNCTION_DECLARATION,                                        \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "LazyFunctionDeclaration")                                                                 \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 18,                                     \
    LazyFunctionExpression, LAZY_FUNCTION_EXPRESSION,                                          \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "LazyFunctionExpression")                                                                  \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 19,                                     \
    LiteralBooleanExpression, LITERAL_BOOLEAN_EXPRESSION,                                      \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "LiteralBooleanExpression")                                                                \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 20,                                     \
    LiteralInfinityExpression, LITERAL_INFINITY_EXPRESSION,                                    \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "LiteralInfinityExpression")                                                               \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 21,                                     \
    LiteralNullExpression, LITERAL_NULL_EXPRESSION,                                            \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "LiteralNullExpression")                                                                   \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 22,                                     \
    LiteralNumericExpression, LITERAL_NUMERIC_EXPRESSION,                                      \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "LiteralNumericExpression")                                                                \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 23,                                     \
    LiteralRegExpExpression, LITERAL_REG_EXP_EXPRESSION,                                       \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "LiteralRegExpExpression")                                                                 \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 24,                                     \
    LiteralStringExpression, LITERAL_STRING_EXPRESSION,                                        \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "LiteralStringExpression")                                                                 \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 25, NewExpression,                      \
    NEW_EXPRESSION,                                                                            \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::NewExpression")                        \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 26,                                     \
    NewTargetExpression, NEW_TARGET_EXPRESSION,                                                \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::NewTargetExpression")                  \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 27, ObjectExpression,                   \
    OBJECT_EXPRESSION,                                                                         \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::ObjectExpression")                     \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 28,                                     \
    StaticMemberExpression, STATIC_MEMBER_EXPRESSION,                                          \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::"                                      \
    "StaticMemberExpression")                                                                  \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 29, TemplateExpression,                 \
    TEMPLATE_EXPRESSION,                                                                       \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::TemplateExpression")                   \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 30, ThisExpression,                     \
    THIS_EXPRESSION,                                                                           \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::ThisExpression")                       \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 31, UnaryExpression,                    \
    UNARY_EXPRESSION,                                                                          \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::UnaryExpression")                      \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 32, UpdateExpression,                   \
    UPDATE_EXPRESSION,                                                                         \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::UpdateExpression")                     \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 33, YieldExpression,                    \
    YIELD_EXPRESSION,                                                                          \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::YieldExpression")                      \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration, 34,                                     \
    YieldStarExpression, YIELD_STAR_EXPRESSION,                                                \
    "ClassDeclarationOrExpressionOrFunctionDeclaration::YieldStarExpression")

const size_t
    BINAST_SUM_CLASS_DECLARATION_OR_EXPRESSION_OR_FUNCTION_DECLARATION_LIMIT =
        35;

// Iteration through the interfaces of sum
// ClassDeclarationOrFunctionDeclarationOrVariableDeclaration
#define FOR_EACH_BIN_INTERFACE_IN_SUM_CLASS_DECLARATION_OR_FUNCTION_DECLARATION_OR_VARIABLE_DECLARATION( \
    F)                                                                                                   \
  F(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration, 0,                                       \
    ClassDeclaration, CLASS_DECLARATION,                                                                 \
    "ClassDeclarationOrFunctionDeclarationOrVariableDeclaration::"                                       \
    "ClassDeclaration")                                                                                  \
  F(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration, 1,                                       \
    EagerFunctionDeclaration, EAGER_FUNCTION_DECLARATION,                                                \
    "ClassDeclarationOrFunctionDeclarationOrVariableDeclaration::"                                       \
    "EagerFunctionDeclaration")                                                                          \
  F(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration, 2,                                       \
    LazyFunctionDeclaration, LAZY_FUNCTION_DECLARATION,                                                  \
    "ClassDeclarationOrFunctionDeclarationOrVariableDeclaration::"                                       \
    "LazyFunctionDeclaration")                                                                           \
  F(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration, 3,                                       \
    VariableDeclaration, VARIABLE_DECLARATION,                                                           \
    "ClassDeclarationOrFunctionDeclarationOrVariableDeclaration::"                                       \
    "VariableDeclaration")

const size_t
    BINAST_SUM_CLASS_DECLARATION_OR_FUNCTION_DECLARATION_OR_VARIABLE_DECLARATION_LIMIT =
        4;

// Iteration through the interfaces of sum ExportDeclaration
#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPORT_DECLARATION(F)            \
  F(ExportDeclaration, 0, Export, EXPORT, "ExportDeclaration::Export") \
  F(ExportDeclaration, 1, ExportAllFrom, EXPORT_ALL_FROM,              \
    "ExportDeclaration::ExportAllFrom")                                \
  F(ExportDeclaration, 2, ExportDefault, EXPORT_DEFAULT,               \
    "ExportDeclaration::ExportDefault")                                \
  F(ExportDeclaration, 3, ExportFrom, EXPORT_FROM,                     \
    "ExportDeclaration::ExportFrom")                                   \
  F(ExportDeclaration, 4, ExportLocals, EXPORT_LOCALS,                 \
    "ExportDeclaration::ExportLocals")

const size_t BINAST_SUM_EXPORT_DECLARATION_LIMIT = 5;

// Iteration through the interfaces of sum
// ExportDeclarationOrImportDeclarationOrStatement
#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPORT_DECLARATION_OR_IMPORT_DECLARATION_OR_STATEMENT( \
    F)                                                                                       \
  F(ExportDeclarationOrImportDeclarationOrStatement, 0, Block, BLOCK,                        \
    "ExportDeclarationOrImportDeclarationOrStatement::Block")                                \
  F(ExportDeclarationOrImportDeclarationOrStatement, 1, BreakStatement,                      \
    BREAK_STATEMENT,                                                                         \
    "ExportDeclarationOrImportDeclarationOrStatement::BreakStatement")                       \
  F(ExportDeclarationOrImportDeclarationOrStatement, 2, ClassDeclaration,                    \
    CLASS_DECLARATION,                                                                       \
    "ExportDeclarationOrImportDeclarationOrStatement::ClassDeclaration")                     \
  F(ExportDeclarationOrImportDeclarationOrStatement, 3, ContinueStatement,                   \
    CONTINUE_STATEMENT,                                                                      \
    "ExportDeclarationOrImportDeclarationOrStatement::ContinueStatement")                    \
  F(ExportDeclarationOrImportDeclarationOrStatement, 4, DebuggerStatement,                   \
    DEBUGGER_STATEMENT,                                                                      \
    "ExportDeclarationOrImportDeclarationOrStatement::DebuggerStatement")                    \
  F(ExportDeclarationOrImportDeclarationOrStatement, 5, DoWhileStatement,                    \
    DO_WHILE_STATEMENT,                                                                      \
    "ExportDeclarationOrImportDeclarationOrStatement::DoWhileStatement")                     \
  F(ExportDeclarationOrImportDeclarationOrStatement, 6,                                      \
    EagerFunctionDeclaration, EAGER_FUNCTION_DECLARATION,                                    \
    "ExportDeclarationOrImportDeclarationOrStatement::"                                      \
    "EagerFunctionDeclaration")                                                              \
  F(ExportDeclarationOrImportDeclarationOrStatement, 7, EmptyStatement,                      \
    EMPTY_STATEMENT,                                                                         \
    "ExportDeclarationOrImportDeclarationOrStatement::EmptyStatement")                       \
  F(ExportDeclarationOrImportDeclarationOrStatement, 8, Export, EXPORT,                      \
    "ExportDeclarationOrImportDeclarationOrStatement::Export")                               \
  F(ExportDeclarationOrImportDeclarationOrStatement, 9, ExportAllFrom,                       \
    EXPORT_ALL_FROM,                                                                         \
    "ExportDeclarationOrImportDeclarationOrStatement::ExportAllFrom")                        \
  F(ExportDeclarationOrImportDeclarationOrStatement, 10, ExportDefault,                      \
    EXPORT_DEFAULT,                                                                          \
    "ExportDeclarationOrImportDeclarationOrStatement::ExportDefault")                        \
  F(ExportDeclarationOrImportDeclarationOrStatement, 11, ExportFrom,                         \
    EXPORT_FROM,                                                                             \
    "ExportDeclarationOrImportDeclarationOrStatement::ExportFrom")                           \
  F(ExportDeclarationOrImportDeclarationOrStatement, 12, ExportLocals,                       \
    EXPORT_LOCALS,                                                                           \
    "ExportDeclarationOrImportDeclarationOrStatement::ExportLocals")                         \
  F(ExportDeclarationOrImportDeclarationOrStatement, 13, ExpressionStatement,                \
    EXPRESSION_STATEMENT,                                                                    \
    "ExportDeclarationOrImportDeclarationOrStatement::ExpressionStatement")                  \
  F(ExportDeclarationOrImportDeclarationOrStatement, 14, ForInStatement,                     \
    FOR_IN_STATEMENT,                                                                        \
    "ExportDeclarationOrImportDeclarationOrStatement::ForInStatement")                       \
  F(ExportDeclarationOrImportDeclarationOrStatement, 15, ForOfStatement,                     \
    FOR_OF_STATEMENT,                                                                        \
    "ExportDeclarationOrImportDeclarationOrStatement::ForOfStatement")                       \
  F(ExportDeclarationOrImportDeclarationOrStatement, 16, ForStatement,                       \
    FOR_STATEMENT,                                                                           \
    "ExportDeclarationOrImportDeclarationOrStatement::ForStatement")                         \
  F(ExportDeclarationOrImportDeclarationOrStatement, 17, IfStatement,                        \
    IF_STATEMENT,                                                                            \
    "ExportDeclarationOrImportDeclarationOrStatement::IfStatement")                          \
  F(ExportDeclarationOrImportDeclarationOrStatement, 18, Import, IMPORT,                     \
    "ExportDeclarationOrImportDeclarationOrStatement::Import")                               \
  F(ExportDeclarationOrImportDeclarationOrStatement, 19, ImportNamespace,                    \
    IMPORT_NAMESPACE,                                                                        \
    "ExportDeclarationOrImportDeclarationOrStatement::ImportNamespace")                      \
  F(ExportDeclarationOrImportDeclarationOrStatement, 20, LabelledStatement,                  \
    LABELLED_STATEMENT,                                                                      \
    "ExportDeclarationOrImportDeclarationOrStatement::LabelledStatement")                    \
  F(ExportDeclarationOrImportDeclarationOrStatement, 21,                                     \
    LazyFunctionDeclaration, LAZY_FUNCTION_DECLARATION,                                      \
    "ExportDeclarationOrImportDeclarationOrStatement::"                                      \
    "LazyFunctionDeclaration")                                                               \
  F(ExportDeclarationOrImportDeclarationOrStatement, 22, ReturnStatement,                    \
    RETURN_STATEMENT,                                                                        \
    "ExportDeclarationOrImportDeclarationOrStatement::ReturnStatement")                      \
  F(ExportDeclarationOrImportDeclarationOrStatement, 23, SwitchStatement,                    \
    SWITCH_STATEMENT,                                                                        \
    "ExportDeclarationOrImportDeclarationOrStatement::SwitchStatement")                      \
  F(ExportDeclarationOrImportDeclarationOrStatement, 24,                                     \
    SwitchStatementWithDefault, SWITCH_STATEMENT_WITH_DEFAULT,                               \
    "ExportDeclarationOrImportDeclarationOrStatement::"                                      \
    "SwitchStatementWithDefault")                                                            \
  F(ExportDeclarationOrImportDeclarationOrStatement, 25, ThrowStatement,                     \
    THROW_STATEMENT,                                                                         \
    "ExportDeclarationOrImportDeclarationOrStatement::ThrowStatement")                       \
  F(ExportDeclarationOrImportDeclarationOrStatement, 26, TryCatchStatement,                  \
    TRY_CATCH_STATEMENT,                                                                     \
    "ExportDeclarationOrImportDeclarationOrStatement::TryCatchStatement")                    \
  F(ExportDeclarationOrImportDeclarationOrStatement, 27, TryFinallyStatement,                \
    TRY_FINALLY_STATEMENT,                                                                   \
    "ExportDeclarationOrImportDeclarationOrStatement::TryFinallyStatement")                  \
  F(ExportDeclarationOrImportDeclarationOrStatement, 28, VariableDeclaration,                \
    VARIABLE_DECLARATION,                                                                    \
    "ExportDeclarationOrImportDeclarationOrStatement::VariableDeclaration")                  \
  F(ExportDeclarationOrImportDeclarationOrStatement, 29, WhileStatement,                     \
    WHILE_STATEMENT,                                                                         \
    "ExportDeclarationOrImportDeclarationOrStatement::WhileStatement")                       \
  F(ExportDeclarationOrImportDeclarationOrStatement, 30, WithStatement,                      \
    WITH_STATEMENT,                                                                          \
    "ExportDeclarationOrImportDeclarationOrStatement::WithStatement")

const size_t
    BINAST_SUM_EXPORT_DECLARATION_OR_IMPORT_DECLARATION_OR_STATEMENT_LIMIT = 31;

// Iteration through the interfaces of sum Expression
#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPRESSION(F)                         \
  F(Expression, 0, ArrayExpression, ARRAY_EXPRESSION,                       \
    "Expression::ArrayExpression")                                          \
  F(Expression, 1, AssignmentExpression, ASSIGNMENT_EXPRESSION,             \
    "Expression::AssignmentExpression")                                     \
  F(Expression, 2, AwaitExpression, AWAIT_EXPRESSION,                       \
    "Expression::AwaitExpression")                                          \
  F(Expression, 3, BinaryExpression, BINARY_EXPRESSION,                     \
    "Expression::BinaryExpression")                                         \
  F(Expression, 4, CallExpression, CALL_EXPRESSION,                         \
    "Expression::CallExpression")                                           \
  F(Expression, 5, ClassExpression, CLASS_EXPRESSION,                       \
    "Expression::ClassExpression")                                          \
  F(Expression, 6, CompoundAssignmentExpression,                            \
    COMPOUND_ASSIGNMENT_EXPRESSION,                                         \
    "Expression::CompoundAssignmentExpression")                             \
  F(Expression, 7, ComputedMemberExpression, COMPUTED_MEMBER_EXPRESSION,    \
    "Expression::ComputedMemberExpression")                                 \
  F(Expression, 8, ConditionalExpression, CONDITIONAL_EXPRESSION,           \
    "Expression::ConditionalExpression")                                    \
  F(Expression, 9, EagerArrowExpressionWithExpression,                      \
    EAGER_ARROW_EXPRESSION_WITH_EXPRESSION,                                 \
    "Expression::EagerArrowExpressionWithExpression")                       \
  F(Expression, 10, EagerArrowExpressionWithFunctionBody,                   \
    EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                              \
    "Expression::EagerArrowExpressionWithFunctionBody")                     \
  F(Expression, 11, EagerFunctionExpression, EAGER_FUNCTION_EXPRESSION,     \
    "Expression::EagerFunctionExpression")                                  \
  F(Expression, 12, IdentifierExpression, IDENTIFIER_EXPRESSION,            \
    "Expression::IdentifierExpression")                                     \
  F(Expression, 13, LazyArrowExpressionWithExpression,                      \
    LAZY_ARROW_EXPRESSION_WITH_EXPRESSION,                                  \
    "Expression::LazyArrowExpressionWithExpression")                        \
  F(Expression, 14, LazyArrowExpressionWithFunctionBody,                    \
    LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                               \
    "Expression::LazyArrowExpressionWithFunctionBody")                      \
  F(Expression, 15, LazyFunctionExpression, LAZY_FUNCTION_EXPRESSION,       \
    "Expression::LazyFunctionExpression")                                   \
  F(Expression, 16, LiteralBooleanExpression, LITERAL_BOOLEAN_EXPRESSION,   \
    "Expression::LiteralBooleanExpression")                                 \
  F(Expression, 17, LiteralInfinityExpression, LITERAL_INFINITY_EXPRESSION, \
    "Expression::LiteralInfinityExpression")                                \
  F(Expression, 18, LiteralNullExpression, LITERAL_NULL_EXPRESSION,         \
    "Expression::LiteralNullExpression")                                    \
  F(Expression, 19, LiteralNumericExpression, LITERAL_NUMERIC_EXPRESSION,   \
    "Expression::LiteralNumericExpression")                                 \
  F(Expression, 20, LiteralRegExpExpression, LITERAL_REG_EXP_EXPRESSION,    \
    "Expression::LiteralRegExpExpression")                                  \
  F(Expression, 21, LiteralStringExpression, LITERAL_STRING_EXPRESSION,     \
    "Expression::LiteralStringExpression")                                  \
  F(Expression, 22, NewExpression, NEW_EXPRESSION,                          \
    "Expression::NewExpression")                                            \
  F(Expression, 23, NewTargetExpression, NEW_TARGET_EXPRESSION,             \
    "Expression::NewTargetExpression")                                      \
  F(Expression, 24, ObjectExpression, OBJECT_EXPRESSION,                    \
    "Expression::ObjectExpression")                                         \
  F(Expression, 25, StaticMemberExpression, STATIC_MEMBER_EXPRESSION,       \
    "Expression::StaticMemberExpression")                                   \
  F(Expression, 26, TemplateExpression, TEMPLATE_EXPRESSION,                \
    "Expression::TemplateExpression")                                       \
  F(Expression, 27, ThisExpression, THIS_EXPRESSION,                        \
    "Expression::ThisExpression")                                           \
  F(Expression, 28, UnaryExpression, UNARY_EXPRESSION,                      \
    "Expression::UnaryExpression")                                          \
  F(Expression, 29, UpdateExpression, UPDATE_EXPRESSION,                    \
    "Expression::UpdateExpression")                                         \
  F(Expression, 30, YieldExpression, YIELD_EXPRESSION,                      \
    "Expression::YieldExpression")                                          \
  F(Expression, 31, YieldStarExpression, YIELD_STAR_EXPRESSION,             \
    "Expression::YieldStarExpression")

const size_t BINAST_SUM_EXPRESSION_LIMIT = 32;

// Iteration through the interfaces of sum ExpressionOrSpreadElement
#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPRESSION_OR_SPREAD_ELEMENT(F)          \
  F(ExpressionOrSpreadElement, 0, ArrayExpression, ARRAY_EXPRESSION,           \
    "ExpressionOrSpreadElement::ArrayExpression")                              \
  F(ExpressionOrSpreadElement, 1, AssignmentExpression, ASSIGNMENT_EXPRESSION, \
    "ExpressionOrSpreadElement::AssignmentExpression")                         \
  F(ExpressionOrSpreadElement, 2, AwaitExpression, AWAIT_EXPRESSION,           \
    "ExpressionOrSpreadElement::AwaitExpression")                              \
  F(ExpressionOrSpreadElement, 3, BinaryExpression, BINARY_EXPRESSION,         \
    "ExpressionOrSpreadElement::BinaryExpression")                             \
  F(ExpressionOrSpreadElement, 4, CallExpression, CALL_EXPRESSION,             \
    "ExpressionOrSpreadElement::CallExpression")                               \
  F(ExpressionOrSpreadElement, 5, ClassExpression, CLASS_EXPRESSION,           \
    "ExpressionOrSpreadElement::ClassExpression")                              \
  F(ExpressionOrSpreadElement, 6, CompoundAssignmentExpression,                \
    COMPOUND_ASSIGNMENT_EXPRESSION,                                            \
    "ExpressionOrSpreadElement::CompoundAssignmentExpression")                 \
  F(ExpressionOrSpreadElement, 7, ComputedMemberExpression,                    \
    COMPUTED_MEMBER_EXPRESSION,                                                \
    "ExpressionOrSpreadElement::ComputedMemberExpression")                     \
  F(ExpressionOrSpreadElement, 8, ConditionalExpression,                       \
    CONDITIONAL_EXPRESSION,                                                    \
    "ExpressionOrSpreadElement::ConditionalExpression")                        \
  F(ExpressionOrSpreadElement, 9, EagerArrowExpressionWithExpression,          \
    EAGER_ARROW_EXPRESSION_WITH_EXPRESSION,                                    \
    "ExpressionOrSpreadElement::EagerArrowExpressionWithExpression")           \
  F(ExpressionOrSpreadElement, 10, EagerArrowExpressionWithFunctionBody,       \
    EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                                 \
    "ExpressionOrSpreadElement::EagerArrowExpressionWithFunctionBody")         \
  F(ExpressionOrSpreadElement, 11, EagerFunctionExpression,                    \
    EAGER_FUNCTION_EXPRESSION,                                                 \
    "ExpressionOrSpreadElement::EagerFunctionExpression")                      \
  F(ExpressionOrSpreadElement, 12, IdentifierExpression,                       \
    IDENTIFIER_EXPRESSION, "ExpressionOrSpreadElement::IdentifierExpression")  \
  F(ExpressionOrSpreadElement, 13, LazyArrowExpressionWithExpression,          \
    LAZY_ARROW_EXPRESSION_WITH_EXPRESSION,                                     \
    "ExpressionOrSpreadElement::LazyArrowExpressionWithExpression")            \
  F(ExpressionOrSpreadElement, 14, LazyArrowExpressionWithFunctionBody,        \
    LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                                  \
    "ExpressionOrSpreadElement::LazyArrowExpressionWithFunctionBody")          \
  F(ExpressionOrSpreadElement, 15, LazyFunctionExpression,                     \
    LAZY_FUNCTION_EXPRESSION,                                                  \
    "ExpressionOrSpreadElement::LazyFunctionExpression")                       \
  F(ExpressionOrSpreadElement, 16, LiteralBooleanExpression,                   \
    LITERAL_BOOLEAN_EXPRESSION,                                                \
    "ExpressionOrSpreadElement::LiteralBooleanExpression")                     \
  F(ExpressionOrSpreadElement, 17, LiteralInfinityExpression,                  \
    LITERAL_INFINITY_EXPRESSION,                                               \
    "ExpressionOrSpreadElement::LiteralInfinityExpression")                    \
  F(ExpressionOrSpreadElement, 18, LiteralNullExpression,                      \
    LITERAL_NULL_EXPRESSION,                                                   \
    "ExpressionOrSpreadElement::LiteralNullExpression")                        \
  F(ExpressionOrSpreadElement, 19, LiteralNumericExpression,                   \
    LITERAL_NUMERIC_EXPRESSION,                                                \
    "ExpressionOrSpreadElement::LiteralNumericExpression")                     \
  F(ExpressionOrSpreadElement, 20, LiteralRegExpExpression,                    \
    LITERAL_REG_EXP_EXPRESSION,                                                \
    "ExpressionOrSpreadElement::LiteralRegExpExpression")                      \
  F(ExpressionOrSpreadElement, 21, LiteralStringExpression,                    \
    LITERAL_STRING_EXPRESSION,                                                 \
    "ExpressionOrSpreadElement::LiteralStringExpression")                      \
  F(ExpressionOrSpreadElement, 22, NewExpression, NEW_EXPRESSION,              \
    "ExpressionOrSpreadElement::NewExpression")                                \
  F(ExpressionOrSpreadElement, 23, NewTargetExpression, NEW_TARGET_EXPRESSION, \
    "ExpressionOrSpreadElement::NewTargetExpression")                          \
  F(ExpressionOrSpreadElement, 24, ObjectExpression, OBJECT_EXPRESSION,        \
    "ExpressionOrSpreadElement::ObjectExpression")                             \
  F(ExpressionOrSpreadElement, 25, SpreadElement, SPREAD_ELEMENT,              \
    "ExpressionOrSpreadElement::SpreadElement")                                \
  F(ExpressionOrSpreadElement, 26, StaticMemberExpression,                     \
    STATIC_MEMBER_EXPRESSION,                                                  \
    "ExpressionOrSpreadElement::StaticMemberExpression")                       \
  F(ExpressionOrSpreadElement, 27, TemplateExpression, TEMPLATE_EXPRESSION,    \
    "ExpressionOrSpreadElement::TemplateExpression")                           \
  F(ExpressionOrSpreadElement, 28, ThisExpression, THIS_EXPRESSION,            \
    "ExpressionOrSpreadElement::ThisExpression")                               \
  F(ExpressionOrSpreadElement, 29, UnaryExpression, UNARY_EXPRESSION,          \
    "ExpressionOrSpreadElement::UnaryExpression")                              \
  F(ExpressionOrSpreadElement, 30, UpdateExpression, UPDATE_EXPRESSION,        \
    "ExpressionOrSpreadElement::UpdateExpression")                             \
  F(ExpressionOrSpreadElement, 31, YieldExpression, YIELD_EXPRESSION,          \
    "ExpressionOrSpreadElement::YieldExpression")                              \
  F(ExpressionOrSpreadElement, 32, YieldStarExpression, YIELD_STAR_EXPRESSION, \
    "ExpressionOrSpreadElement::YieldStarExpression")

const size_t BINAST_SUM_EXPRESSION_OR_SPREAD_ELEMENT_LIMIT = 33;

// Iteration through the interfaces of sum ExpressionOrSuper
#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPRESSION_OR_SUPER(F)                   \
  F(ExpressionOrSuper, 0, ArrayExpression, ARRAY_EXPRESSION,                   \
    "ExpressionOrSuper::ArrayExpression")                                      \
  F(ExpressionOrSuper, 1, AssignmentExpression, ASSIGNMENT_EXPRESSION,         \
    "ExpressionOrSuper::AssignmentExpression")                                 \
  F(ExpressionOrSuper, 2, AwaitExpression, AWAIT_EXPRESSION,                   \
    "ExpressionOrSuper::AwaitExpression")                                      \
  F(ExpressionOrSuper, 3, BinaryExpression, BINARY_EXPRESSION,                 \
    "ExpressionOrSuper::BinaryExpression")                                     \
  F(ExpressionOrSuper, 4, CallExpression, CALL_EXPRESSION,                     \
    "ExpressionOrSuper::CallExpression")                                       \
  F(ExpressionOrSuper, 5, ClassExpression, CLASS_EXPRESSION,                   \
    "ExpressionOrSuper::ClassExpression")                                      \
  F(ExpressionOrSuper, 6, CompoundAssignmentExpression,                        \
    COMPOUND_ASSIGNMENT_EXPRESSION,                                            \
    "ExpressionOrSuper::CompoundAssignmentExpression")                         \
  F(ExpressionOrSuper, 7, ComputedMemberExpression,                            \
    COMPUTED_MEMBER_EXPRESSION, "ExpressionOrSuper::ComputedMemberExpression") \
  F(ExpressionOrSuper, 8, ConditionalExpression, CONDITIONAL_EXPRESSION,       \
    "ExpressionOrSuper::ConditionalExpression")                                \
  F(ExpressionOrSuper, 9, EagerArrowExpressionWithExpression,                  \
    EAGER_ARROW_EXPRESSION_WITH_EXPRESSION,                                    \
    "ExpressionOrSuper::EagerArrowExpressionWithExpression")                   \
  F(ExpressionOrSuper, 10, EagerArrowExpressionWithFunctionBody,               \
    EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                                 \
    "ExpressionOrSuper::EagerArrowExpressionWithFunctionBody")                 \
  F(ExpressionOrSuper, 11, EagerFunctionExpression, EAGER_FUNCTION_EXPRESSION, \
    "ExpressionOrSuper::EagerFunctionExpression")                              \
  F(ExpressionOrSuper, 12, IdentifierExpression, IDENTIFIER_EXPRESSION,        \
    "ExpressionOrSuper::IdentifierExpression")                                 \
  F(ExpressionOrSuper, 13, LazyArrowExpressionWithExpression,                  \
    LAZY_ARROW_EXPRESSION_WITH_EXPRESSION,                                     \
    "ExpressionOrSuper::LazyArrowExpressionWithExpression")                    \
  F(ExpressionOrSuper, 14, LazyArrowExpressionWithFunctionBody,                \
    LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                                  \
    "ExpressionOrSuper::LazyArrowExpressionWithFunctionBody")                  \
  F(ExpressionOrSuper, 15, LazyFunctionExpression, LAZY_FUNCTION_EXPRESSION,   \
    "ExpressionOrSuper::LazyFunctionExpression")                               \
  F(ExpressionOrSuper, 16, LiteralBooleanExpression,                           \
    LITERAL_BOOLEAN_EXPRESSION, "ExpressionOrSuper::LiteralBooleanExpression") \
  F(ExpressionOrSuper, 17, LiteralInfinityExpression,                          \
    LITERAL_INFINITY_EXPRESSION,                                               \
    "ExpressionOrSuper::LiteralInfinityExpression")                            \
  F(ExpressionOrSuper, 18, LiteralNullExpression, LITERAL_NULL_EXPRESSION,     \
    "ExpressionOrSuper::LiteralNullExpression")                                \
  F(ExpressionOrSuper, 19, LiteralNumericExpression,                           \
    LITERAL_NUMERIC_EXPRESSION, "ExpressionOrSuper::LiteralNumericExpression") \
  F(ExpressionOrSuper, 20, LiteralRegExpExpression,                            \
    LITERAL_REG_EXP_EXPRESSION, "ExpressionOrSuper::LiteralRegExpExpression")  \
  F(ExpressionOrSuper, 21, LiteralStringExpression, LITERAL_STRING_EXPRESSION, \
    "ExpressionOrSuper::LiteralStringExpression")                              \
  F(ExpressionOrSuper, 22, NewExpression, NEW_EXPRESSION,                      \
    "ExpressionOrSuper::NewExpression")                                        \
  F(ExpressionOrSuper, 23, NewTargetExpression, NEW_TARGET_EXPRESSION,         \
    "ExpressionOrSuper::NewTargetExpression")                                  \
  F(ExpressionOrSuper, 24, ObjectExpression, OBJECT_EXPRESSION,                \
    "ExpressionOrSuper::ObjectExpression")                                     \
  F(ExpressionOrSuper, 25, StaticMemberExpression, STATIC_MEMBER_EXPRESSION,   \
    "ExpressionOrSuper::StaticMemberExpression")                               \
  F(ExpressionOrSuper, 26, Super, SUPER, "ExpressionOrSuper::Super")           \
  F(ExpressionOrSuper, 27, TemplateExpression, TEMPLATE_EXPRESSION,            \
    "ExpressionOrSuper::TemplateExpression")                                   \
  F(ExpressionOrSuper, 28, ThisExpression, THIS_EXPRESSION,                    \
    "ExpressionOrSuper::ThisExpression")                                       \
  F(ExpressionOrSuper, 29, UnaryExpression, UNARY_EXPRESSION,                  \
    "ExpressionOrSuper::UnaryExpression")                                      \
  F(ExpressionOrSuper, 30, UpdateExpression, UPDATE_EXPRESSION,                \
    "ExpressionOrSuper::UpdateExpression")                                     \
  F(ExpressionOrSuper, 31, YieldExpression, YIELD_EXPRESSION,                  \
    "ExpressionOrSuper::YieldExpression")                                      \
  F(ExpressionOrSuper, 32, YieldStarExpression, YIELD_STAR_EXPRESSION,         \
    "ExpressionOrSuper::YieldStarExpression")

const size_t BINAST_SUM_EXPRESSION_OR_SUPER_LIMIT = 33;

// Iteration through the interfaces of sum ExpressionOrTemplateElement
#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPRESSION_OR_TEMPLATE_ELEMENT(F)        \
  F(ExpressionOrTemplateElement, 0, ArrayExpression, ARRAY_EXPRESSION,         \
    "ExpressionOrTemplateElement::ArrayExpression")                            \
  F(ExpressionOrTemplateElement, 1, AssignmentExpression,                      \
    ASSIGNMENT_EXPRESSION,                                                     \
    "ExpressionOrTemplateElement::AssignmentExpression")                       \
  F(ExpressionOrTemplateElement, 2, AwaitExpression, AWAIT_EXPRESSION,         \
    "ExpressionOrTemplateElement::AwaitExpression")                            \
  F(ExpressionOrTemplateElement, 3, BinaryExpression, BINARY_EXPRESSION,       \
    "ExpressionOrTemplateElement::BinaryExpression")                           \
  F(ExpressionOrTemplateElement, 4, CallExpression, CALL_EXPRESSION,           \
    "ExpressionOrTemplateElement::CallExpression")                             \
  F(ExpressionOrTemplateElement, 5, ClassExpression, CLASS_EXPRESSION,         \
    "ExpressionOrTemplateElement::ClassExpression")                            \
  F(ExpressionOrTemplateElement, 6, CompoundAssignmentExpression,              \
    COMPOUND_ASSIGNMENT_EXPRESSION,                                            \
    "ExpressionOrTemplateElement::CompoundAssignmentExpression")               \
  F(ExpressionOrTemplateElement, 7, ComputedMemberExpression,                  \
    COMPUTED_MEMBER_EXPRESSION,                                                \
    "ExpressionOrTemplateElement::ComputedMemberExpression")                   \
  F(ExpressionOrTemplateElement, 8, ConditionalExpression,                     \
    CONDITIONAL_EXPRESSION,                                                    \
    "ExpressionOrTemplateElement::ConditionalExpression")                      \
  F(ExpressionOrTemplateElement, 9, EagerArrowExpressionWithExpression,        \
    EAGER_ARROW_EXPRESSION_WITH_EXPRESSION,                                    \
    "ExpressionOrTemplateElement::EagerArrowExpressionWithExpression")         \
  F(ExpressionOrTemplateElement, 10, EagerArrowExpressionWithFunctionBody,     \
    EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                                 \
    "ExpressionOrTemplateElement::EagerArrowExpressionWithFunctionBody")       \
  F(ExpressionOrTemplateElement, 11, EagerFunctionExpression,                  \
    EAGER_FUNCTION_EXPRESSION,                                                 \
    "ExpressionOrTemplateElement::EagerFunctionExpression")                    \
  F(ExpressionOrTemplateElement, 12, IdentifierExpression,                     \
    IDENTIFIER_EXPRESSION,                                                     \
    "ExpressionOrTemplateElement::IdentifierExpression")                       \
  F(ExpressionOrTemplateElement, 13, LazyArrowExpressionWithExpression,        \
    LAZY_ARROW_EXPRESSION_WITH_EXPRESSION,                                     \
    "ExpressionOrTemplateElement::LazyArrowExpressionWithExpression")          \
  F(ExpressionOrTemplateElement, 14, LazyArrowExpressionWithFunctionBody,      \
    LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                                  \
    "ExpressionOrTemplateElement::LazyArrowExpressionWithFunctionBody")        \
  F(ExpressionOrTemplateElement, 15, LazyFunctionExpression,                   \
    LAZY_FUNCTION_EXPRESSION,                                                  \
    "ExpressionOrTemplateElement::LazyFunctionExpression")                     \
  F(ExpressionOrTemplateElement, 16, LiteralBooleanExpression,                 \
    LITERAL_BOOLEAN_EXPRESSION,                                                \
    "ExpressionOrTemplateElement::LiteralBooleanExpression")                   \
  F(ExpressionOrTemplateElement, 17, LiteralInfinityExpression,                \
    LITERAL_INFINITY_EXPRESSION,                                               \
    "ExpressionOrTemplateElement::LiteralInfinityExpression")                  \
  F(ExpressionOrTemplateElement, 18, LiteralNullExpression,                    \
    LITERAL_NULL_EXPRESSION,                                                   \
    "ExpressionOrTemplateElement::LiteralNullExpression")                      \
  F(ExpressionOrTemplateElement, 19, LiteralNumericExpression,                 \
    LITERAL_NUMERIC_EXPRESSION,                                                \
    "ExpressionOrTemplateElement::LiteralNumericExpression")                   \
  F(ExpressionOrTemplateElement, 20, LiteralRegExpExpression,                  \
    LITERAL_REG_EXP_EXPRESSION,                                                \
    "ExpressionOrTemplateElement::LiteralRegExpExpression")                    \
  F(ExpressionOrTemplateElement, 21, LiteralStringExpression,                  \
    LITERAL_STRING_EXPRESSION,                                                 \
    "ExpressionOrTemplateElement::LiteralStringExpression")                    \
  F(ExpressionOrTemplateElement, 22, NewExpression, NEW_EXPRESSION,            \
    "ExpressionOrTemplateElement::NewExpression")                              \
  F(ExpressionOrTemplateElement, 23, NewTargetExpression,                      \
    NEW_TARGET_EXPRESSION, "ExpressionOrTemplateElement::NewTargetExpression") \
  F(ExpressionOrTemplateElement, 24, ObjectExpression, OBJECT_EXPRESSION,      \
    "ExpressionOrTemplateElement::ObjectExpression")                           \
  F(ExpressionOrTemplateElement, 25, StaticMemberExpression,                   \
    STATIC_MEMBER_EXPRESSION,                                                  \
    "ExpressionOrTemplateElement::StaticMemberExpression")                     \
  F(ExpressionOrTemplateElement, 26, TemplateElement, TEMPLATE_ELEMENT,        \
    "ExpressionOrTemplateElement::TemplateElement")                            \
  F(ExpressionOrTemplateElement, 27, TemplateExpression, TEMPLATE_EXPRESSION,  \
    "ExpressionOrTemplateElement::TemplateExpression")                         \
  F(ExpressionOrTemplateElement, 28, ThisExpression, THIS_EXPRESSION,          \
    "ExpressionOrTemplateElement::ThisExpression")                             \
  F(ExpressionOrTemplateElement, 29, UnaryExpression, UNARY_EXPRESSION,        \
    "ExpressionOrTemplateElement::UnaryExpression")                            \
  F(ExpressionOrTemplateElement, 30, UpdateExpression, UPDATE_EXPRESSION,      \
    "ExpressionOrTemplateElement::UpdateExpression")                           \
  F(ExpressionOrTemplateElement, 31, YieldExpression, YIELD_EXPRESSION,        \
    "ExpressionOrTemplateElement::YieldExpression")                            \
  F(ExpressionOrTemplateElement, 32, YieldStarExpression,                      \
    YIELD_STAR_EXPRESSION, "ExpressionOrTemplateElement::YieldStarExpression")

const size_t BINAST_SUM_EXPRESSION_OR_TEMPLATE_ELEMENT_LIMIT = 33;

// Iteration through the interfaces of sum ExpressionOrVariableDeclaration
#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPRESSION_OR_VARIABLE_DECLARATION(F)    \
  F(ExpressionOrVariableDeclaration, 0, ArrayExpression, ARRAY_EXPRESSION,     \
    "ExpressionOrVariableDeclaration::ArrayExpression")                        \
  F(ExpressionOrVariableDeclaration, 1, AssignmentExpression,                  \
    ASSIGNMENT_EXPRESSION,                                                     \
    "ExpressionOrVariableDeclaration::AssignmentExpression")                   \
  F(ExpressionOrVariableDeclaration, 2, AwaitExpression, AWAIT_EXPRESSION,     \
    "ExpressionOrVariableDeclaration::AwaitExpression")                        \
  F(ExpressionOrVariableDeclaration, 3, BinaryExpression, BINARY_EXPRESSION,   \
    "ExpressionOrVariableDeclaration::BinaryExpression")                       \
  F(ExpressionOrVariableDeclaration, 4, CallExpression, CALL_EXPRESSION,       \
    "ExpressionOrVariableDeclaration::CallExpression")                         \
  F(ExpressionOrVariableDeclaration, 5, ClassExpression, CLASS_EXPRESSION,     \
    "ExpressionOrVariableDeclaration::ClassExpression")                        \
  F(ExpressionOrVariableDeclaration, 6, CompoundAssignmentExpression,          \
    COMPOUND_ASSIGNMENT_EXPRESSION,                                            \
    "ExpressionOrVariableDeclaration::CompoundAssignmentExpression")           \
  F(ExpressionOrVariableDeclaration, 7, ComputedMemberExpression,              \
    COMPUTED_MEMBER_EXPRESSION,                                                \
    "ExpressionOrVariableDeclaration::ComputedMemberExpression")               \
  F(ExpressionOrVariableDeclaration, 8, ConditionalExpression,                 \
    CONDITIONAL_EXPRESSION,                                                    \
    "ExpressionOrVariableDeclaration::ConditionalExpression")                  \
  F(ExpressionOrVariableDeclaration, 9, EagerArrowExpressionWithExpression,    \
    EAGER_ARROW_EXPRESSION_WITH_EXPRESSION,                                    \
    "ExpressionOrVariableDeclaration::EagerArrowExpressionWithExpression")     \
  F(ExpressionOrVariableDeclaration, 10, EagerArrowExpressionWithFunctionBody, \
    EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                                 \
    "ExpressionOrVariableDeclaration::EagerArrowExpressionWithFunctionBody")   \
  F(ExpressionOrVariableDeclaration, 11, EagerFunctionExpression,              \
    EAGER_FUNCTION_EXPRESSION,                                                 \
    "ExpressionOrVariableDeclaration::EagerFunctionExpression")                \
  F(ExpressionOrVariableDeclaration, 12, IdentifierExpression,                 \
    IDENTIFIER_EXPRESSION,                                                     \
    "ExpressionOrVariableDeclaration::IdentifierExpression")                   \
  F(ExpressionOrVariableDeclaration, 13, LazyArrowExpressionWithExpression,    \
    LAZY_ARROW_EXPRESSION_WITH_EXPRESSION,                                     \
    "ExpressionOrVariableDeclaration::LazyArrowExpressionWithExpression")      \
  F(ExpressionOrVariableDeclaration, 14, LazyArrowExpressionWithFunctionBody,  \
    LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY,                                  \
    "ExpressionOrVariableDeclaration::LazyArrowExpressionWithFunctionBody")    \
  F(ExpressionOrVariableDeclaration, 15, LazyFunctionExpression,               \
    LAZY_FUNCTION_EXPRESSION,                                                  \
    "ExpressionOrVariableDeclaration::LazyFunctionExpression")                 \
  F(ExpressionOrVariableDeclaration, 16, LiteralBooleanExpression,             \
    LITERAL_BOOLEAN_EXPRESSION,                                                \
    "ExpressionOrVariableDeclaration::LiteralBooleanExpression")               \
  F(ExpressionOrVariableDeclaration, 17, LiteralInfinityExpression,            \
    LITERAL_INFINITY_EXPRESSION,                                               \
    "ExpressionOrVariableDeclaration::LiteralInfinityExpression")              \
  F(ExpressionOrVariableDeclaration, 18, LiteralNullExpression,                \
    LITERAL_NULL_EXPRESSION,                                                   \
    "ExpressionOrVariableDeclaration::LiteralNullExpression")                  \
  F(ExpressionOrVariableDeclaration, 19, LiteralNumericExpression,             \
    LITERAL_NUMERIC_EXPRESSION,                                                \
    "ExpressionOrVariableDeclaration::LiteralNumericExpression")               \
  F(ExpressionOrVariableDeclaration, 20, LiteralRegExpExpression,              \
    LITERAL_REG_EXP_EXPRESSION,                                                \
    "ExpressionOrVariableDeclaration::LiteralRegExpExpression")                \
  F(ExpressionOrVariableDeclaration, 21, LiteralStringExpression,              \
    LITERAL_STRING_EXPRESSION,                                                 \
    "ExpressionOrVariableDeclaration::LiteralStringExpression")                \
  F(ExpressionOrVariableDeclaration, 22, NewExpression, NEW_EXPRESSION,        \
    "ExpressionOrVariableDeclaration::NewExpression")                          \
  F(ExpressionOrVariableDeclaration, 23, NewTargetExpression,                  \
    NEW_TARGET_EXPRESSION,                                                     \
    "ExpressionOrVariableDeclaration::NewTargetExpression")                    \
  F(ExpressionOrVariableDeclaration, 24, ObjectExpression, OBJECT_EXPRESSION,  \
    "ExpressionOrVariableDeclaration::ObjectExpression")                       \
  F(ExpressionOrVariableDeclaration, 25, StaticMemberExpression,               \
    STATIC_MEMBER_EXPRESSION,                                                  \
    "ExpressionOrVariableDeclaration::StaticMemberExpression")                 \
  F(ExpressionOrVariableDeclaration, 26, TemplateExpression,                   \
    TEMPLATE_EXPRESSION,                                                       \
    "ExpressionOrVariableDeclaration::TemplateExpression")                     \
  F(ExpressionOrVariableDeclaration, 27, ThisExpression, THIS_EXPRESSION,      \
    "ExpressionOrVariableDeclaration::ThisExpression")                         \
  F(ExpressionOrVariableDeclaration, 28, UnaryExpression, UNARY_EXPRESSION,    \
    "ExpressionOrVariableDeclaration::UnaryExpression")                        \
  F(ExpressionOrVariableDeclaration, 29, UpdateExpression, UPDATE_EXPRESSION,  \
    "ExpressionOrVariableDeclaration::UpdateExpression")                       \
  F(ExpressionOrVariableDeclaration, 30, VariableDeclaration,                  \
    VARIABLE_DECLARATION,                                                      \
    "ExpressionOrVariableDeclaration::VariableDeclaration")                    \
  F(ExpressionOrVariableDeclaration, 31, YieldExpression, YIELD_EXPRESSION,    \
    "ExpressionOrVariableDeclaration::YieldExpression")                        \
  F(ExpressionOrVariableDeclaration, 32, YieldStarExpression,                  \
    YIELD_STAR_EXPRESSION,                                                     \
    "ExpressionOrVariableDeclaration::YieldStarExpression")

const size_t BINAST_SUM_EXPRESSION_OR_VARIABLE_DECLARATION_LIMIT = 33;

// Iteration through the interfaces of sum FunctionDeclaration
#define FOR_EACH_BIN_INTERFACE_IN_SUM_FUNCTION_DECLARATION(F) \
  F(FunctionDeclaration, 0, EagerFunctionDeclaration,         \
    EAGER_FUNCTION_DECLARATION,                               \
    "FunctionDeclaration::EagerFunctionDeclaration")          \
  F(FunctionDeclaration, 1, LazyFunctionDeclaration,          \
    LAZY_FUNCTION_DECLARATION, "FunctionDeclaration::LazyFunctionDeclaration")

const size_t BINAST_SUM_FUNCTION_DECLARATION_LIMIT = 2;

// Iteration through the interfaces of sum FunctionExpression
#define FOR_EACH_BIN_INTERFACE_IN_SUM_FUNCTION_EXPRESSION(F)                   \
  F(FunctionExpression, 0, EagerFunctionExpression, EAGER_FUNCTION_EXPRESSION, \
    "FunctionExpression::EagerFunctionExpression")                             \
  F(FunctionExpression, 1, LazyFunctionExpression, LAZY_FUNCTION_EXPRESSION,   \
    "FunctionExpression::LazyFunctionExpression")

const size_t BINAST_SUM_FUNCTION_EXPRESSION_LIMIT = 2;

// Iteration through the interfaces of sum Getter
#define FOR_EACH_BIN_INTERFACE_IN_SUM_GETTER(F)                  \
  F(Getter, 0, EagerGetter, EAGER_GETTER, "Getter::EagerGetter") \
  F(Getter, 1, LazyGetter, LAZY_GETTER, "Getter::LazyGetter")

const size_t BINAST_SUM_GETTER_LIMIT = 2;

// Iteration through the interfaces of sum ImportDeclaration
#define FOR_EACH_BIN_INTERFACE_IN_SUM_IMPORT_DECLARATION(F)            \
  F(ImportDeclaration, 0, Import, IMPORT, "ImportDeclaration::Import") \
  F(ImportDeclaration, 1, ImportNamespace, IMPORT_NAMESPACE,           \
    "ImportDeclaration::ImportNamespace")

const size_t BINAST_SUM_IMPORT_DECLARATION_LIMIT = 2;

// Iteration through the interfaces of sum IterationStatement
#define FOR_EACH_BIN_INTERFACE_IN_SUM_ITERATION_STATEMENT(F)     \
  F(IterationStatement, 0, DoWhileStatement, DO_WHILE_STATEMENT, \
    "IterationStatement::DoWhileStatement")                      \
  F(IterationStatement, 1, ForInStatement, FOR_IN_STATEMENT,     \
    "IterationStatement::ForInStatement")                        \
  F(IterationStatement, 2, ForOfStatement, FOR_OF_STATEMENT,     \
    "IterationStatement::ForOfStatement")                        \
  F(IterationStatement, 3, ForStatement, FOR_STATEMENT,          \
    "IterationStatement::ForStatement")                          \
  F(IterationStatement, 4, WhileStatement, WHILE_STATEMENT,      \
    "IterationStatement::WhileStatement")

const size_t BINAST_SUM_ITERATION_STATEMENT_LIMIT = 5;

// Iteration through the interfaces of sum Literal
#define FOR_EACH_BIN_INTERFACE_IN_SUM_LITERAL(F)                        \
  F(Literal, 0, LiteralBooleanExpression, LITERAL_BOOLEAN_EXPRESSION,   \
    "Literal::LiteralBooleanExpression")                                \
  F(Literal, 1, LiteralInfinityExpression, LITERAL_INFINITY_EXPRESSION, \
    "Literal::LiteralInfinityExpression")                               \
  F(Literal, 2, LiteralNullExpression, LITERAL_NULL_EXPRESSION,         \
    "Literal::LiteralNullExpression")                                   \
  F(Literal, 3, LiteralNumericExpression, LITERAL_NUMERIC_EXPRESSION,   \
    "Literal::LiteralNumericExpression")                                \
  F(Literal, 4, LiteralStringExpression, LITERAL_STRING_EXPRESSION,     \
    "Literal::LiteralStringExpression")

const size_t BINAST_SUM_LITERAL_LIMIT = 5;

// Iteration through the interfaces of sum Method
#define FOR_EACH_BIN_INTERFACE_IN_SUM_METHOD(F)                  \
  F(Method, 0, EagerMethod, EAGER_METHOD, "Method::EagerMethod") \
  F(Method, 1, LazyMethod, LAZY_METHOD, "Method::LazyMethod")

const size_t BINAST_SUM_METHOD_LIMIT = 2;

// Iteration through the interfaces of sum MethodDefinition
#define FOR_EACH_BIN_INTERFACE_IN_SUM_METHOD_DEFINITION(F) \
  F(MethodDefinition, 0, EagerGetter, EAGER_GETTER,        \
    "MethodDefinition::EagerGetter")                       \
  F(MethodDefinition, 1, EagerMethod, EAGER_METHOD,        \
    "MethodDefinition::EagerMethod")                       \
  F(MethodDefinition, 2, EagerSetter, EAGER_SETTER,        \
    "MethodDefinition::EagerSetter")                       \
  F(MethodDefinition, 3, LazyGetter, LAZY_GETTER,          \
    "MethodDefinition::LazyGetter")                        \
  F(MethodDefinition, 4, LazyMethod, LAZY_METHOD,          \
    "MethodDefinition::LazyMethod")                        \
  F(MethodDefinition, 5, LazySetter, LAZY_SETTER,          \
    "MethodDefinition::LazySetter")

const size_t BINAST_SUM_METHOD_DEFINITION_LIMIT = 6;

// Iteration through the interfaces of sum ObjectProperty
#define FOR_EACH_BIN_INTERFACE_IN_SUM_OBJECT_PROPERTY(F)                      \
  F(ObjectProperty, 0, DataProperty, DATA_PROPERTY,                           \
    "ObjectProperty::DataProperty")                                           \
  F(ObjectProperty, 1, EagerGetter, EAGER_GETTER,                             \
    "ObjectProperty::EagerGetter")                                            \
  F(ObjectProperty, 2, EagerMethod, EAGER_METHOD,                             \
    "ObjectProperty::EagerMethod")                                            \
  F(ObjectProperty, 3, EagerSetter, EAGER_SETTER,                             \
    "ObjectProperty::EagerSetter")                                            \
  F(ObjectProperty, 4, LazyGetter, LAZY_GETTER, "ObjectProperty::LazyGetter") \
  F(ObjectProperty, 5, LazyMethod, LAZY_METHOD, "ObjectProperty::LazyMethod") \
  F(ObjectProperty, 6, LazySetter, LAZY_SETTER, "ObjectProperty::LazySetter") \
  F(ObjectProperty, 7, ShorthandProperty, SHORTHAND_PROPERTY,                 \
    "ObjectProperty::ShorthandProperty")

const size_t BINAST_SUM_OBJECT_PROPERTY_LIMIT = 8;

// Iteration through the interfaces of sum Parameter
#define FOR_EACH_BIN_INTERFACE_IN_SUM_PARAMETER(F)                        \
  F(Parameter, 0, ArrayBinding, ARRAY_BINDING, "Parameter::ArrayBinding") \
  F(Parameter, 1, BindingIdentifier, BINDING_IDENTIFIER,                  \
    "Parameter::BindingIdentifier")                                       \
  F(Parameter, 2, BindingWithInitializer, BINDING_WITH_INITIALIZER,       \
    "Parameter::BindingWithInitializer")                                  \
  F(Parameter, 3, ObjectBinding, OBJECT_BINDING, "Parameter::ObjectBinding")

const size_t BINAST_SUM_PARAMETER_LIMIT = 4;

// Iteration through the interfaces of sum Program
#define FOR_EACH_BIN_INTERFACE_IN_SUM_PROGRAM(F)   \
  F(Program, 0, Module, MODULE, "Program::Module") \
  F(Program, 1, Script, SCRIPT, "Program::Script")

const size_t BINAST_SUM_PROGRAM_LIMIT = 2;

// Iteration through the interfaces of sum PropertyName
#define FOR_EACH_BIN_INTERFACE_IN_SUM_PROPERTY_NAME(F)             \
  F(PropertyName, 0, ComputedPropertyName, COMPUTED_PROPERTY_NAME, \
    "PropertyName::ComputedPropertyName")                          \
  F(PropertyName, 1, LiteralPropertyName, LITERAL_PROPERTY_NAME,   \
    "PropertyName::LiteralPropertyName")

const size_t BINAST_SUM_PROPERTY_NAME_LIMIT = 2;

// Iteration through the interfaces of sum Setter
#define FOR_EACH_BIN_INTERFACE_IN_SUM_SETTER(F)                  \
  F(Setter, 0, EagerSetter, EAGER_SETTER, "Setter::EagerSetter") \
  F(Setter, 1, LazySetter, LAZY_SETTER, "Setter::LazySetter")

const size_t BINAST_SUM_SETTER_LIMIT = 2;

// Iteration through the interfaces of sum SimpleAssignmentTarget
#define FOR_EACH_BIN_INTERFACE_IN_SUM_SIMPLE_ASSIGNMENT_TARGET(F) \
  F(SimpleAssignmentTarget, 0, AssignmentTargetIdentifier,        \
    ASSIGNMENT_TARGET_IDENTIFIER,                                 \
    "SimpleAssignmentTarget::AssignmentTargetIdentifier")         \
  F(SimpleAssignmentTarget, 1, ComputedMemberAssignmentTarget,    \
    COMPUTED_MEMBER_ASSIGNMENT_TARGET,                            \
    "SimpleAssignmentTarget::ComputedMemberAssignmentTarget")     \
  F(SimpleAssignmentTarget, 2, StaticMemberAssignmentTarget,      \
    STATIC_MEMBER_ASSIGNMENT_TARGET,                              \
    "SimpleAssignmentTarget::StaticMemberAssignmentTarget")

const size_t BINAST_SUM_SIMPLE_ASSIGNMENT_TARGET_LIMIT = 3;

// Iteration through the interfaces of sum Statement
#define FOR_EACH_BIN_INTERFACE_IN_SUM_STATEMENT(F)                            \
  F(Statement, 0, Block, BLOCK, "Statement::Block")                           \
  F(Statement, 1, BreakStatement, BREAK_STATEMENT,                            \
    "Statement::BreakStatement")                                              \
  F(Statement, 2, ClassDeclaration, CLASS_DECLARATION,                        \
    "Statement::ClassDeclaration")                                            \
  F(Statement, 3, ContinueStatement, CONTINUE_STATEMENT,                      \
    "Statement::ContinueStatement")                                           \
  F(Statement, 4, DebuggerStatement, DEBUGGER_STATEMENT,                      \
    "Statement::DebuggerStatement")                                           \
  F(Statement, 5, DoWhileStatement, DO_WHILE_STATEMENT,                       \
    "Statement::DoWhileStatement")                                            \
  F(Statement, 6, EagerFunctionDeclaration, EAGER_FUNCTION_DECLARATION,       \
    "Statement::EagerFunctionDeclaration")                                    \
  F(Statement, 7, EmptyStatement, EMPTY_STATEMENT,                            \
    "Statement::EmptyStatement")                                              \
  F(Statement, 8, ExpressionStatement, EXPRESSION_STATEMENT,                  \
    "Statement::ExpressionStatement")                                         \
  F(Statement, 9, ForInStatement, FOR_IN_STATEMENT,                           \
    "Statement::ForInStatement")                                              \
  F(Statement, 10, ForOfStatement, FOR_OF_STATEMENT,                          \
    "Statement::ForOfStatement")                                              \
  F(Statement, 11, ForStatement, FOR_STATEMENT, "Statement::ForStatement")    \
  F(Statement, 12, IfStatement, IF_STATEMENT, "Statement::IfStatement")       \
  F(Statement, 13, LabelledStatement, LABELLED_STATEMENT,                     \
    "Statement::LabelledStatement")                                           \
  F(Statement, 14, LazyFunctionDeclaration, LAZY_FUNCTION_DECLARATION,        \
    "Statement::LazyFunctionDeclaration")                                     \
  F(Statement, 15, ReturnStatement, RETURN_STATEMENT,                         \
    "Statement::ReturnStatement")                                             \
  F(Statement, 16, SwitchStatement, SWITCH_STATEMENT,                         \
    "Statement::SwitchStatement")                                             \
  F(Statement, 17, SwitchStatementWithDefault, SWITCH_STATEMENT_WITH_DEFAULT, \
    "Statement::SwitchStatementWithDefault")                                  \
  F(Statement, 18, ThrowStatement, THROW_STATEMENT,                           \
    "Statement::ThrowStatement")                                              \
  F(Statement, 19, TryCatchStatement, TRY_CATCH_STATEMENT,                    \
    "Statement::TryCatchStatement")                                           \
  F(Statement, 20, TryFinallyStatement, TRY_FINALLY_STATEMENT,                \
    "Statement::TryFinallyStatement")                                         \
  F(Statement, 21, VariableDeclaration, VARIABLE_DECLARATION,                 \
    "Statement::VariableDeclaration")                                         \
  F(Statement, 22, WhileStatement, WHILE_STATEMENT,                           \
    "Statement::WhileStatement")                                              \
  F(Statement, 23, WithStatement, WITH_STATEMENT, "Statement::WithStatement")

const size_t BINAST_SUM_STATEMENT_LIMIT = 24;

// Strongly typed iterations through the fields of interfaces.
//
// Each of these macros accepts the following arguments:
// - F: callback
// - PRIMITIVE: wrapper for primitive type names - called as
// `PRIMITIVE(typename)`
// - INTERFACE: wrapper for non-optional interface type names - called as
// `INTERFACE(typename)`
// - OPTIONAL_INTERFACE: wrapper for optional interface type names - called as
// `OPTIONAL_INTERFACE(typename)` where
//      `typename` is the name of the interface (e.g. no `Maybe` prefix)
// - LIST: wrapper for list types - called as `LIST(list_typename,
// element_typename)`
// - SUM: wrapper for non-optional type names - called as `SUM(typename)`
// - OPTIONAL_SUM: wrapper for optional sum type names - called as
// `OPTIONAL_SUM(typename)` where
//      `typename` is the name of the sum (e.g. no `Maybe` prefix)
// - STRING_ENUM: wrapper for non-optional string enum types - called as
// `STRING_ENUNM(typename)`
// - OPTIONAL_STRING_ENUM: wrapper for optional string enum type names - called
// as `OPTIONAL_STRING_ENUM(typename)` where
//      `typename` is the name of the string enum (e.g. no `Maybe` prefix)
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_UNINITIALIZED(                    \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)

// Strongly typed iteration through the fields of interface _Null.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_NULL(                             \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)

// The number of fields of interface .
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_NULL = 0;

// Strongly typed iteration through the fields of interface
// ArrayAssignmentTarget.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ARRAY_ASSIGNMENT_TARGET(          \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ArrayAssignmentTarget, Elements, 0,                                   \
    LIST(ListOfAssignmentTargetOrAssignmentTargetWithInitializer,         \
         SUM(AssignmentTargetOrAssignmentTargetWithInitializer)),         \
    "ArrayAssignmentTarget::elements")                                    \
  F(ArrayAssignmentTarget, Rest, 1, OPTIONAL_SUM(AssignmentTarget),       \
    "ArrayAssignmentTarget::rest")

// The number of fields of interface ArrayAssignmentTarget.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ARRAY_ASSIGNMENT_TARGET = 2;

// Strongly typed iteration through the fields of interface ArrayBinding.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ARRAY_BINDING(                    \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ArrayBinding, Elements, 0,                                            \
    LIST(ListOfOptionalBindingOrBindingWithInitializer,                   \
         OPTIONAL_SUM(BindingOrBindingWithInitializer)),                  \
    "ArrayBinding::elements")                                             \
  F(ArrayBinding, Rest, 1, OPTIONAL_SUM(Binding), "ArrayBinding::rest")

// The number of fields of interface ArrayBinding.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ARRAY_BINDING = 2;

// Strongly typed iteration through the fields of interface ArrayExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ARRAY_EXPRESSION(                 \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ArrayExpression, Elements, 0,                                         \
    LIST(ListOfOptionalExpressionOrSpreadElement,                         \
         OPTIONAL_SUM(ExpressionOrSpreadElement)),                        \
    "ArrayExpression::elements")

// The number of fields of interface ArrayExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ARRAY_EXPRESSION = 1;

// Strongly typed iteration through the fields of interface
// ArrowExpressionContentsWithExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ARROW_EXPRESSION_CONTENTS_WITH_EXPRESSION( \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,          \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                             \
  F(ArrowExpressionContentsWithExpression, ParameterScope, 0,                      \
    INTERFACE(AssertedParameterScope),                                             \
    "ArrowExpressionContentsWithExpression::parameterScope")                       \
  F(ArrowExpressionContentsWithExpression, Params, 1,                              \
    INTERFACE(FormalParameters),                                                   \
    "ArrowExpressionContentsWithExpression::params")                               \
  F(ArrowExpressionContentsWithExpression, BodyScope, 2,                           \
    INTERFACE(AssertedVarScope),                                                   \
    "ArrowExpressionContentsWithExpression::bodyScope")                            \
  F(ArrowExpressionContentsWithExpression, Body, 3, SUM(Expression),               \
    "ArrowExpressionContentsWithExpression::body")

// The number of fields of interface ArrowExpressionContentsWithExpression.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ARROW_EXPRESSION_CONTENTS_WITH_EXPRESSION =
        4;

// Strongly typed iteration through the fields of interface
// ArrowExpressionContentsWithFunctionBody.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ARROW_EXPRESSION_CONTENTS_WITH_FUNCTION_BODY( \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,             \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                                \
  F(ArrowExpressionContentsWithFunctionBody, ParameterScope, 0,                       \
    INTERFACE(AssertedParameterScope),                                                \
    "ArrowExpressionContentsWithFunctionBody::parameterScope")                        \
  F(ArrowExpressionContentsWithFunctionBody, Params, 1,                               \
    INTERFACE(FormalParameters),                                                      \
    "ArrowExpressionContentsWithFunctionBody::params")                                \
  F(ArrowExpressionContentsWithFunctionBody, BodyScope, 2,                            \
    INTERFACE(AssertedVarScope),                                                      \
    "ArrowExpressionContentsWithFunctionBody::bodyScope")                             \
  F(ArrowExpressionContentsWithFunctionBody, Body, 3,                                 \
    LIST(ListOfStatement, SUM(Statement)),                                            \
    "ArrowExpressionContentsWithFunctionBody::body")

// The number of fields of interface ArrowExpressionContentsWithFunctionBody.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ARROW_EXPRESSION_CONTENTS_WITH_FUNCTION_BODY =
        4;

// Strongly typed iteration through the fields of interface AssertedBlockScope.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_BLOCK_SCOPE(             \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AssertedBlockScope, DeclaredNames, 0,                                 \
    LIST(ListOfAssertedDeclaredName, INTERFACE(AssertedDeclaredName)),    \
    "AssertedBlockScope::declaredNames")                                  \
  F(AssertedBlockScope, HasDirectEval, 1, PRIMITIVE(Boolean),             \
    "AssertedBlockScope::hasDirectEval")

// The number of fields of interface AssertedBlockScope.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_BLOCK_SCOPE = 2;

// Strongly typed iteration through the fields of interface AssertedBoundName.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_BOUND_NAME(              \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AssertedBoundName, Name, 0, PRIMITIVE(IdentifierName),                \
    "AssertedBoundName::name")                                            \
  F(AssertedBoundName, IsCaptured, 1, PRIMITIVE(Boolean),                 \
    "AssertedBoundName::isCaptured")

// The number of fields of interface AssertedBoundName.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_BOUND_NAME = 2;

// Strongly typed iteration through the fields of interface
// AssertedBoundNamesScope.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_BOUND_NAMES_SCOPE(       \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AssertedBoundNamesScope, BoundNames, 0,                               \
    LIST(ListOfAssertedBoundName, INTERFACE(AssertedBoundName)),          \
    "AssertedBoundNamesScope::boundNames")                                \
  F(AssertedBoundNamesScope, HasDirectEval, 1, PRIMITIVE(Boolean),        \
    "AssertedBoundNamesScope::hasDirectEval")

// The number of fields of interface AssertedBoundNamesScope.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_BOUND_NAMES_SCOPE =
    2;

// Strongly typed iteration through the fields of interface
// AssertedDeclaredName.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_DECLARED_NAME(           \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AssertedDeclaredName, Name, 0, PRIMITIVE(IdentifierName),             \
    "AssertedDeclaredName::name")                                         \
  F(AssertedDeclaredName, Kind, 1, STRING_ENUM(AssertedDeclaredKind),     \
    "AssertedDeclaredName::kind")                                         \
  F(AssertedDeclaredName, IsCaptured, 2, PRIMITIVE(Boolean),              \
    "AssertedDeclaredName::isCaptured")

// The number of fields of interface AssertedDeclaredName.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_DECLARED_NAME = 3;

// Strongly typed iteration through the fields of interface
// AssertedParameterName.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_PARAMETER_NAME(          \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AssertedParameterName, Name, 0, PRIMITIVE(IdentifierName),            \
    "AssertedParameterName::name")                                        \
  F(AssertedParameterName, IsCaptured, 1, PRIMITIVE(Boolean),             \
    "AssertedParameterName::isCaptured")

// The number of fields of interface AssertedParameterName.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_PARAMETER_NAME = 2;

// Strongly typed iteration through the fields of interface
// AssertedParameterScope.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_PARAMETER_SCOPE(         \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AssertedParameterScope, ParamNames, 0,                                \
    LIST(ListOfAssertedMaybePositionalParameterName,                      \
         SUM(AssertedMaybePositionalParameterName)),                      \
    "AssertedParameterScope::paramNames")                                 \
  F(AssertedParameterScope, HasDirectEval, 1, PRIMITIVE(Boolean),         \
    "AssertedParameterScope::hasDirectEval")                              \
  F(AssertedParameterScope, IsSimpleParameterList, 2, PRIMITIVE(Boolean), \
    "AssertedParameterScope::isSimpleParameterList")

// The number of fields of interface AssertedParameterScope.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_PARAMETER_SCOPE = 3;

// Strongly typed iteration through the fields of interface
// AssertedPositionalParameterName.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_POSITIONAL_PARAMETER_NAME( \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,   \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                      \
  F(AssertedPositionalParameterName, Index, 0, PRIMITIVE(UnsignedLong),     \
    "AssertedPositionalParameterName::index")                               \
  F(AssertedPositionalParameterName, Name, 1, PRIMITIVE(IdentifierName),    \
    "AssertedPositionalParameterName::name")                                \
  F(AssertedPositionalParameterName, IsCaptured, 2, PRIMITIVE(Boolean),     \
    "AssertedPositionalParameterName::isCaptured")

// The number of fields of interface AssertedPositionalParameterName.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_POSITIONAL_PARAMETER_NAME = 3;

// Strongly typed iteration through the fields of interface
// AssertedRestParameterName.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_REST_PARAMETER_NAME(     \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AssertedRestParameterName, Name, 0, PRIMITIVE(IdentifierName),        \
    "AssertedRestParameterName::name")                                    \
  F(AssertedRestParameterName, IsCaptured, 1, PRIMITIVE(Boolean),         \
    "AssertedRestParameterName::isCaptured")

// The number of fields of interface AssertedRestParameterName.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_REST_PARAMETER_NAME =
    2;

// Strongly typed iteration through the fields of interface
// AssertedScriptGlobalScope.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_SCRIPT_GLOBAL_SCOPE(     \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AssertedScriptGlobalScope, DeclaredNames, 0,                          \
    LIST(ListOfAssertedDeclaredName, INTERFACE(AssertedDeclaredName)),    \
    "AssertedScriptGlobalScope::declaredNames")                           \
  F(AssertedScriptGlobalScope, HasDirectEval, 1, PRIMITIVE(Boolean),      \
    "AssertedScriptGlobalScope::hasDirectEval")

// The number of fields of interface AssertedScriptGlobalScope.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_SCRIPT_GLOBAL_SCOPE =
    2;

// Strongly typed iteration through the fields of interface AssertedVarScope.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_VAR_SCOPE(               \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AssertedVarScope, DeclaredNames, 0,                                   \
    LIST(ListOfAssertedDeclaredName, INTERFACE(AssertedDeclaredName)),    \
    "AssertedVarScope::declaredNames")                                    \
  F(AssertedVarScope, HasDirectEval, 1, PRIMITIVE(Boolean),               \
    "AssertedVarScope::hasDirectEval")

// The number of fields of interface AssertedVarScope.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_VAR_SCOPE = 2;

// Strongly typed iteration through the fields of interface
// AssignmentExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSIGNMENT_EXPRESSION(            \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AssignmentExpression, Binding, 0, SUM(AssignmentTarget),              \
    "AssignmentExpression::binding")                                      \
  F(AssignmentExpression, Expression, 1, SUM(Expression),                 \
    "AssignmentExpression::expression")

// The number of fields of interface AssignmentExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSIGNMENT_EXPRESSION = 2;

// Strongly typed iteration through the fields of interface
// AssignmentTargetIdentifier.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSIGNMENT_TARGET_IDENTIFIER(     \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AssignmentTargetIdentifier, Name, 0, PRIMITIVE(IdentifierName),       \
    "AssignmentTargetIdentifier::name")

// The number of fields of interface AssignmentTargetIdentifier.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSIGNMENT_TARGET_IDENTIFIER =
    1;

// Strongly typed iteration through the fields of interface
// AssignmentTargetPropertyIdentifier.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSIGNMENT_TARGET_PROPERTY_IDENTIFIER( \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,      \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                         \
  F(AssignmentTargetPropertyIdentifier, Binding, 0,                            \
    INTERFACE(AssignmentTargetIdentifier),                                     \
    "AssignmentTargetPropertyIdentifier::binding")                             \
  F(AssignmentTargetPropertyIdentifier, Init, 1, OPTIONAL_SUM(Expression),     \
    "AssignmentTargetPropertyIdentifier::init")

// The number of fields of interface AssignmentTargetPropertyIdentifier.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSIGNMENT_TARGET_PROPERTY_IDENTIFIER =
        2;

// Strongly typed iteration through the fields of interface
// AssignmentTargetPropertyProperty.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSIGNMENT_TARGET_PROPERTY_PROPERTY( \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,    \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                       \
  F(AssignmentTargetPropertyProperty, Name, 0, SUM(PropertyName),            \
    "AssignmentTargetPropertyProperty::name")                                \
  F(AssignmentTargetPropertyProperty, Binding, 1,                            \
    SUM(AssignmentTargetOrAssignmentTargetWithInitializer),                  \
    "AssignmentTargetPropertyProperty::binding")

// The number of fields of interface AssignmentTargetPropertyProperty.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSIGNMENT_TARGET_PROPERTY_PROPERTY =
        2;

// Strongly typed iteration through the fields of interface
// AssignmentTargetWithInitializer.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSIGNMENT_TARGET_WITH_INITIALIZER( \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,   \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                      \
  F(AssignmentTargetWithInitializer, Binding, 0, SUM(AssignmentTarget),     \
    "AssignmentTargetWithInitializer::binding")                             \
  F(AssignmentTargetWithInitializer, Init, 1, SUM(Expression),              \
    "AssignmentTargetWithInitializer::init")

// The number of fields of interface AssignmentTargetWithInitializer.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSIGNMENT_TARGET_WITH_INITIALIZER = 2;

// Strongly typed iteration through the fields of interface AwaitExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_AWAIT_EXPRESSION(                 \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(AwaitExpression, Expression, 0, SUM(Expression),                      \
    "AwaitExpression::expression")

// The number of fields of interface AwaitExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_AWAIT_EXPRESSION = 1;

// Strongly typed iteration through the fields of interface BinaryExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BINARY_EXPRESSION(                \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(BinaryExpression, Operator, 0, STRING_ENUM(BinaryOperator),           \
    "BinaryExpression::operator")                                         \
  F(BinaryExpression, Left, 1, SUM(Expression), "BinaryExpression::left") \
  F(BinaryExpression, Right, 2, SUM(Expression), "BinaryExpression::right")

// The number of fields of interface BinaryExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BINARY_EXPRESSION = 3;

// Strongly typed iteration through the fields of interface BindingIdentifier.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BINDING_IDENTIFIER(               \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(BindingIdentifier, Name, 0, PRIMITIVE(IdentifierName),                \
    "BindingIdentifier::name")

// The number of fields of interface BindingIdentifier.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BINDING_IDENTIFIER = 1;

// Strongly typed iteration through the fields of interface
// BindingPropertyIdentifier.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BINDING_PROPERTY_IDENTIFIER(      \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(BindingPropertyIdentifier, Binding, 0, INTERFACE(BindingIdentifier),  \
    "BindingPropertyIdentifier::binding")                                 \
  F(BindingPropertyIdentifier, Init, 1, OPTIONAL_SUM(Expression),         \
    "BindingPropertyIdentifier::init")

// The number of fields of interface BindingPropertyIdentifier.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BINDING_PROPERTY_IDENTIFIER =
    2;

// Strongly typed iteration through the fields of interface
// BindingPropertyProperty.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BINDING_PROPERTY_PROPERTY(             \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,      \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                         \
  F(BindingPropertyProperty, Name, 0, SUM(PropertyName),                       \
    "BindingPropertyProperty::name")                                           \
  F(BindingPropertyProperty, Binding, 1, SUM(BindingOrBindingWithInitializer), \
    "BindingPropertyProperty::binding")

// The number of fields of interface BindingPropertyProperty.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BINDING_PROPERTY_PROPERTY = 2;

// Strongly typed iteration through the fields of interface
// BindingWithInitializer.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BINDING_WITH_INITIALIZER(         \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(BindingWithInitializer, Binding, 0, SUM(Binding),                     \
    "BindingWithInitializer::binding")                                    \
  F(BindingWithInitializer, Init, 1, SUM(Expression),                     \
    "BindingWithInitializer::init")

// The number of fields of interface BindingWithInitializer.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BINDING_WITH_INITIALIZER = 2;

// Strongly typed iteration through the fields of interface Block.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BLOCK(                            \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(Block, Scope, 0, INTERFACE(AssertedBlockScope), "Block::scope")       \
  F(Block, Statements, 1, LIST(ListOfStatement, SUM(Statement)),          \
    "Block::statements")

// The number of fields of interface Block.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BLOCK = 2;

// Strongly typed iteration through the fields of interface BreakStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BREAK_STATEMENT(                  \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(BreakStatement, Label, 0, PRIMITIVE(MaybeString), "BreakStatement::label")

// The number of fields of interface BreakStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BREAK_STATEMENT = 1;

// Strongly typed iteration through the fields of interface CallExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CALL_EXPRESSION(                  \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(CallExpression, Callee, 0, SUM(ExpressionOrSuper),                    \
    "CallExpression::callee")                                             \
  F(CallExpression, Arguments, 1,                                         \
    LIST(Arguments, SUM(ExpressionOrSpreadElement)),                      \
    "CallExpression::arguments")

// The number of fields of interface CallExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CALL_EXPRESSION = 2;

// Strongly typed iteration through the fields of interface CatchClause.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CATCH_CLAUSE(                     \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(CatchClause, BindingScope, 0, INTERFACE(AssertedBoundNamesScope),     \
    "CatchClause::bindingScope")                                          \
  F(CatchClause, Binding, 1, SUM(Binding), "CatchClause::binding")        \
  F(CatchClause, Body, 2, INTERFACE(Block), "CatchClause::body")

// The number of fields of interface CatchClause.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CATCH_CLAUSE = 3;

// Strongly typed iteration through the fields of interface ClassDeclaration.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CLASS_DECLARATION(                \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ClassDeclaration, Name, 0, INTERFACE(BindingIdentifier),              \
    "ClassDeclaration::name")                                             \
  F(ClassDeclaration, Super, 1, OPTIONAL_SUM(Expression),                 \
    "ClassDeclaration::super")                                            \
  F(ClassDeclaration, Elements, 2,                                        \
    LIST(ListOfClassElement, INTERFACE(ClassElement)),                    \
    "ClassDeclaration::elements")

// The number of fields of interface ClassDeclaration.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CLASS_DECLARATION = 3;

// Strongly typed iteration through the fields of interface ClassElement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CLASS_ELEMENT(                       \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,    \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                       \
  F(ClassElement, IsStatic, 0, PRIMITIVE(Boolean), "ClassElement::isStatic") \
  F(ClassElement, Method, 1, SUM(MethodDefinition), "ClassElement::method")

// The number of fields of interface ClassElement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CLASS_ELEMENT = 2;

// Strongly typed iteration through the fields of interface ClassExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CLASS_EXPRESSION(                 \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ClassExpression, Name, 0, OPTIONAL_INTERFACE(BindingIdentifier),      \
    "ClassExpression::name")                                              \
  F(ClassExpression, Super, 1, OPTIONAL_SUM(Expression),                  \
    "ClassExpression::super")                                             \
  F(ClassExpression, Elements, 2,                                         \
    LIST(ListOfClassElement, INTERFACE(ClassElement)),                    \
    "ClassExpression::elements")

// The number of fields of interface ClassExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CLASS_EXPRESSION = 3;

// Strongly typed iteration through the fields of interface
// CompoundAssignmentExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_COMPOUND_ASSIGNMENT_EXPRESSION(    \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,  \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                     \
  F(CompoundAssignmentExpression, Operator, 0,                             \
    STRING_ENUM(CompoundAssignmentOperator),                               \
    "CompoundAssignmentExpression::operator")                              \
  F(CompoundAssignmentExpression, Binding, 1, SUM(SimpleAssignmentTarget), \
    "CompoundAssignmentExpression::binding")                               \
  F(CompoundAssignmentExpression, Expression, 2, SUM(Expression),          \
    "CompoundAssignmentExpression::expression")

// The number of fields of interface CompoundAssignmentExpression.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_COMPOUND_ASSIGNMENT_EXPRESSION = 3;

// Strongly typed iteration through the fields of interface
// ComputedMemberAssignmentTarget.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_COMPUTED_MEMBER_ASSIGNMENT_TARGET( \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,  \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                     \
  F(ComputedMemberAssignmentTarget, Object, 0, SUM(ExpressionOrSuper),     \
    "ComputedMemberAssignmentTarget::object")                              \
  F(ComputedMemberAssignmentTarget, Expression, 1, SUM(Expression),        \
    "ComputedMemberAssignmentTarget::expression")

// The number of fields of interface ComputedMemberAssignmentTarget.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_COMPUTED_MEMBER_ASSIGNMENT_TARGET = 2;

// Strongly typed iteration through the fields of interface
// ComputedMemberExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_COMPUTED_MEMBER_EXPRESSION(       \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ComputedMemberExpression, Object, 0, SUM(ExpressionOrSuper),          \
    "ComputedMemberExpression::object")                                   \
  F(ComputedMemberExpression, Expression, 1, SUM(Expression),             \
    "ComputedMemberExpression::expression")

// The number of fields of interface ComputedMemberExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_COMPUTED_MEMBER_EXPRESSION =
    2;

// Strongly typed iteration through the fields of interface
// ComputedPropertyName.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_COMPUTED_PROPERTY_NAME(           \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ComputedPropertyName, Expression, 0, SUM(Expression),                 \
    "ComputedPropertyName::expression")

// The number of fields of interface ComputedPropertyName.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_COMPUTED_PROPERTY_NAME = 1;

// Strongly typed iteration through the fields of interface
// ConditionalExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CONDITIONAL_EXPRESSION(           \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ConditionalExpression, Test, 0, SUM(Expression),                      \
    "ConditionalExpression::test")                                        \
  F(ConditionalExpression, Consequent, 1, SUM(Expression),                \
    "ConditionalExpression::consequent")                                  \
  F(ConditionalExpression, Alternate, 2, SUM(Expression),                 \
    "ConditionalExpression::alternate")

// The number of fields of interface ConditionalExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CONDITIONAL_EXPRESSION = 3;

// Strongly typed iteration through the fields of interface ContinueStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CONTINUE_STATEMENT(               \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ContinueStatement, Label, 0, PRIMITIVE(MaybeString),                  \
    "ContinueStatement::label")

// The number of fields of interface ContinueStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CONTINUE_STATEMENT = 1;

// Strongly typed iteration through the fields of interface DataProperty.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_DATA_PROPERTY(                    \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(DataProperty, Name, 0, SUM(PropertyName), "DataProperty::name")       \
  F(DataProperty, Expression, 1, SUM(Expression), "DataProperty::expression")

// The number of fields of interface DataProperty.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_DATA_PROPERTY = 2;

// Strongly typed iteration through the fields of interface DebuggerStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_DEBUGGER_STATEMENT(               \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)

// The number of fields of interface DebuggerStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_DEBUGGER_STATEMENT = 0;

// Strongly typed iteration through the fields of interface Directive.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_DIRECTIVE(                        \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(Directive, RawValue, 0, PRIMITIVE(String), "Directive::rawValue")

// The number of fields of interface Directive.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_DIRECTIVE = 1;

// Strongly typed iteration through the fields of interface DoWhileStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_DO_WHILE_STATEMENT(               \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(DoWhileStatement, Test, 0, SUM(Expression), "DoWhileStatement::test") \
  F(DoWhileStatement, Body, 1, SUM(Statement), "DoWhileStatement::body")

// The number of fields of interface DoWhileStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_DO_WHILE_STATEMENT = 2;

// Strongly typed iteration through the fields of interface
// EagerArrowExpressionWithExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_ARROW_EXPRESSION_WITH_EXPRESSION( \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,       \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                          \
  F(EagerArrowExpressionWithExpression, IsAsync, 0, PRIMITIVE(Boolean),         \
    "EagerArrowExpressionWithExpression::isAsync")                              \
  F(EagerArrowExpressionWithExpression, Length, 1, PRIMITIVE(UnsignedLong),     \
    "EagerArrowExpressionWithExpression::length")                               \
  F(EagerArrowExpressionWithExpression, Contents, 2,                            \
    INTERFACE(ArrowExpressionContentsWithExpression),                           \
    "EagerArrowExpressionWithExpression::contents")

// The number of fields of interface EagerArrowExpressionWithExpression.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_ARROW_EXPRESSION_WITH_EXPRESSION =
        3;

// Strongly typed iteration through the fields of interface
// EagerArrowExpressionWithFunctionBody.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY( \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,          \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                             \
  F(EagerArrowExpressionWithFunctionBody, IsAsync, 0, PRIMITIVE(Boolean),          \
    "EagerArrowExpressionWithFunctionBody::isAsync")                               \
  F(EagerArrowExpressionWithFunctionBody, Length, 1, PRIMITIVE(UnsignedLong),      \
    "EagerArrowExpressionWithFunctionBody::length")                                \
  F(EagerArrowExpressionWithFunctionBody, Directives, 2,                           \
    LIST(ListOfDirective, INTERFACE(Directive)),                                   \
    "EagerArrowExpressionWithFunctionBody::directives")                            \
  F(EagerArrowExpressionWithFunctionBody, Contents, 3,                             \
    INTERFACE(ArrowExpressionContentsWithFunctionBody),                            \
    "EagerArrowExpressionWithFunctionBody::contents")

// The number of fields of interface EagerArrowExpressionWithFunctionBody.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY =
        4;

// Strongly typed iteration through the fields of interface
// EagerFunctionDeclaration.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_FUNCTION_DECLARATION(       \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(EagerFunctionDeclaration, IsAsync, 0, PRIMITIVE(Boolean),             \
    "EagerFunctionDeclaration::isAsync")                                  \
  F(EagerFunctionDeclaration, IsGenerator, 1, PRIMITIVE(Boolean),         \
    "EagerFunctionDeclaration::isGenerator")                              \
  F(EagerFunctionDeclaration, Name, 2, INTERFACE(BindingIdentifier),      \
    "EagerFunctionDeclaration::name")                                     \
  F(EagerFunctionDeclaration, Length, 3, PRIMITIVE(UnsignedLong),         \
    "EagerFunctionDeclaration::length")                                   \
  F(EagerFunctionDeclaration, Directives, 4,                              \
    LIST(ListOfDirective, INTERFACE(Directive)),                          \
    "EagerFunctionDeclaration::directives")                               \
  F(EagerFunctionDeclaration, Contents, 5,                                \
    INTERFACE(FunctionOrMethodContents), "EagerFunctionDeclaration::contents")

// The number of fields of interface EagerFunctionDeclaration.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_FUNCTION_DECLARATION =
    6;

// Strongly typed iteration through the fields of interface
// EagerFunctionExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_FUNCTION_EXPRESSION(           \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,    \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                       \
  F(EagerFunctionExpression, IsAsync, 0, PRIMITIVE(Boolean),                 \
    "EagerFunctionExpression::isAsync")                                      \
  F(EagerFunctionExpression, IsGenerator, 1, PRIMITIVE(Boolean),             \
    "EagerFunctionExpression::isGenerator")                                  \
  F(EagerFunctionExpression, Name, 2, OPTIONAL_INTERFACE(BindingIdentifier), \
    "EagerFunctionExpression::name")                                         \
  F(EagerFunctionExpression, Length, 3, PRIMITIVE(UnsignedLong),             \
    "EagerFunctionExpression::length")                                       \
  F(EagerFunctionExpression, Directives, 4,                                  \
    LIST(ListOfDirective, INTERFACE(Directive)),                             \
    "EagerFunctionExpression::directives")                                   \
  F(EagerFunctionExpression, Contents, 5,                                    \
    INTERFACE(FunctionExpressionContents),                                   \
    "EagerFunctionExpression::contents")

// The number of fields of interface EagerFunctionExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_FUNCTION_EXPRESSION = 6;

// Strongly typed iteration through the fields of interface EagerGetter.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_GETTER(                        \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,    \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                       \
  F(EagerGetter, Name, 0, SUM(PropertyName), "EagerGetter::name")            \
  F(EagerGetter, Directives, 1, LIST(ListOfDirective, INTERFACE(Directive)), \
    "EagerGetter::directives")                                               \
  F(EagerGetter, Contents, 2, INTERFACE(GetterContents),                     \
    "EagerGetter::contents")

// The number of fields of interface EagerGetter.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_GETTER = 3;

// Strongly typed iteration through the fields of interface EagerMethod.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_METHOD(                        \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,    \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                       \
  F(EagerMethod, IsAsync, 0, PRIMITIVE(Boolean), "EagerMethod::isAsync")     \
  F(EagerMethod, IsGenerator, 1, PRIMITIVE(Boolean),                         \
    "EagerMethod::isGenerator")                                              \
  F(EagerMethod, Name, 2, SUM(PropertyName), "EagerMethod::name")            \
  F(EagerMethod, Length, 3, PRIMITIVE(UnsignedLong), "EagerMethod::length")  \
  F(EagerMethod, Directives, 4, LIST(ListOfDirective, INTERFACE(Directive)), \
    "EagerMethod::directives")                                               \
  F(EagerMethod, Contents, 5, INTERFACE(FunctionOrMethodContents),           \
    "EagerMethod::contents")

// The number of fields of interface EagerMethod.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_METHOD = 6;

// Strongly typed iteration through the fields of interface EagerSetter.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_SETTER(                        \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,    \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                       \
  F(EagerSetter, Name, 0, SUM(PropertyName), "EagerSetter::name")            \
  F(EagerSetter, Length, 1, PRIMITIVE(UnsignedLong), "EagerSetter::length")  \
  F(EagerSetter, Directives, 2, LIST(ListOfDirective, INTERFACE(Directive)), \
    "EagerSetter::directives")                                               \
  F(EagerSetter, Contents, 3, INTERFACE(SetterContents),                     \
    "EagerSetter::contents")

// The number of fields of interface EagerSetter.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_SETTER = 4;

// Strongly typed iteration through the fields of interface EmptyStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EMPTY_STATEMENT(                  \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)

// The number of fields of interface EmptyStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EMPTY_STATEMENT = 0;

// Strongly typed iteration through the fields of interface Export.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT(                           \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(Export, Declaration, 0,                                               \
    SUM(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration),      \
    "Export::declaration")

// The number of fields of interface Export.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT = 1;

// Strongly typed iteration through the fields of interface ExportAllFrom.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_ALL_FROM(                  \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ExportAllFrom, ModuleSpecifier, 0, PRIMITIVE(String),                 \
    "ExportAllFrom::moduleSpecifier")

// The number of fields of interface ExportAllFrom.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_ALL_FROM = 1;

// Strongly typed iteration through the fields of interface ExportDefault.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_DEFAULT(                   \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ExportDefault, Body, 0,                                               \
    SUM(ClassDeclarationOrExpressionOrFunctionDeclaration),               \
    "ExportDefault::body")

// The number of fields of interface ExportDefault.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_DEFAULT = 1;

// Strongly typed iteration through the fields of interface ExportFrom.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_FROM(                      \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ExportFrom, NamedExports, 0,                                          \
    LIST(ListOfExportFromSpecifier, INTERFACE(ExportFromSpecifier)),      \
    "ExportFrom::namedExports")                                           \
  F(ExportFrom, ModuleSpecifier, 1, PRIMITIVE(String),                    \
    "ExportFrom::moduleSpecifier")

// The number of fields of interface ExportFrom.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_FROM = 2;

// Strongly typed iteration through the fields of interface ExportFromSpecifier.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_FROM_SPECIFIER(            \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ExportFromSpecifier, Name, 0, PRIMITIVE(IdentifierName),              \
    "ExportFromSpecifier::name")                                          \
  F(ExportFromSpecifier, ExportedName, 1, PRIMITIVE(MaybeIdentifierName), \
    "ExportFromSpecifier::exportedName")

// The number of fields of interface ExportFromSpecifier.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_FROM_SPECIFIER = 2;

// Strongly typed iteration through the fields of interface
// ExportLocalSpecifier.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_LOCAL_SPECIFIER(           \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ExportLocalSpecifier, Name, 0, INTERFACE(IdentifierExpression),       \
    "ExportLocalSpecifier::name")                                         \
  F(ExportLocalSpecifier, ExportedName, 1, PRIMITIVE(MaybePropertyKey),   \
    "ExportLocalSpecifier::exportedName")

// The number of fields of interface ExportLocalSpecifier.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_LOCAL_SPECIFIER = 2;

// Strongly typed iteration through the fields of interface ExportLocals.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_LOCALS(                    \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ExportLocals, NamedExports, 0,                                        \
    LIST(ListOfExportLocalSpecifier, INTERFACE(ExportLocalSpecifier)),    \
    "ExportLocals::namedExports")

// The number of fields of interface ExportLocals.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_LOCALS = 1;

// Strongly typed iteration through the fields of interface ExpressionStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPRESSION_STATEMENT(             \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ExpressionStatement, Expression, 0, SUM(Expression),                  \
    "ExpressionStatement::expression")

// The number of fields of interface ExpressionStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPRESSION_STATEMENT = 1;

// Strongly typed iteration through the fields of interface ForInOfBinding.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FOR_IN_OF_BINDING(                \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ForInOfBinding, Kind, 0, STRING_ENUM(VariableDeclarationKind),        \
    "ForInOfBinding::kind")                                               \
  F(ForInOfBinding, Binding, 1, SUM(Binding), "ForInOfBinding::binding")

// The number of fields of interface ForInOfBinding.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FOR_IN_OF_BINDING = 2;

// Strongly typed iteration through the fields of interface ForInStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FOR_IN_STATEMENT(                 \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ForInStatement, Left, 0, SUM(AssignmentTargetOrForInOfBinding),       \
    "ForInStatement::left")                                               \
  F(ForInStatement, Right, 1, SUM(Expression), "ForInStatement::right")   \
  F(ForInStatement, Body, 2, SUM(Statement), "ForInStatement::body")

// The number of fields of interface ForInStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FOR_IN_STATEMENT = 3;

// Strongly typed iteration through the fields of interface ForOfStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FOR_OF_STATEMENT(                 \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ForOfStatement, Left, 0, SUM(AssignmentTargetOrForInOfBinding),       \
    "ForOfStatement::left")                                               \
  F(ForOfStatement, Right, 1, SUM(Expression), "ForOfStatement::right")   \
  F(ForOfStatement, Body, 2, SUM(Statement), "ForOfStatement::body")

// The number of fields of interface ForOfStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FOR_OF_STATEMENT = 3;

// Strongly typed iteration through the fields of interface ForStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FOR_STATEMENT(                         \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,      \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                         \
  F(ForStatement, Init, 0, OPTIONAL_SUM(ExpressionOrVariableDeclaration),      \
    "ForStatement::init")                                                      \
  F(ForStatement, Test, 1, OPTIONAL_SUM(Expression), "ForStatement::test")     \
  F(ForStatement, Update, 2, OPTIONAL_SUM(Expression), "ForStatement::update") \
  F(ForStatement, Body, 3, SUM(Statement), "ForStatement::body")

// The number of fields of interface ForStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FOR_STATEMENT = 4;

// Strongly typed iteration through the fields of interface FormalParameters.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FORMAL_PARAMETERS(                \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(FormalParameters, Items, 0, LIST(ListOfParameter, SUM(Parameter)),    \
    "FormalParameters::items")                                            \
  F(FormalParameters, Rest, 1, OPTIONAL_SUM(Binding), "FormalParameters::rest")

// The number of fields of interface FormalParameters.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FORMAL_PARAMETERS = 2;

// Strongly typed iteration through the fields of interface
// FunctionExpressionContents.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FUNCTION_EXPRESSION_CONTENTS(          \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,      \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                         \
  F(FunctionExpressionContents, IsFunctionNameCaptured, 0, PRIMITIVE(Boolean), \
    "FunctionExpressionContents::isFunctionNameCaptured")                      \
  F(FunctionExpressionContents, IsThisCaptured, 1, PRIMITIVE(Boolean),         \
    "FunctionExpressionContents::isThisCaptured")                              \
  F(FunctionExpressionContents, ParameterScope, 2,                             \
    INTERFACE(AssertedParameterScope),                                         \
    "FunctionExpressionContents::parameterScope")                              \
  F(FunctionExpressionContents, Params, 3, INTERFACE(FormalParameters),        \
    "FunctionExpressionContents::params")                                      \
  F(FunctionExpressionContents, BodyScope, 4, INTERFACE(AssertedVarScope),     \
    "FunctionExpressionContents::bodyScope")                                   \
  F(FunctionExpressionContents, Body, 5,                                       \
    LIST(ListOfStatement, SUM(Statement)), "FunctionExpressionContents::body")

// The number of fields of interface FunctionExpressionContents.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FUNCTION_EXPRESSION_CONTENTS =
    6;

// Strongly typed iteration through the fields of interface
// FunctionOrMethodContents.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FUNCTION_OR_METHOD_CONTENTS(          \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,     \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                        \
  F(FunctionOrMethodContents, IsThisCaptured, 0, PRIMITIVE(Boolean),          \
    "FunctionOrMethodContents::isThisCaptured")                               \
  F(FunctionOrMethodContents, ParameterScope, 1,                              \
    INTERFACE(AssertedParameterScope),                                        \
    "FunctionOrMethodContents::parameterScope")                               \
  F(FunctionOrMethodContents, Params, 2, INTERFACE(FormalParameters),         \
    "FunctionOrMethodContents::params")                                       \
  F(FunctionOrMethodContents, BodyScope, 3, INTERFACE(AssertedVarScope),      \
    "FunctionOrMethodContents::bodyScope")                                    \
  F(FunctionOrMethodContents, Body, 4, LIST(ListOfStatement, SUM(Statement)), \
    "FunctionOrMethodContents::body")

// The number of fields of interface FunctionOrMethodContents.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FUNCTION_OR_METHOD_CONTENTS =
    5;

// Strongly typed iteration through the fields of interface GetterContents.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_GETTER_CONTENTS(                  \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(GetterContents, IsThisCaptured, 0, PRIMITIVE(Boolean),                \
    "GetterContents::isThisCaptured")                                     \
  F(GetterContents, BodyScope, 1, INTERFACE(AssertedVarScope),            \
    "GetterContents::bodyScope")                                          \
  F(GetterContents, Body, 2, LIST(ListOfStatement, SUM(Statement)),       \
    "GetterContents::body")

// The number of fields of interface GetterContents.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_GETTER_CONTENTS = 3;

// Strongly typed iteration through the fields of interface
// IdentifierExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_IDENTIFIER_EXPRESSION(            \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(IdentifierExpression, Name, 0, PRIMITIVE(IdentifierName),             \
    "IdentifierExpression::name")

// The number of fields of interface IdentifierExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_IDENTIFIER_EXPRESSION = 1;

// Strongly typed iteration through the fields of interface IfStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_IF_STATEMENT(                      \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,  \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                     \
  F(IfStatement, Test, 0, SUM(Expression), "IfStatement::test")            \
  F(IfStatement, Consequent, 1, SUM(Statement), "IfStatement::consequent") \
  F(IfStatement, Alternate, 2, OPTIONAL_SUM(Statement),                    \
    "IfStatement::alternate")

// The number of fields of interface IfStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_IF_STATEMENT = 3;

// Strongly typed iteration through the fields of interface Import.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_IMPORT(                               \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,     \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                        \
  F(Import, ModuleSpecifier, 0, PRIMITIVE(String), "Import::moduleSpecifier") \
  F(Import, DefaultBinding, 1, OPTIONAL_INTERFACE(BindingIdentifier),         \
    "Import::defaultBinding")                                                 \
  F(Import, NamedImports, 2,                                                  \
    LIST(ListOfImportSpecifier, INTERFACE(ImportSpecifier)),                  \
    "Import::namedImports")

// The number of fields of interface Import.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_IMPORT = 3;

// Strongly typed iteration through the fields of interface ImportNamespace.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_IMPORT_NAMESPACE(                      \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,      \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                         \
  F(ImportNamespace, ModuleSpecifier, 0, PRIMITIVE(String),                    \
    "ImportNamespace::moduleSpecifier")                                        \
  F(ImportNamespace, DefaultBinding, 1, OPTIONAL_INTERFACE(BindingIdentifier), \
    "ImportNamespace::defaultBinding")                                         \
  F(ImportNamespace, NamespaceBinding, 2, INTERFACE(BindingIdentifier),        \
    "ImportNamespace::namespaceBinding")

// The number of fields of interface ImportNamespace.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_IMPORT_NAMESPACE = 3;

// Strongly typed iteration through the fields of interface ImportSpecifier.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_IMPORT_SPECIFIER(                 \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ImportSpecifier, Name, 0, PRIMITIVE(MaybePropertyKey),                \
    "ImportSpecifier::name")                                              \
  F(ImportSpecifier, Binding, 1, INTERFACE(BindingIdentifier),            \
    "ImportSpecifier::binding")

// The number of fields of interface ImportSpecifier.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_IMPORT_SPECIFIER = 2;

// Strongly typed iteration through the fields of interface LabelledStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LABELLED_STATEMENT(               \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(LabelledStatement, Label, 0, PRIMITIVE(String),                       \
    "LabelledStatement::label")                                           \
  F(LabelledStatement, Body, 1, SUM(Statement), "LabelledStatement::body")

// The number of fields of interface LabelledStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LABELLED_STATEMENT = 2;

// Strongly typed iteration through the fields of interface
// LazyArrowExpressionWithExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_ARROW_EXPRESSION_WITH_EXPRESSION( \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,      \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                         \
  F(LazyArrowExpressionWithExpression, IsAsync, 0, PRIMITIVE(Boolean),         \
    "LazyArrowExpressionWithExpression::isAsync")                              \
  F(LazyArrowExpressionWithExpression, Length, 1, PRIMITIVE(UnsignedLong),     \
    "LazyArrowExpressionWithExpression::length")                               \
  F(LazyArrowExpressionWithExpression, ContentsSkip, 2, PRIMITIVE(Lazy),       \
    "LazyArrowExpressionWithExpression::contents_skip")                        \
  F(LazyArrowExpressionWithExpression, Contents, 3,                            \
    INTERFACE(ArrowExpressionContentsWithExpression),                          \
    "LazyArrowExpressionWithExpression::contents")

// The number of fields of interface LazyArrowExpressionWithExpression.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_ARROW_EXPRESSION_WITH_EXPRESSION =
        4;

// Strongly typed iteration through the fields of interface
// LazyArrowExpressionWithFunctionBody.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY( \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,         \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                            \
  F(LazyArrowExpressionWithFunctionBody, IsAsync, 0, PRIMITIVE(Boolean),          \
    "LazyArrowExpressionWithFunctionBody::isAsync")                               \
  F(LazyArrowExpressionWithFunctionBody, Length, 1, PRIMITIVE(UnsignedLong),      \
    "LazyArrowExpressionWithFunctionBody::length")                                \
  F(LazyArrowExpressionWithFunctionBody, Directives, 2,                           \
    LIST(ListOfDirective, INTERFACE(Directive)),                                  \
    "LazyArrowExpressionWithFunctionBody::directives")                            \
  F(LazyArrowExpressionWithFunctionBody, ContentsSkip, 3, PRIMITIVE(Lazy),        \
    "LazyArrowExpressionWithFunctionBody::contents_skip")                         \
  F(LazyArrowExpressionWithFunctionBody, Contents, 4,                             \
    INTERFACE(ArrowExpressionContentsWithFunctionBody),                           \
    "LazyArrowExpressionWithFunctionBody::contents")

// The number of fields of interface LazyArrowExpressionWithFunctionBody.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY =
        5;

// Strongly typed iteration through the fields of interface
// LazyFunctionDeclaration.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_FUNCTION_DECLARATION(             \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,      \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                         \
  F(LazyFunctionDeclaration, IsAsync, 0, PRIMITIVE(Boolean),                   \
    "LazyFunctionDeclaration::isAsync")                                        \
  F(LazyFunctionDeclaration, IsGenerator, 1, PRIMITIVE(Boolean),               \
    "LazyFunctionDeclaration::isGenerator")                                    \
  F(LazyFunctionDeclaration, Name, 2, INTERFACE(BindingIdentifier),            \
    "LazyFunctionDeclaration::name")                                           \
  F(LazyFunctionDeclaration, Length, 3, PRIMITIVE(UnsignedLong),               \
    "LazyFunctionDeclaration::length")                                         \
  F(LazyFunctionDeclaration, Directives, 4,                                    \
    LIST(ListOfDirective, INTERFACE(Directive)),                               \
    "LazyFunctionDeclaration::directives")                                     \
  F(LazyFunctionDeclaration, ContentsSkip, 5, PRIMITIVE(Lazy),                 \
    "LazyFunctionDeclaration::contents_skip")                                  \
  F(LazyFunctionDeclaration, Contents, 6, INTERFACE(FunctionOrMethodContents), \
    "LazyFunctionDeclaration::contents")

// The number of fields of interface LazyFunctionDeclaration.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_FUNCTION_DECLARATION = 7;

// Strongly typed iteration through the fields of interface
// LazyFunctionExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_FUNCTION_EXPRESSION(           \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,   \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                      \
  F(LazyFunctionExpression, IsAsync, 0, PRIMITIVE(Boolean),                 \
    "LazyFunctionExpression::isAsync")                                      \
  F(LazyFunctionExpression, IsGenerator, 1, PRIMITIVE(Boolean),             \
    "LazyFunctionExpression::isGenerator")                                  \
  F(LazyFunctionExpression, Name, 2, OPTIONAL_INTERFACE(BindingIdentifier), \
    "LazyFunctionExpression::name")                                         \
  F(LazyFunctionExpression, Length, 3, PRIMITIVE(UnsignedLong),             \
    "LazyFunctionExpression::length")                                       \
  F(LazyFunctionExpression, Directives, 4,                                  \
    LIST(ListOfDirective, INTERFACE(Directive)),                            \
    "LazyFunctionExpression::directives")                                   \
  F(LazyFunctionExpression, ContentsSkip, 5, PRIMITIVE(Lazy),               \
    "LazyFunctionExpression::contents_skip")                                \
  F(LazyFunctionExpression, Contents, 6,                                    \
    INTERFACE(FunctionExpressionContents), "LazyFunctionExpression::contents")

// The number of fields of interface LazyFunctionExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_FUNCTION_EXPRESSION = 7;

// Strongly typed iteration through the fields of interface LazyGetter.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_GETTER(                           \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,      \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                         \
  F(LazyGetter, Name, 0, SUM(PropertyName), "LazyGetter::name")                \
  F(LazyGetter, Directives, 1, LIST(ListOfDirective, INTERFACE(Directive)),    \
    "LazyGetter::directives")                                                  \
  F(LazyGetter, ContentsSkip, 2, PRIMITIVE(Lazy), "LazyGetter::contents_skip") \
  F(LazyGetter, Contents, 3, INTERFACE(GetterContents), "LazyGetter::contents")

// The number of fields of interface LazyGetter.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_GETTER = 4;

// Strongly typed iteration through the fields of interface LazyMethod.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_METHOD(                           \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,      \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                         \
  F(LazyMethod, IsAsync, 0, PRIMITIVE(Boolean), "LazyMethod::isAsync")         \
  F(LazyMethod, IsGenerator, 1, PRIMITIVE(Boolean), "LazyMethod::isGenerator") \
  F(LazyMethod, Name, 2, SUM(PropertyName), "LazyMethod::name")                \
  F(LazyMethod, Length, 3, PRIMITIVE(UnsignedLong), "LazyMethod::length")      \
  F(LazyMethod, Directives, 4, LIST(ListOfDirective, INTERFACE(Directive)),    \
    "LazyMethod::directives")                                                  \
  F(LazyMethod, ContentsSkip, 5, PRIMITIVE(Lazy), "LazyMethod::contents_skip") \
  F(LazyMethod, Contents, 6, INTERFACE(FunctionOrMethodContents),              \
    "LazyMethod::contents")

// The number of fields of interface LazyMethod.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_METHOD = 7;

// Strongly typed iteration through the fields of interface LazySetter.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_SETTER(                           \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,      \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                         \
  F(LazySetter, Name, 0, SUM(PropertyName), "LazySetter::name")                \
  F(LazySetter, Length, 1, PRIMITIVE(UnsignedLong), "LazySetter::length")      \
  F(LazySetter, Directives, 2, LIST(ListOfDirective, INTERFACE(Directive)),    \
    "LazySetter::directives")                                                  \
  F(LazySetter, ContentsSkip, 3, PRIMITIVE(Lazy), "LazySetter::contents_skip") \
  F(LazySetter, Contents, 4, INTERFACE(SetterContents), "LazySetter::contents")

// The number of fields of interface LazySetter.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_SETTER = 5;

// Strongly typed iteration through the fields of interface
// LiteralBooleanExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_BOOLEAN_EXPRESSION(       \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(LiteralBooleanExpression, Value, 0, PRIMITIVE(Boolean),               \
    "LiteralBooleanExpression::value")

// The number of fields of interface LiteralBooleanExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_BOOLEAN_EXPRESSION =
    1;

// Strongly typed iteration through the fields of interface
// LiteralInfinityExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_INFINITY_EXPRESSION(      \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)

// The number of fields of interface LiteralInfinityExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_INFINITY_EXPRESSION =
    0;

// Strongly typed iteration through the fields of interface
// LiteralNullExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_NULL_EXPRESSION(          \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)

// The number of fields of interface LiteralNullExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_NULL_EXPRESSION = 0;

// Strongly typed iteration through the fields of interface
// LiteralNumericExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_NUMERIC_EXPRESSION(       \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(LiteralNumericExpression, Value, 0, PRIMITIVE(Number),                \
    "LiteralNumericExpression::value")

// The number of fields of interface LiteralNumericExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_NUMERIC_EXPRESSION =
    1;

// Strongly typed iteration through the fields of interface LiteralPropertyName.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_PROPERTY_NAME(            \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(LiteralPropertyName, Value, 0, PRIMITIVE(String),                     \
    "LiteralPropertyName::value")

// The number of fields of interface LiteralPropertyName.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_PROPERTY_NAME = 1;

// Strongly typed iteration through the fields of interface
// LiteralRegExpExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_REG_EXP_EXPRESSION(       \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(LiteralRegExpExpression, Pattern, 0, PRIMITIVE(String),               \
    "LiteralRegExpExpression::pattern")                                   \
  F(LiteralRegExpExpression, Flags, 1, PRIMITIVE(String),                 \
    "LiteralRegExpExpression::flags")

// The number of fields of interface LiteralRegExpExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_REG_EXP_EXPRESSION =
    2;

// Strongly typed iteration through the fields of interface
// LiteralStringExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_STRING_EXPRESSION(        \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(LiteralStringExpression, Value, 0, PRIMITIVE(String),                 \
    "LiteralStringExpression::value")

// The number of fields of interface LiteralStringExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_STRING_EXPRESSION = 1;

// Strongly typed iteration through the fields of interface Module.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_MODULE(                           \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(Module, Scope, 0, INTERFACE(AssertedVarScope), "Module::scope")       \
  F(Module, Directives, 1, LIST(ListOfDirective, INTERFACE(Directive)),   \
    "Module::directives")                                                 \
  F(Module, Items, 2,                                                     \
    LIST(ListOfExportDeclarationOrImportDeclarationOrStatement,           \
         SUM(ExportDeclarationOrImportDeclarationOrStatement)),           \
    "Module::items")

// The number of fields of interface Module.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_MODULE = 3;

// Strongly typed iteration through the fields of interface NewExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_NEW_EXPRESSION(                   \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(NewExpression, Callee, 0, SUM(Expression), "NewExpression::callee")   \
  F(NewExpression, Arguments, 1,                                          \
    LIST(Arguments, SUM(ExpressionOrSpreadElement)),                      \
    "NewExpression::arguments")

// The number of fields of interface NewExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_NEW_EXPRESSION = 2;

// Strongly typed iteration through the fields of interface NewTargetExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_NEW_TARGET_EXPRESSION(            \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)

// The number of fields of interface NewTargetExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_NEW_TARGET_EXPRESSION = 0;

// Strongly typed iteration through the fields of interface
// ObjectAssignmentTarget.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_OBJECT_ASSIGNMENT_TARGET(         \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ObjectAssignmentTarget, Properties, 0,                                \
    LIST(ListOfAssignmentTargetProperty, SUM(AssignmentTargetProperty)),  \
    "ObjectAssignmentTarget::properties")

// The number of fields of interface ObjectAssignmentTarget.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_OBJECT_ASSIGNMENT_TARGET = 1;

// Strongly typed iteration through the fields of interface ObjectBinding.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_OBJECT_BINDING(                   \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ObjectBinding, Properties, 0,                                         \
    LIST(ListOfBindingProperty, SUM(BindingProperty)),                    \
    "ObjectBinding::properties")

// The number of fields of interface ObjectBinding.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_OBJECT_BINDING = 1;

// Strongly typed iteration through the fields of interface ObjectExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_OBJECT_EXPRESSION(                \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ObjectExpression, Properties, 0,                                      \
    LIST(ListOfObjectProperty, SUM(ObjectProperty)),                      \
    "ObjectExpression::properties")

// The number of fields of interface ObjectExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_OBJECT_EXPRESSION = 1;

// Strongly typed iteration through the fields of interface ReturnStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_RETURN_STATEMENT(                 \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ReturnStatement, Expression, 0, OPTIONAL_SUM(Expression),             \
    "ReturnStatement::expression")

// The number of fields of interface ReturnStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_RETURN_STATEMENT = 1;

// Strongly typed iteration through the fields of interface Script.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SCRIPT(                              \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,    \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                       \
  F(Script, Scope, 0, INTERFACE(AssertedScriptGlobalScope), "Script::scope") \
  F(Script, Directives, 1, LIST(ListOfDirective, INTERFACE(Directive)),      \
    "Script::directives")                                                    \
  F(Script, Statements, 2, LIST(ListOfStatement, SUM(Statement)),            \
    "Script::statements")

// The number of fields of interface Script.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SCRIPT = 3;

// Strongly typed iteration through the fields of interface SetterContents.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SETTER_CONTENTS(                  \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(SetterContents, IsThisCaptured, 0, PRIMITIVE(Boolean),                \
    "SetterContents::isThisCaptured")                                     \
  F(SetterContents, ParameterScope, 1, INTERFACE(AssertedParameterScope), \
    "SetterContents::parameterScope")                                     \
  F(SetterContents, Param, 2, SUM(Parameter), "SetterContents::param")    \
  F(SetterContents, BodyScope, 3, INTERFACE(AssertedVarScope),            \
    "SetterContents::bodyScope")                                          \
  F(SetterContents, Body, 4, LIST(ListOfStatement, SUM(Statement)),       \
    "SetterContents::body")

// The number of fields of interface SetterContents.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SETTER_CONTENTS = 5;

// Strongly typed iteration through the fields of interface ShorthandProperty.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SHORTHAND_PROPERTY(               \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ShorthandProperty, Name, 0, INTERFACE(IdentifierExpression),          \
    "ShorthandProperty::name")

// The number of fields of interface ShorthandProperty.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SHORTHAND_PROPERTY = 1;

// Strongly typed iteration through the fields of interface SpreadElement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SPREAD_ELEMENT(                   \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(SpreadElement, Expression, 0, SUM(Expression), "SpreadElement::expression")

// The number of fields of interface SpreadElement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SPREAD_ELEMENT = 1;

// Strongly typed iteration through the fields of interface
// StaticMemberAssignmentTarget.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_STATIC_MEMBER_ASSIGNMENT_TARGET(  \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(StaticMemberAssignmentTarget, Object, 0, SUM(ExpressionOrSuper),      \
    "StaticMemberAssignmentTarget::object")                               \
  F(StaticMemberAssignmentTarget, Property, 1, PRIMITIVE(PropertyKey),    \
    "StaticMemberAssignmentTarget::property")

// The number of fields of interface StaticMemberAssignmentTarget.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_STATIC_MEMBER_ASSIGNMENT_TARGET = 2;

// Strongly typed iteration through the fields of interface
// StaticMemberExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_STATIC_MEMBER_EXPRESSION(         \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(StaticMemberExpression, Object, 0, SUM(ExpressionOrSuper),            \
    "StaticMemberExpression::object")                                     \
  F(StaticMemberExpression, Property, 1, PRIMITIVE(PropertyKey),          \
    "StaticMemberExpression::property")

// The number of fields of interface StaticMemberExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_STATIC_MEMBER_EXPRESSION = 2;

// Strongly typed iteration through the fields of interface Super.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SUPER(                            \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)

// The number of fields of interface Super.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SUPER = 0;

// Strongly typed iteration through the fields of interface SwitchCase.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SWITCH_CASE(                      \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(SwitchCase, Test, 0, SUM(Expression), "SwitchCase::test")             \
  F(SwitchCase, Consequent, 1, LIST(ListOfStatement, SUM(Statement)),     \
    "SwitchCase::consequent")

// The number of fields of interface SwitchCase.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SWITCH_CASE = 2;

// Strongly typed iteration through the fields of interface SwitchDefault.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SWITCH_DEFAULT(                   \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(SwitchDefault, Consequent, 0, LIST(ListOfStatement, SUM(Statement)),  \
    "SwitchDefault::consequent")

// The number of fields of interface SwitchDefault.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SWITCH_DEFAULT = 1;

// Strongly typed iteration through the fields of interface SwitchStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SWITCH_STATEMENT(                     \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,     \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                        \
  F(SwitchStatement, Discriminant, 0, SUM(Expression),                        \
    "SwitchStatement::discriminant")                                          \
  F(SwitchStatement, Cases, 1, LIST(ListOfSwitchCase, INTERFACE(SwitchCase)), \
    "SwitchStatement::cases")

// The number of fields of interface SwitchStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SWITCH_STATEMENT = 2;

// Strongly typed iteration through the fields of interface
// SwitchStatementWithDefault.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SWITCH_STATEMENT_WITH_DEFAULT(    \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(SwitchStatementWithDefault, Discriminant, 0, SUM(Expression),         \
    "SwitchStatementWithDefault::discriminant")                           \
  F(SwitchStatementWithDefault, PreDefaultCases, 1,                       \
    LIST(ListOfSwitchCase, INTERFACE(SwitchCase)),                        \
    "SwitchStatementWithDefault::preDefaultCases")                        \
  F(SwitchStatementWithDefault, DefaultCase, 2, INTERFACE(SwitchDefault), \
    "SwitchStatementWithDefault::defaultCase")                            \
  F(SwitchStatementWithDefault, PostDefaultCases, 3,                      \
    LIST(ListOfSwitchCase, INTERFACE(SwitchCase)),                        \
    "SwitchStatementWithDefault::postDefaultCases")

// The number of fields of interface SwitchStatementWithDefault.
const size_t
    BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SWITCH_STATEMENT_WITH_DEFAULT = 4;

// Strongly typed iteration through the fields of interface TemplateElement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_TEMPLATE_ELEMENT(                 \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(TemplateElement, RawValue, 0, PRIMITIVE(String),                      \
    "TemplateElement::rawValue")

// The number of fields of interface TemplateElement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_TEMPLATE_ELEMENT = 1;

// Strongly typed iteration through the fields of interface TemplateExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_TEMPLATE_EXPRESSION(                   \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,      \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                         \
  F(TemplateExpression, Tag, 0, OPTIONAL_SUM(Expression),                      \
    "TemplateExpression::tag")                                                 \
  F(TemplateExpression, Elements, 1,                                           \
    LIST(ListOfExpressionOrTemplateElement, SUM(ExpressionOrTemplateElement)), \
    "TemplateExpression::elements")

// The number of fields of interface TemplateExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_TEMPLATE_EXPRESSION = 2;

// Strongly typed iteration through the fields of interface ThisExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_THIS_EXPRESSION(                  \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)

// The number of fields of interface ThisExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_THIS_EXPRESSION = 0;

// Strongly typed iteration through the fields of interface ThrowStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_THROW_STATEMENT(                  \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(ThrowStatement, Expression, 0, SUM(Expression),                       \
    "ThrowStatement::expression")

// The number of fields of interface ThrowStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_THROW_STATEMENT = 1;

// Strongly typed iteration through the fields of interface TryCatchStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_TRY_CATCH_STATEMENT(                 \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM,    \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                       \
  F(TryCatchStatement, Body, 0, INTERFACE(Block), "TryCatchStatement::body") \
  F(TryCatchStatement, CatchClause, 1, INTERFACE(CatchClause),               \
    "TryCatchStatement::catchClause")

// The number of fields of interface TryCatchStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_TRY_CATCH_STATEMENT = 2;

// Strongly typed iteration through the fields of interface TryFinallyStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_TRY_FINALLY_STATEMENT(            \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(TryFinallyStatement, Body, 0, INTERFACE(Block),                       \
    "TryFinallyStatement::body")                                          \
  F(TryFinallyStatement, CatchClause, 1, OPTIONAL_INTERFACE(CatchClause), \
    "TryFinallyStatement::catchClause")                                   \
  F(TryFinallyStatement, Finalizer, 2, INTERFACE(Block),                  \
    "TryFinallyStatement::finalizer")

// The number of fields of interface TryFinallyStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_TRY_FINALLY_STATEMENT = 3;

// Strongly typed iteration through the fields of interface UnaryExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_UNARY_EXPRESSION(                 \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(UnaryExpression, Operator, 0, STRING_ENUM(UnaryOperator),             \
    "UnaryExpression::operator")                                          \
  F(UnaryExpression, Operand, 1, SUM(Expression), "UnaryExpression::operand")

// The number of fields of interface UnaryExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_UNARY_EXPRESSION = 2;

// Strongly typed iteration through the fields of interface UpdateExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_UPDATE_EXPRESSION(                \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(UpdateExpression, IsPrefix, 0, PRIMITIVE(Boolean),                    \
    "UpdateExpression::isPrefix")                                         \
  F(UpdateExpression, Operator, 1, STRING_ENUM(UpdateOperator),           \
    "UpdateExpression::operator")                                         \
  F(UpdateExpression, Operand, 2, SUM(SimpleAssignmentTarget),            \
    "UpdateExpression::operand")

// The number of fields of interface UpdateExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_UPDATE_EXPRESSION = 3;

// Strongly typed iteration through the fields of interface VariableDeclaration.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_VARIABLE_DECLARATION(             \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(VariableDeclaration, Kind, 0, STRING_ENUM(VariableDeclarationKind),   \
    "VariableDeclaration::kind")                                          \
  F(VariableDeclaration, Declarators, 1,                                  \
    LIST(ListOfVariableDeclarator, INTERFACE(VariableDeclarator)),        \
    "VariableDeclaration::declarators")

// The number of fields of interface VariableDeclaration.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_VARIABLE_DECLARATION = 2;

// Strongly typed iteration through the fields of interface VariableDeclarator.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_VARIABLE_DECLARATOR(              \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(VariableDeclarator, Binding, 0, SUM(Binding),                         \
    "VariableDeclarator::binding")                                        \
  F(VariableDeclarator, Init, 1, OPTIONAL_SUM(Expression),                \
    "VariableDeclarator::init")

// The number of fields of interface VariableDeclarator.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_VARIABLE_DECLARATOR = 2;

// Strongly typed iteration through the fields of interface WhileStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_WHILE_STATEMENT(                  \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(WhileStatement, Test, 0, SUM(Expression), "WhileStatement::test")     \
  F(WhileStatement, Body, 1, SUM(Statement), "WhileStatement::body")

// The number of fields of interface WhileStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_WHILE_STATEMENT = 2;

// Strongly typed iteration through the fields of interface WithStatement.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_WITH_STATEMENT(                   \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(WithStatement, Object, 0, SUM(Expression), "WithStatement::object")   \
  F(WithStatement, Body, 1, SUM(Statement), "WithStatement::body")

// The number of fields of interface WithStatement.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_WITH_STATEMENT = 2;

// Strongly typed iteration through the fields of interface YieldExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_YIELD_EXPRESSION(                 \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(YieldExpression, Expression, 0, OPTIONAL_SUM(Expression),             \
    "YieldExpression::expression")

// The number of fields of interface YieldExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_YIELD_EXPRESSION = 1;

// Strongly typed iteration through the fields of interface YieldStarExpression.
#define FOR_EACH_BIN_FIELD_IN_INTERFACE_YIELD_STAR_EXPRESSION(            \
    F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \
    STRING_ENUM, OPTIONAL_STRING_ENUM)                                    \
  F(YieldStarExpression, Expression, 0, SUM(Expression),                  \
    "YieldStarExpression::expression")

// The number of fields of interface YieldStarExpression.
const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_YIELD_STAR_EXPRESSION = 1;
// The total number of fields across all interfaces. Used typically to maintain
// a probability table per field.
const size_t BINAST_INTERFACE_AND_FIELD_LIMIT = 275;

// Create parameters list to pass mozilla::Array constructor.
// The number of parameters equals to BINAST_INTERFACE_AND_FIELD_LIMIT.
#define BINAST_PARAM_NUMBER_OF_INTERFACE_AND_FIELD(X)                        \
  (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X),  \
      (X), (X), (X), (X), (X), (X), (X), (X)

/**
 * The different variants of Binary AST string enums, as per
 * the specifications of Binary AST, as a single macro and
 * `enum class`.
 *
 * Separate enum classes are also defined in BinASTParser.h.
 *
 * Usage:
 *
 * ```c++
 * #define WITH_VARIANT(CPP_NAME, SPEC_NAME) ...
 * FOR_EACH_BIN_VARIANT(WITH_VARIANT)
 * ```
 *
 * (sorted by alphabetical order)
 */
#define FOR_EACH_BIN_VARIANT(F)                               \
  F(UnaryOperatorNot, "!")                                    \
  F(BinaryOperatorNeq, "!=")                                  \
  F(BinaryOperatorStrictNeq, "!==")                           \
  F(BinaryOperatorMod, "%")                                   \
  F(CompoundAssignmentOperatorModAssign, "%=")                \
  F(BinaryOperatorBitAnd, "&")                                \
  F(BinaryOperatorLogicalAnd, "&&")                           \
  F(CompoundAssignmentOperatorBitAndAssign, "&=")             \
  F(BinaryOperatorMul, "*")                                   \
  F(BinaryOperatorPow, "**")                                  \
  F(CompoundAssignmentOperatorPowAssign, "**=")               \
  F(CompoundAssignmentOperatorMulAssign, "*=")                \
  F(BinaryOperatorOrUnaryOperatorPlus, "+")                   \
  F(UpdateOperatorIncr, "++")                                 \
  F(CompoundAssignmentOperatorPlusAssign, "+=")               \
  F(BinaryOperatorComma, ",")                                 \
  F(BinaryOperatorOrUnaryOperatorMinus, "-")                  \
  F(UpdateOperatorDecr, "--")                                 \
  F(CompoundAssignmentOperatorMinusAssign, "-=")              \
  F(BinaryOperatorDiv, "/")                                   \
  F(CompoundAssignmentOperatorDivAssign, "/=")                \
  F(BinaryOperatorLessThan, "<")                              \
  F(BinaryOperatorLsh, "<<")                                  \
  F(CompoundAssignmentOperatorLshAssign, "<<=")               \
  F(BinaryOperatorLeqThan, "<=")                              \
  F(BinaryOperatorEq, "==")                                   \
  F(BinaryOperatorStrictEq, "===")                            \
  F(BinaryOperatorGreaterThan, ">")                           \
  F(BinaryOperatorGeqThan, ">=")                              \
  F(BinaryOperatorRsh, ">>")                                  \
  F(CompoundAssignmentOperatorRshAssign, ">>=")               \
  F(BinaryOperatorUrsh, ">>>")                                \
  F(CompoundAssignmentOperatorUrshAssign, ">>>=")             \
  F(BinaryOperatorBitXor, "^")                                \
  F(CompoundAssignmentOperatorBitXorAssign, "^=")             \
  F(VariableDeclarationKindConst, "const")                    \
  F(AssertedDeclaredKindConstLexical, "const lexical")        \
  F(UnaryOperatorDelete, "delete")                            \
  F(BinaryOperatorIn, "in")                                   \
  F(BinaryOperatorInstanceof, "instanceof")                   \
  F(VariableDeclarationKindLet, "let")                        \
  F(AssertedDeclaredKindNonConstLexical, "non-const lexical") \
  F(UnaryOperatorTypeof, "typeof")                            \
  F(AssertedDeclaredKindOrVariableDeclarationKindVar, "var")  \
  F(UnaryOperatorVoid, "void")                                \
  F(BinaryOperatorBitOr, "|")                                 \
  F(CompoundAssignmentOperatorBitOrAssign, "|=")              \
  F(BinaryOperatorLogicalOr, "||")                            \
  F(UnaryOperatorBitNot, "~")

enum class BinASTVariant : uint16_t {
#define EMIT_ENUM(name, _) name,
  FOR_EACH_BIN_VARIANT(EMIT_ENUM)
#undef EMIT_ENUM
};

// The number of distinct values of BinASTVariant.
const size_t BINASTVARIANT_LIMIT = 49;

#define FOR_EACH_BIN_STRING_ENUM(F)                                       \
  F(AssertedDeclaredKind, "AssertedDeclaredKind", ASSERTED_DECLARED_KIND) \
  F(BinaryOperator, "BinaryOperator", BINARY_OPERATOR)                    \
  F(CompoundAssignmentOperator, "CompoundAssignmentOperator",             \
    COMPOUND_ASSIGNMENT_OPERATOR)                                         \
  F(UnaryOperator, "UnaryOperator", UNARY_OPERATOR)                       \
  F(UpdateOperator, "UpdateOperator", UPDATE_OPERATOR)                    \
  F(VariableDeclarationKind, "VariableDeclarationKind",                   \
    VARIABLE_DECLARATION_KIND)

enum class BinASTStringEnum : uint16_t {
#define EMIT_ENUM(NAME, _HUMAN_NAME, _MACRO_NAME) NAME,
  FOR_EACH_BIN_STRING_ENUM(EMIT_ENUM)
#undef EMIT_ENUM
};

// The number of distinct values of BinASTStringEnum.
const size_t BINASTSTRINGENUM_LIMIT = 6;

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_ASSERTED_DECLARED_KIND_BY_STRING_ORDER( \
    F)                                                                              \
  F(AssertedDeclaredKind, AssertedDeclaredKindConstLexical, "const lexical")        \
  F(AssertedDeclaredKind, AssertedDeclaredKindNonConstLexical,                      \
    "non-const lexical")                                                            \
  F(AssertedDeclaredKind, AssertedDeclaredKindOrVariableDeclarationKindVar,         \
    "var")

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_ASSERTED_DECLARED_KIND_BY_WEBIDL_ORDER( \
    F)                                                                              \
  F(AssertedDeclaredKind, AssertedDeclaredKindOrVariableDeclarationKindVar,         \
    "var")                                                                          \
  F(AssertedDeclaredKind, AssertedDeclaredKindNonConstLexical,                      \
    "non-const lexical")                                                            \
  F(AssertedDeclaredKind, AssertedDeclaredKindConstLexical, "const lexical")

const size_t BIN_AST_STRING_ENUM_ASSERTED_DECLARED_KIND_LIMIT = 3;

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_BINARY_OPERATOR_BY_STRING_ORDER(F) \
  F(BinaryOperator, BinaryOperatorNeq, "!=")                                   \
  F(BinaryOperator, BinaryOperatorStrictNeq, "!==")                            \
  F(BinaryOperator, BinaryOperatorMod, "%")                                    \
  F(BinaryOperator, BinaryOperatorBitAnd, "&")                                 \
  F(BinaryOperator, BinaryOperatorLogicalAnd, "&&")                            \
  F(BinaryOperator, BinaryOperatorMul, "*")                                    \
  F(BinaryOperator, BinaryOperatorPow, "**")                                   \
  F(BinaryOperator, BinaryOperatorOrUnaryOperatorPlus, "+")                    \
  F(BinaryOperator, BinaryOperatorComma, ",")                                  \
  F(BinaryOperator, BinaryOperatorOrUnaryOperatorMinus, "-")                   \
  F(BinaryOperator, BinaryOperatorDiv, "/")                                    \
  F(BinaryOperator, BinaryOperatorLessThan, "<")                               \
  F(BinaryOperator, BinaryOperatorLsh, "<<")                                   \
  F(BinaryOperator, BinaryOperatorLeqThan, "<=")                               \
  F(BinaryOperator, BinaryOperatorEq, "==")                                    \
  F(BinaryOperator, BinaryOperatorStrictEq, "===")                             \
  F(BinaryOperator, BinaryOperatorGreaterThan, ">")                            \
  F(BinaryOperator, BinaryOperatorGeqThan, ">=")                               \
  F(BinaryOperator, BinaryOperatorRsh, ">>")                                   \
  F(BinaryOperator, BinaryOperatorUrsh, ">>>")                                 \
  F(BinaryOperator, BinaryOperatorBitXor, "^")                                 \
  F(BinaryOperator, BinaryOperatorIn, "in")                                    \
  F(BinaryOperator, BinaryOperatorInstanceof, "instanceof")                    \
  F(BinaryOperator, BinaryOperatorBitOr, "|")                                  \
  F(BinaryOperator, BinaryOperatorLogicalOr, "||")

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_BINARY_OPERATOR_BY_WEBIDL_ORDER(F) \
  F(BinaryOperator, BinaryOperatorComma, ",")                                  \
  F(BinaryOperator, BinaryOperatorLogicalOr, "||")                             \
  F(BinaryOperator, BinaryOperatorLogicalAnd, "&&")                            \
  F(BinaryOperator, BinaryOperatorBitOr, "|")                                  \
  F(BinaryOperator, BinaryOperatorBitXor, "^")                                 \
  F(BinaryOperator, BinaryOperatorBitAnd, "&")                                 \
  F(BinaryOperator, BinaryOperatorEq, "==")                                    \
  F(BinaryOperator, BinaryOperatorNeq, "!=")                                   \
  F(BinaryOperator, BinaryOperatorStrictEq, "===")                             \
  F(BinaryOperator, BinaryOperatorStrictNeq, "!==")                            \
  F(BinaryOperator, BinaryOperatorLessThan, "<")                               \
  F(BinaryOperator, BinaryOperatorLeqThan, "<=")                               \
  F(BinaryOperator, BinaryOperatorGreaterThan, ">")                            \
  F(BinaryOperator, BinaryOperatorGeqThan, ">=")                               \
  F(BinaryOperator, BinaryOperatorIn, "in")                                    \
  F(BinaryOperator, BinaryOperatorInstanceof, "instanceof")                    \
  F(BinaryOperator, BinaryOperatorLsh, "<<")                                   \
  F(BinaryOperator, BinaryOperatorRsh, ">>")                                   \
  F(BinaryOperator, BinaryOperatorUrsh, ">>>")                                 \
  F(BinaryOperator, BinaryOperatorOrUnaryOperatorPlus, "+")                    \
  F(BinaryOperator, BinaryOperatorOrUnaryOperatorMinus, "-")                   \
  F(BinaryOperator, BinaryOperatorMul, "*")                                    \
  F(BinaryOperator, BinaryOperatorDiv, "/")                                    \
  F(BinaryOperator, BinaryOperatorMod, "%")                                    \
  F(BinaryOperator, BinaryOperatorPow, "**")

const size_t BIN_AST_STRING_ENUM_BINARY_OPERATOR_LIMIT = 25;

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_COMPOUND_ASSIGNMENT_OPERATOR_BY_STRING_ORDER( \
    F)                                                                                    \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorModAssign, "%=")                \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitAndAssign, "&=")             \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorPowAssign, "**=")               \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorMulAssign, "*=")                \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorPlusAssign, "+=")               \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorMinusAssign, "-=")              \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorDivAssign, "/=")                \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorLshAssign, "<<=")               \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorRshAssign, ">>=")               \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorUrshAssign, ">>>=")             \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitXorAssign, "^=")             \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitOrAssign, "|=")

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_COMPOUND_ASSIGNMENT_OPERATOR_BY_WEBIDL_ORDER( \
    F)                                                                                    \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorPlusAssign, "+=")               \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorMinusAssign, "-=")              \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorMulAssign, "*=")                \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorDivAssign, "/=")                \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorModAssign, "%=")                \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorPowAssign, "**=")               \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorLshAssign, "<<=")               \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorRshAssign, ">>=")               \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorUrshAssign, ">>>=")             \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitOrAssign, "|=")              \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitXorAssign, "^=")             \
  F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitAndAssign, "&=")

const size_t BIN_AST_STRING_ENUM_COMPOUND_ASSIGNMENT_OPERATOR_LIMIT = 12;

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_UNARY_OPERATOR_BY_STRING_ORDER(F) \
  F(UnaryOperator, UnaryOperatorNot, "!")                                     \
  F(UnaryOperator, BinaryOperatorOrUnaryOperatorPlus, "+")                    \
  F(UnaryOperator, BinaryOperatorOrUnaryOperatorMinus, "-")                   \
  F(UnaryOperator, UnaryOperatorDelete, "delete")                             \
  F(UnaryOperator, UnaryOperatorTypeof, "typeof")                             \
  F(UnaryOperator, UnaryOperatorVoid, "void")                                 \
  F(UnaryOperator, UnaryOperatorBitNot, "~")

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_UNARY_OPERATOR_BY_WEBIDL_ORDER(F) \
  F(UnaryOperator, BinaryOperatorOrUnaryOperatorPlus, "+")                    \
  F(UnaryOperator, BinaryOperatorOrUnaryOperatorMinus, "-")                   \
  F(UnaryOperator, UnaryOperatorNot, "!")                                     \
  F(UnaryOperator, UnaryOperatorBitNot, "~")                                  \
  F(UnaryOperator, UnaryOperatorTypeof, "typeof")                             \
  F(UnaryOperator, UnaryOperatorVoid, "void")                                 \
  F(UnaryOperator, UnaryOperatorDelete, "delete")

const size_t BIN_AST_STRING_ENUM_UNARY_OPERATOR_LIMIT = 7;

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_UPDATE_OPERATOR_BY_STRING_ORDER(F) \
  F(UpdateOperator, UpdateOperatorIncr, "++")                                  \
  F(UpdateOperator, UpdateOperatorDecr, "--")

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_UPDATE_OPERATOR_BY_WEBIDL_ORDER(F) \
  F(UpdateOperator, UpdateOperatorIncr, "++")                                  \
  F(UpdateOperator, UpdateOperatorDecr, "--")

const size_t BIN_AST_STRING_ENUM_UPDATE_OPERATOR_LIMIT = 2;

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_VARIABLE_DECLARATION_KIND_BY_STRING_ORDER( \
    F)                                                                                 \
  F(VariableDeclarationKind, VariableDeclarationKindConst, "const")                    \
  F(VariableDeclarationKind, VariableDeclarationKindLet, "let")                        \
  F(VariableDeclarationKind, AssertedDeclaredKindOrVariableDeclarationKindVar,         \
    "var")

#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_VARIABLE_DECLARATION_KIND_BY_WEBIDL_ORDER( \
    F)                                                                                 \
  F(VariableDeclarationKind, AssertedDeclaredKindOrVariableDeclarationKindVar,         \
    "var")                                                                             \
  F(VariableDeclarationKind, VariableDeclarationKindLet, "let")                        \
  F(VariableDeclarationKind, VariableDeclarationKindConst, "const")

const size_t BIN_AST_STRING_ENUM_VARIABLE_DECLARATION_KIND_LIMIT = 3;

// This macro accepts the following arguments:
// - F: callback
// - PRIMITIVE: wrapper for primitive type names - called as
// `PRIMITIVE(typename)`
// - INTERFACE: wrapper for non-optional interface type names - called as
// `INTERFACE(typename)`
// - OPTIONAL_INTERFACE: wrapper for optional interface type names - called as
// `OPTIONAL_INTERFACE(typename)` where
//      `typename` is the name of the interface (e.g. no `Maybe` prefix)
// - LIST: wrapper for list types - called as `LIST(list_typename,
// element_typename)`
// - SUM: wrapper for non-optional type names - called as `SUM(typename)`
// - OPTIONAL_SUM: wrapper for optional sum type names - called as
// `OPTIONAL_SUM(typename)` where
//      `typename` is the name of the sum (e.g. no `Maybe` prefix)
// - STRING_ENUM: wrapper for non-optional string enum types - called as
// `STRING_ENUNM(typename)`
// - OPTIONAL_STRING_ENUM: wrapper for optional string enum type names - called
// as `OPTIONAL_STRING_ENUM(typename)` where
//      `typename` is the name of the string enum (e.g. no `Maybe` prefix)
#define FOR_EACH_BIN_LIST(F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST,   \
                          SUM, OPTIONAL_SUM, STRING_ENUM,                      \
                          OPTIONAL_STRING_ENUM)                                \
  F(Arguments, ExpressionOrSpreadElement, "Arguments",                         \
    LIST(Arguments, SUM(ExpressionOrSpreadElement)))                           \
  F(ListOfAssertedBoundName, AssertedBoundName, "ListOfAssertedBoundName",     \
    LIST(ListOfAssertedBoundName, INTERFACE(AssertedBoundName)))               \
  F(ListOfAssertedDeclaredName, AssertedDeclaredName,                          \
    "ListOfAssertedDeclaredName",                                              \
    LIST(ListOfAssertedDeclaredName, INTERFACE(AssertedDeclaredName)))         \
  F(ListOfAssertedMaybePositionalParameterName,                                \
    AssertedMaybePositionalParameterName,                                      \
    "ListOfAssertedMaybePositionalParameterName",                              \
    LIST(ListOfAssertedMaybePositionalParameterName,                           \
         SUM(AssertedMaybePositionalParameterName)))                           \
  F(ListOfAssignmentTargetOrAssignmentTargetWithInitializer,                   \
    AssignmentTargetOrAssignmentTargetWithInitializer,                         \
    "ListOfAssignmentTargetOrAssignmentTargetWithInitializer",                 \
    LIST(ListOfAssignmentTargetOrAssignmentTargetWithInitializer,              \
         SUM(AssignmentTargetOrAssignmentTargetWithInitializer)))              \
  F(ListOfAssignmentTargetProperty, AssignmentTargetProperty,                  \
    "ListOfAssignmentTargetProperty",                                          \
    LIST(ListOfAssignmentTargetProperty, SUM(AssignmentTargetProperty)))       \
  F(ListOfBindingProperty, BindingProperty, "ListOfBindingProperty",           \
    LIST(ListOfBindingProperty, SUM(BindingProperty)))                         \
  F(ListOfClassElement, ClassElement, "ListOfClassElement",                    \
    LIST(ListOfClassElement, INTERFACE(ClassElement)))                         \
  F(ListOfDirective, Directive, "ListOfDirective",                             \
    LIST(ListOfDirective, INTERFACE(Directive)))                               \
  F(ListOfExportDeclarationOrImportDeclarationOrStatement,                     \
    ExportDeclarationOrImportDeclarationOrStatement,                           \
    "ListOfExportDeclarationOrImportDeclarationOrStatement",                   \
    LIST(ListOfExportDeclarationOrImportDeclarationOrStatement,                \
         SUM(ExportDeclarationOrImportDeclarationOrStatement)))                \
  F(ListOfExportFromSpecifier, ExportFromSpecifier,                            \
    "ListOfExportFromSpecifier",                                               \
    LIST(ListOfExportFromSpecifier, INTERFACE(ExportFromSpecifier)))           \
  F(ListOfExportLocalSpecifier, ExportLocalSpecifier,                          \
    "ListOfExportLocalSpecifier",                                              \
    LIST(ListOfExportLocalSpecifier, INTERFACE(ExportLocalSpecifier)))         \
  F(ListOfExpressionOrTemplateElement, ExpressionOrTemplateElement,            \
    "ListOfExpressionOrTemplateElement",                                       \
    LIST(ListOfExpressionOrTemplateElement, SUM(ExpressionOrTemplateElement))) \
  F(ListOfImportSpecifier, ImportSpecifier, "ListOfImportSpecifier",           \
    LIST(ListOfImportSpecifier, INTERFACE(ImportSpecifier)))                   \
  F(ListOfObjectProperty, ObjectProperty, "ListOfObjectProperty",              \
    LIST(ListOfObjectProperty, SUM(ObjectProperty)))                           \
  F(ListOfOptionalBindingOrBindingWithInitializer,                             \
    OptionalBindingOrBindingWithInitializer,                                   \
    "ListOfOptionalBindingOrBindingWithInitializer",                           \
    LIST(ListOfOptionalBindingOrBindingWithInitializer,                        \
         OPTIONAL_SUM(BindingOrBindingWithInitializer)))                       \
  F(ListOfOptionalExpressionOrSpreadElement,                                   \
    OptionalExpressionOrSpreadElement,                                         \
    "ListOfOptionalExpressionOrSpreadElement",                                 \
    LIST(ListOfOptionalExpressionOrSpreadElement,                              \
         OPTIONAL_SUM(ExpressionOrSpreadElement)))                             \
  F(ListOfParameter, Parameter, "ListOfParameter",                             \
    LIST(ListOfParameter, SUM(Parameter)))                                     \
  F(ListOfStatement, Statement, "ListOfStatement",                             \
    LIST(ListOfStatement, SUM(Statement)))                                     \
  F(ListOfSwitchCase, SwitchCase, "ListOfSwitchCase",                          \
    LIST(ListOfSwitchCase, INTERFACE(SwitchCase)))                             \
  F(ListOfVariableDeclarator, VariableDeclarator, "ListOfVariableDeclarator",  \
    LIST(ListOfVariableDeclarator, INTERFACE(VariableDeclarator)))

enum class BinASTList : uint16_t {
#define NOTHING(_)
#define EMIT_ENUM(name, _content, _user, _type_name) name,
  FOR_EACH_BIN_LIST(EMIT_ENUM, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING,
                    NOTHING, NOTHING, NOTHING)
#undef EMIT_ENUM
#undef NOTHING
};

// The number of distinct list types in the grammar. Used typically to maintain
// a probability table per list type.
const size_t BINAST_NUMBER_OF_LIST_TYPES = 22;

// Create parameters list to pass mozilla::Array constructor.
// The number of parameters equals to BINAST_NUMBER_OF_LIST_TYPES.
#define BINAST_PARAM_NUMBER_OF_LIST_TYPES(X)                                 \
  (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \
      (X), (X), (X), (X), (X), (X), (X)

#define FOR_EACH_BIN_SUM(F)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         \
  F(ArrowExpression, "ArrowExpression", ARROW_EXPRESSION,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           \
    SUM(EagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBody))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          \
  F(AssertedMaybePositionalParameterName,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           \
    "AssertedMaybePositionalParameterName",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         \
    ASSERTED_MAYBE_POSITIONAL_PARAMETER_NAME,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       \
    SUM(AssertedParameterNameOrAssertedPositionalParameterNameOrAssertedRestParameterName))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         \
  F(AssignmentTarget, "AssignmentTarget", ASSIGNMENT_TARGET,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        \
    SUM(ArrayAssignmentTargetOrAssignmentTargetIdentifierOrComputedMemberAssignmentTargetOrObjectAssignmentTargetOrStaticMemberAssignmentTarget))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   \
  F(AssignmentTargetOrAssignmentTargetWithInitializer,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              \
    "AssignmentTargetOrAssignmentTargetWithInitializer",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            \
    ASSIGNMENT_TARGET_OR_ASSIGNMENT_TARGET_WITH_INITIALIZER,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        \
    SUM(ArrayAssignmentTargetOrAssignmentTargetIdentifierOrAssignmentTargetWithInitializerOrComputedMemberAssignmentTargetOrObjectAssignmentTargetOrStaticMemberAssignmentTarget))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  \
  F(AssignmentTargetOrForInOfBinding, "AssignmentTargetOrForInOfBinding",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           \
    ASSIGNMENT_TARGET_OR_FOR_IN_OF_BINDING,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         \
    SUM(ArrayAssignmentTargetOrAssignmentTargetIdentifierOrComputedMemberAssignmentTargetOrForInOfBindingOrObjectAssignmentTargetOrStaticMemberAssignmentTarget))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   \
  F(AssignmentTargetPattern, "AssignmentTargetPattern",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             \
    ASSIGNMENT_TARGET_PATTERN,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      \
    SUM(ArrayAssignmentTargetOrObjectAssignmentTarget))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             \
  F(AssignmentTargetProperty, "AssignmentTargetProperty",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           \
    ASSIGNMENT_TARGET_PROPERTY,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     \
    SUM(AssignmentTargetPropertyIdentifierOrAssignmentTargetPropertyProperty))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      \
  F(Binding, "Binding", BINDING,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    \
    SUM(ArrayBindingOrBindingIdentifierOrObjectBinding))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            \
  F(BindingOrBindingWithInitializer, "BindingOrBindingWithInitializer",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             \
    BINDING_OR_BINDING_WITH_INITIALIZER,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            \
    SUM(ArrayBindingOrBindingIdentifierOrBindingWithInitializerOrObjectBinding))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    \
  F(BindingPattern, "BindingPattern", BINDING_PATTERN,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              \
    SUM(ArrayBindingOrObjectBinding))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               \
  F(BindingProperty, "BindingProperty", BINDING_PROPERTY,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           \
    SUM(BindingPropertyIdentifierOrBindingPropertyProperty))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        \
  F(ClassDeclarationOrExpressionOrFunctionDeclaration,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              \
    "ClassDeclarationOrExpressionOrFunctionDeclaration",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            \
    CLASS_DECLARATION_OR_EXPRESSION_OR_FUNCTION_DECLARATION,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        \
    SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassDeclarationOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionDeclarationOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionDeclarationOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrStaticMemberExpressionOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrYieldExpressionOrYieldStarExpression)) \
  F(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     \
    "ClassDeclarationOrFunctionDeclarationOrVariableDeclaration",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   \
    CLASS_DECLARATION_OR_FUNCTION_DECLARATION_OR_VARIABLE_DECLARATION,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              \
    SUM(ClassDeclarationOrEagerFunctionDeclarationOrLazyFunctionDeclarationOrVariableDeclaration))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  \
  F(ExportDeclaration, "ExportDeclaration", EXPORT_DECLARATION,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     \
    SUM(ExportOrExportAllFromOrExportDefaultOrExportFromOrExportLocals))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            \
  F(ExportDeclarationOrImportDeclarationOrStatement,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                \
    "ExportDeclarationOrImportDeclarationOrStatement",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              \
    EXPORT_DECLARATION_OR_IMPORT_DECLARATION_OR_STATEMENT,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          \
    SUM(BlockOrBreakStatementOrClassDeclarationOrContinueStatementOrDebuggerStatementOrDoWhileStatementOrEagerFunctionDeclarationOrEmptyStatementOrExportOrExportAllFromOrExportDefaultOrExportFromOrExportLocalsOrExpressionStatementOrForInStatementOrForOfStatementOrForStatementOrIfStatementOrImportOrImportNamespaceOrLabelledStatementOrLazyFunctionDeclarationOrReturnStatementOrSwitchStatementOrSwitchStatementWithDefaultOrThrowStatementOrTryCatchStatementOrTryFinallyStatementOrVariableDeclarationOrWhileStatementOrWithStatement))                                                                                                                                                                                                                                                                                                  \
  F(Expression, "Expression", EXPRESSION,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           \
    SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrStaticMemberExpressionOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrYieldExpressionOrYieldStarExpression))                                                                      \
  F(ExpressionOrSpreadElement, "ExpressionOrSpreadElement",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         \
    EXPRESSION_OR_SPREAD_ELEMENT,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   \
    SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrSpreadElementOrStaticMemberExpressionOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrYieldExpressionOrYieldStarExpression))                                                       \
  F(ExpressionOrSuper, "ExpressionOrSuper", EXPRESSION_OR_SUPER,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    \
    SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrStaticMemberExpressionOrSuperOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrYieldExpressionOrYieldStarExpression))                                                               \
  F(ExpressionOrTemplateElement, "ExpressionOrTemplateElement",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     \
    EXPRESSION_OR_TEMPLATE_ELEMENT,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 \
    SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrStaticMemberExpressionOrTemplateElementOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrYieldExpressionOrYieldStarExpression))                                                     \
  F(ExpressionOrVariableDeclaration, "ExpressionOrVariableDeclaration",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             \
    EXPRESSION_OR_VARIABLE_DECLARATION,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             \
    SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrStaticMemberExpressionOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrVariableDeclarationOrYieldExpressionOrYieldStarExpression))                                                 \
  F(FunctionDeclaration, "FunctionDeclaration", FUNCTION_DECLARATION,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               \
    SUM(EagerFunctionDeclarationOrLazyFunctionDeclaration))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         \
  F(FunctionExpression, "FunctionExpression", FUNCTION_EXPRESSION,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  \
    SUM(EagerFunctionExpressionOrLazyFunctionExpression))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           \
  F(Getter, "Getter", GETTER, SUM(EagerGetterOrLazyGetter))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         \
  F(ImportDeclaration, "ImportDeclaration", IMPORT_DECLARATION,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     \
    SUM(ImportOrImportNamespace))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   \
  F(IterationStatement, "IterationStatement", ITERATION_STATEMENT,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  \
    SUM(DoWhileStatementOrForInStatementOrForOfStatementOrForStatementOrWhileStatement))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            \
  F(Literal, "Literal", LITERAL,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    \
    SUM(LiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralStringExpression))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             \
  F(Method, "Method", METHOD, SUM(EagerMethodOrLazyMethod))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         \
  F(MethodDefinition, "MethodDefinition", METHOD_DEFINITION,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        \
    SUM(EagerGetterOrEagerMethodOrEagerSetterOrLazyGetterOrLazyMethodOrLazySetter))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 \
  F(ObjectProperty, "ObjectProperty", OBJECT_PROPERTY,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              \
    SUM(DataPropertyOrEagerGetterOrEagerMethodOrEagerSetterOrLazyGetterOrLazyMethodOrLazySetterOrShorthandProperty))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                \
  F(Parameter, "Parameter", PARAMETER,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              \
    SUM(ArrayBindingOrBindingIdentifierOrBindingWithInitializerOrObjectBinding))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    \
  F(Program, "Program", PROGRAM, SUM(ModuleOrScript))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               \
  F(PropertyName, "PropertyName", PROPERTY_NAME,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    \
    SUM(ComputedPropertyNameOrLiteralPropertyName))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 \
  F(Setter, "Setter", SETTER, SUM(EagerSetterOrLazySetter))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         \
  F(SimpleAssignmentTarget, "SimpleAssignmentTarget",                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               \
    SIMPLE_ASSIGNMENT_TARGET,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       \
    SUM(AssignmentTargetIdentifierOrComputedMemberAssignmentTargetOrStaticMemberAssignmentTarget))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  \
  F(Statement, "Statement", STATEMENT,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              \
    SUM(BlockOrBreakStatementOrClassDeclarationOrContinueStatementOrDebuggerStatementOrDoWhileStatementOrEagerFunctionDeclarationOrEmptyStatementOrExpressionStatementOrForInStatementOrForOfStatementOrForStatementOrIfStatementOrLabelledStatementOrLazyFunctionDeclarationOrReturnStatementOrSwitchStatementOrSwitchStatementWithDefaultOrThrowStatementOrTryCatchStatementOrTryFinallyStatementOrVariableDeclarationOrWhileStatementOrWithStatement))

enum class BinASTSum : uint16_t {
#define EMIT_ENUM(name, _user, _macro, _type) name,
  FOR_EACH_BIN_SUM(EMIT_ENUM)
#undef EMIT_ENUM
};

// The number of distinct sum types in the grammar. Used typically to maintain a
// probability table per sum type.
const size_t BINAST_NUMBER_OF_SUM_TYPES = 35;

/**
 * Return a string describing a `BinASTKind`.
 */
const char* describeBinASTKind(const BinASTKind& kind);

/**
 * Return a string describing a `BinASTField`.
 */
const char* describeBinASTField(const BinASTField& field);

/**
 * Return a string describing a `BinASTInterfaceAndField`.
 */
const char* describeBinASTInterfaceAndField(
    const BinASTInterfaceAndField& field);

/**
 * Return a string describing a `BinASTVariant`.
 */
const char* describeBinASTVariant(const BinASTVariant& variant);

/**
 * Return a string describing a `BinASTList`.
 */
const char* describeBinASTList(const BinASTList& list);

/**
 * Return a sort key for sorting `BinASTKind`s alphabetically.
 */
size_t getBinASTKindSortKey(const BinASTKind& kind);

/**
 * Return a sort key for sorting `BinASTVariant`s alphabetically.
 */
size_t getBinASTVariantSortKey(const BinASTVariant& variant);

}  // namespace frontend
}  // namespace js

#endif  // frontend_BinASTToken_h
