/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the "Elastic License
 * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
 * Public License v 1"; you may not use this file except in compliance with, at
 * your election, the "Elastic License 2.0", the "GNU Affero General Public
 * License v3.0 only", or the "Server Side Public License, v 1".
 */

package org.elasticsearch.painless.phase;

import org.elasticsearch.painless.ir.BinaryImplNode;
import org.elasticsearch.painless.ir.BinaryMathNode;
import org.elasticsearch.painless.ir.BlockNode;
import org.elasticsearch.painless.ir.BooleanNode;
import org.elasticsearch.painless.ir.BreakNode;
import org.elasticsearch.painless.ir.CastNode;
import org.elasticsearch.painless.ir.CatchNode;
import org.elasticsearch.painless.ir.ClassNode;
import org.elasticsearch.painless.ir.ComparisonNode;
import org.elasticsearch.painless.ir.ConditionalNode;
import org.elasticsearch.painless.ir.ConstantNode;
import org.elasticsearch.painless.ir.ContinueNode;
import org.elasticsearch.painless.ir.DeclarationBlockNode;
import org.elasticsearch.painless.ir.DeclarationNode;
import org.elasticsearch.painless.ir.DefInterfaceReferenceNode;
import org.elasticsearch.painless.ir.DoWhileLoopNode;
import org.elasticsearch.painless.ir.DupNode;
import org.elasticsearch.painless.ir.ElvisNode;
import org.elasticsearch.painless.ir.FieldNode;
import org.elasticsearch.painless.ir.FlipArrayIndexNode;
import org.elasticsearch.painless.ir.FlipCollectionIndexNode;
import org.elasticsearch.painless.ir.FlipDefIndexNode;
import org.elasticsearch.painless.ir.ForEachLoopNode;
import org.elasticsearch.painless.ir.ForEachSubArrayNode;
import org.elasticsearch.painless.ir.ForEachSubIterableNode;
import org.elasticsearch.painless.ir.ForLoopNode;
import org.elasticsearch.painless.ir.FunctionNode;
import org.elasticsearch.painless.ir.IfElseNode;
import org.elasticsearch.painless.ir.IfNode;
import org.elasticsearch.painless.ir.InstanceofNode;
import org.elasticsearch.painless.ir.InvokeCallDefNode;
import org.elasticsearch.painless.ir.InvokeCallMemberNode;
import org.elasticsearch.painless.ir.InvokeCallNode;
import org.elasticsearch.painless.ir.ListInitializationNode;
import org.elasticsearch.painless.ir.LoadBraceDefNode;
import org.elasticsearch.painless.ir.LoadBraceNode;
import org.elasticsearch.painless.ir.LoadDotArrayLengthNode;
import org.elasticsearch.painless.ir.LoadDotDefNode;
import org.elasticsearch.painless.ir.LoadDotNode;
import org.elasticsearch.painless.ir.LoadDotShortcutNode;
import org.elasticsearch.painless.ir.LoadFieldMemberNode;
import org.elasticsearch.painless.ir.LoadListShortcutNode;
import org.elasticsearch.painless.ir.LoadMapShortcutNode;
import org.elasticsearch.painless.ir.LoadVariableNode;
import org.elasticsearch.painless.ir.MapInitializationNode;
import org.elasticsearch.painless.ir.NewArrayNode;
import org.elasticsearch.painless.ir.NewObjectNode;
import org.elasticsearch.painless.ir.NullNode;
import org.elasticsearch.painless.ir.NullSafeSubNode;
import org.elasticsearch.painless.ir.ReturnNode;
import org.elasticsearch.painless.ir.StatementExpressionNode;
import org.elasticsearch.painless.ir.StaticNode;
import org.elasticsearch.painless.ir.StoreBraceDefNode;
import org.elasticsearch.painless.ir.StoreBraceNode;
import org.elasticsearch.painless.ir.StoreDotDefNode;
import org.elasticsearch.painless.ir.StoreDotNode;
import org.elasticsearch.painless.ir.StoreDotShortcutNode;
import org.elasticsearch.painless.ir.StoreFieldMemberNode;
import org.elasticsearch.painless.ir.StoreListShortcutNode;
import org.elasticsearch.painless.ir.StoreMapShortcutNode;
import org.elasticsearch.painless.ir.StoreVariableNode;
import org.elasticsearch.painless.ir.StringConcatenationNode;
import org.elasticsearch.painless.ir.ThrowNode;
import org.elasticsearch.painless.ir.TryNode;
import org.elasticsearch.painless.ir.TypedCaptureReferenceNode;
import org.elasticsearch.painless.ir.TypedInterfaceReferenceNode;
import org.elasticsearch.painless.ir.UnaryMathNode;
import org.elasticsearch.painless.ir.WhileLoopNode;

public interface IRTreeVisitor<Scope> {

    void visitClass(ClassNode irClassNode, Scope scope);

    void visitFunction(FunctionNode irFunctionNode, Scope scope);

    void visitField(FieldNode irFieldNode, Scope scope);

    void visitBlock(BlockNode irBlockNode, Scope scope);

    void visitIf(IfNode irIfNode, Scope scope);

    void visitIfElse(IfElseNode irIfElseNode, Scope scope);

    void visitWhileLoop(WhileLoopNode irWhileLoopNode, Scope scope);

    void visitDoWhileLoop(DoWhileLoopNode irDoWhileLoopNode, Scope scope);

    void visitForLoop(ForLoopNode irForLoopNode, Scope scope);

    void visitForEachLoop(ForEachLoopNode irForEachLoopNode, Scope scope);

    void visitForEachSubArrayLoop(ForEachSubArrayNode irForEachSubArrayNode, Scope scope);

    void visitForEachSubIterableLoop(ForEachSubIterableNode irForEachSubIterableNode, Scope scope);

    void visitDeclarationBlock(DeclarationBlockNode irDeclarationBlockNode, Scope scope);

    void visitDeclaration(DeclarationNode irDeclarationNode, Scope scope);

    void visitReturn(ReturnNode irReturnNode, Scope scope);

    void visitStatementExpression(StatementExpressionNode irStatementExpressionNode, Scope scope);

    void visitTry(TryNode irTryNode, Scope scope);

    void visitCatch(CatchNode irCatchNode, Scope scope);

    void visitThrow(ThrowNode irThrowNode, Scope scope);

    void visitContinue(ContinueNode irContinueNode, Scope scope);

    void visitBreak(BreakNode irBreakNode, Scope scope);

    void visitBinaryImpl(BinaryImplNode irBinaryImplNode, Scope scope);

    void visitUnaryMath(UnaryMathNode irUnaryMathNode, Scope scope);

    void visitBinaryMath(BinaryMathNode irBinaryMathNode, Scope scope);

    void visitStringConcatenation(StringConcatenationNode irStringConcatenationNode, Scope scope);

    void visitBoolean(BooleanNode irBooleanNode, Scope scope);

    void visitComparison(ComparisonNode irComparisonNode, Scope scope);

    void visitCast(CastNode irCastNode, Scope scope);

    void visitInstanceof(InstanceofNode irInstanceofNode, Scope scope);

    void visitConditional(ConditionalNode irConditionalNode, Scope scope);

    void visitElvis(ElvisNode irElvisNode, Scope scope);

    void visitListInitialization(ListInitializationNode irListInitializationNode, Scope scope);

    void visitMapInitialization(MapInitializationNode irMapInitializationNode, Scope scope);

    void visitNewArray(NewArrayNode irNewArrayNode, Scope scope);

    void visitNewObject(NewObjectNode irNewObjectNode, Scope scope);

    void visitConstant(ConstantNode irConstantNode, Scope scope);

    void visitNull(NullNode irNullNode, Scope scope);

    void visitDefInterfaceReference(DefInterfaceReferenceNode irDefInterfaceReferenceNode, Scope scope);

    void visitTypedInterfaceReference(TypedInterfaceReferenceNode irTypedInterfaceReferenceNode, Scope scope);

    void visitTypedCaptureReference(TypedCaptureReferenceNode irTypedCaptureReferenceNode, Scope scope);

    void visitStatic(StaticNode irStaticNode, Scope scope);

    void visitLoadVariable(LoadVariableNode irLoadVariableNode, Scope scope);

    void visitNullSafeSub(NullSafeSubNode irNullSafeSubNode, Scope scope);

    void visitLoadDotArrayLengthNode(LoadDotArrayLengthNode irLoadDotArrayLengthNode, Scope scope);

    void visitLoadDotDef(LoadDotDefNode irLoadDotDefNode, Scope scope);

    void visitLoadDot(LoadDotNode irLoadDotNode, Scope scope);

    void visitLoadDotShortcut(LoadDotShortcutNode irDotSubShortcutNode, Scope scope);

    void visitLoadListShortcut(LoadListShortcutNode irLoadListShortcutNode, Scope scope);

    void visitLoadMapShortcut(LoadMapShortcutNode irLoadMapShortcutNode, Scope scope);

    void visitLoadFieldMember(LoadFieldMemberNode irLoadFieldMemberNode, Scope scope);

    void visitLoadBraceDef(LoadBraceDefNode irLoadBraceDefNode, Scope scope);

    void visitLoadBrace(LoadBraceNode irLoadBraceNode, Scope scope);

    void visitStoreVariable(StoreVariableNode irStoreVariableNode, Scope scope);

    void visitStoreDotDef(StoreDotDefNode irStoreDotDefNode, Scope scope);

    void visitStoreDot(StoreDotNode irStoreDotNode, Scope scope);

    void visitStoreDotShortcut(StoreDotShortcutNode irDotSubShortcutNode, Scope scope);

    void visitStoreListShortcut(StoreListShortcutNode irStoreListShortcutNode, Scope scope);

    void visitStoreMapShortcut(StoreMapShortcutNode irStoreMapShortcutNode, Scope scope);

    void visitStoreFieldMember(StoreFieldMemberNode irStoreFieldMemberNode, Scope scope);

    void visitStoreBraceDef(StoreBraceDefNode irStoreBraceDefNode, Scope scope);

    void visitStoreBrace(StoreBraceNode irStoreBraceNode, Scope scope);

    void visitInvokeCallDef(InvokeCallDefNode irInvokeCallDefNode, Scope scope);

    void visitInvokeCall(InvokeCallNode irInvokeCallNode, Scope scope);

    void visitInvokeCallMember(InvokeCallMemberNode irInvokeCallMemberNode, Scope scope);

    void visitFlipArrayIndex(FlipArrayIndexNode irFlipArrayIndexNode, Scope scope);

    void visitFlipCollectionIndex(FlipCollectionIndexNode irFlipCollectionIndexNode, Scope scope);

    void visitFlipDefIndex(FlipDefIndexNode irFlipDefIndexNode, Scope scope);

    void visitDup(DupNode irDupNode, Scope scope);
}
