Introduce enum to quickly discriminate AST nodes.

RELNOTES: None.
PiperOrigin-RevId: 166370036
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/AbstractComprehension.java b/src/main/java/com/google/devtools/build/lib/syntax/AbstractComprehension.java
index 5cdaaa9..5278c80 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/AbstractComprehension.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/AbstractComprehension.java
@@ -269,6 +269,11 @@
   }
 
   @Override
+  public Kind kind() {
+    return Kind.COMPREHENSION;
+  }
+
+  @Override
   Object doEval(Environment env) throws EvalException, InterruptedException {
     OutputCollector collector = createCollector(env);
     evalStep(env, collector, 0);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java
index 436384a..facf5dd 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java
@@ -66,4 +66,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.ASSIGNMENT;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java
index 902b73a..2520348 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java
@@ -67,4 +67,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.AUGMENTED_ASSIGNMENT;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
index 65565ad..bd416a7 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
@@ -259,6 +259,11 @@
     visitor.visit(this);
   }
 
+  @Override
+  public Kind kind() {
+    return Kind.BINARY_OPERATOR;
+  }
+
   /** Implements Operator.PLUS. */
   private static Object plus(
       Object lval, Object rval, Environment env, Location location, boolean isAugmented)
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java
index c2d1c5d..e5a0b4c 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java
@@ -65,4 +65,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.CONDITIONAL;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DictionaryLiteral.java b/src/main/java/com/google/devtools/build/lib/syntax/DictionaryLiteral.java
index 7a5abd2..2cecb11 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DictionaryLiteral.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DictionaryLiteral.java
@@ -99,6 +99,11 @@
     visitor.visit(this);
   }
 
+  @Override
+  public Kind kind() {
+    return Kind.DICTIONARY_LITERAL;
+  }
+
   public ImmutableList<DictionaryEntryLiteral> getEntries() {
     return entries;
   }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
index 056fca4..970d0ca 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
@@ -124,4 +124,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.DOT;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Expression.java b/src/main/java/com/google/devtools/build/lib/syntax/Expression.java
index ae1707c..a7188d8 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Expression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Expression.java
@@ -21,6 +21,26 @@
 public abstract class Expression extends ASTNode {
 
   /**
+   * Kind of the expression. This is similar to using instanceof, except that it's more efficient
+   * and can be used in a switch/case.
+   */
+  public enum Kind {
+    BINARY_OPERATOR,
+    COMPREHENSION,
+    CONDITIONAL,
+    DICTIONARY_LITERAL,
+    DOT,
+    FUNCALL,
+    IDENTIFIER,
+    INDEX,
+    INTEGER_LITERAL,
+    LIST_LITERAL,
+    SLICE,
+    STRING_LITERAL,
+    UNARY_OPERATOR,
+  }
+
+  /**
    * Returns the result of evaluating this build-language expression in the
    * specified environment. All BUILD language datatypes are mapped onto the
    * corresponding Java types as follows:
@@ -70,4 +90,10 @@
    */
   @Override
   public abstract void prettyPrint(Appendable buffer) throws IOException;
+
+  /**
+   * Kind of the expression. This is similar to using instanceof, except that it's more efficient
+   * and can be used in a switch/case.
+   */
+  public abstract Kind kind();
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java
index f0a5fa3..7367fdc 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java
@@ -47,4 +47,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.EXPRESSION;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
index 187c4b8..e2d5344 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
@@ -19,6 +19,7 @@
  * A class for flow statements (e.g. break and continue)
  */
 public final class FlowStatement extends Statement {
+  // TODO(laurentlb): This conflicts with Statement.Kind, maybe remove it?
   public enum Kind {
     BREAK("break"),
     CONTINUE("continue");
@@ -68,6 +69,11 @@
     visitor.visit(this);
   }
 
+  @Override
+  public Statement.Kind kind() {
+    return Statement.Kind.FLOW;
+  }
+
   /**
    * An exception that signals changes in the control flow (e.g. break or continue)
    */
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java
index 381995d..32a1d26 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java
@@ -96,4 +96,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.FOR;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
index e034b16..f3019e4 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
@@ -761,6 +761,11 @@
   }
 
   @Override
+  public Kind kind() {
+    return Kind.FUNCALL;
+  }
+
+  @Override
   protected boolean isNewScope() {
     return true;
   }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java
index d3089c3..544870e 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java
@@ -110,4 +110,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.FUNCTION_DEF;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java b/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java
index 419427c..a0dc773 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java
@@ -85,6 +85,11 @@
     visitor.visit(this);
   }
 
+  @Override
+  public Kind kind() {
+    return Kind.IDENTIFIER;
+  }
+
   EvalException createInvalidIdentifierException(Set<String> symbols) {
     if (name.equals("$error$")) {
       return new EvalException(getLocation(), "contains syntax error(s)", true);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java
index 089f9c1..c49613d 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java
@@ -62,6 +62,11 @@
       visitor.visit(this);
     }
 
+    @Override
+    public Kind kind() {
+      return Kind.CONDITIONAL;
+    }
+
     public Expression getCondition() {
       return condition;
     }
@@ -133,4 +138,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.IF;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java
index 6597f9b..efb1a64 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java
@@ -83,4 +83,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.INDEX;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java b/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java
index 68192c8..ea88509 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java
@@ -43,4 +43,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.INTEGER_LITERAL;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java b/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java
index c173401..26bf96b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java
@@ -32,6 +32,7 @@
   /**
    * Types of the ListLiteral.
    */
+  // TODO(laurentlb): This conflicts with Expression.Kind, maybe remove it?
   public enum Kind {LIST, TUPLE}
 
   private final Kind kind;
@@ -112,4 +113,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Expression.Kind kind() {
+    return Expression.Kind.LIST_LITERAL;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
index 21c0888..084ffa8 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
@@ -107,4 +107,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.LOAD;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
index 5235e58..8366119 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
@@ -81,4 +81,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.RETURN;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java
index 71b6376..a2b6036 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java
@@ -118,4 +118,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.SLICE;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Statement.java b/src/main/java/com/google/devtools/build/lib/syntax/Statement.java
index 58130b6..1795af1 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Statement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Statement.java
@@ -20,6 +20,23 @@
 public abstract class Statement extends ASTNode {
 
   /**
+   * Kind of the statement. This is similar to using instanceof, except that it's more efficient and
+   * can be used in a switch/case.
+   */
+  public enum Kind {
+    ASSIGNMENT,
+    AUGMENTED_ASSIGNMENT,
+    CONDITIONAL,
+    EXPRESSION,
+    FLOW,
+    FOR,
+    FUNCTION_DEF,
+    IF,
+    LOAD,
+    RETURN,
+  }
+
+  /**
    * Executes the statement in the specified build environment, which may be
    * modified.
    *
@@ -44,4 +61,10 @@
    * @throws InterruptedException may be thrown in a sub class.
    */
   abstract void doExec(Environment env) throws EvalException, InterruptedException;
+
+  /**
+   * Kind of the statement. This is similar to using instanceof, except that it's more efficient and
+   * can be used in a switch/case.
+   */
+  public abstract Kind kind();
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java b/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java
index 61856e2..26144ec 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java
@@ -43,4 +43,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.STRING_LITERAL;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
index e55acdd..6ca614b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
@@ -99,4 +99,9 @@
   public void accept(SyntaxTreeVisitor visitor) {
     visitor.visit(this);
   }
+
+  @Override
+  public Kind kind() {
+    return Kind.UNARY_OPERATOR;
+  }
 }