Fix `equals()` and `hashCode()` for artifacts: artifacts of different classes are not equal.

Also validate that there are no tree and file artifacts with the same exec path.

Fixes #4668.

Closes #5284.

Change-Id: Id97c0407a476a5bfc697b4ca7b858e3d0c0f8c75
PiperOrigin-RevId: 198540425
diff --git a/src/main/java/com/google/devtools/build/lib/packages/OutputFile.java b/src/main/java/com/google/devtools/build/lib/packages/OutputFile.java
index 101cb1b..90f6707 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/OutputFile.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/OutputFile.java
@@ -22,14 +22,35 @@
  */
 public final class OutputFile extends FileTarget {
 
+  /**
+   * A kind of output file.
+   *
+   * The FILESET kind is only supported for a non-open-sourced {@code fileset} rule.
+   */
+  public enum Kind {
+    FILE,
+    FILESET
+  }
+
   private final Rule generatingRule;
+  private final Kind kind;
 
   /**
    * Constructs an output file with the given label, which must be in the given
    * package.
    */
   OutputFile(Package pkg, Label label, Rule generatingRule) {
+    this(pkg, label, Kind.FILE, generatingRule);
+  }
+
+  /**
+   * Constructs an output file with the given label, which must be in the given
+   * package.
+   */
+  OutputFile(Package pkg, Label label,
+      Kind kind, Rule generatingRule) {
     super(pkg, label);
+    this.kind = kind;
     this.generatingRule = generatingRule;
   }
 
@@ -50,6 +71,13 @@
     return generatingRule;
   }
 
+  /**
+   * Returns the kind of this output file.
+   */
+  public Kind getKind() {
+    return kind;
+  }
+
   @Override
   public String getTargetKind() {
     return targetKind();