BEP: report analysis failure events

...as completion of the respective top-level targets. In this way,
a failure is associated to its root cause, even if the cause is at
analysis phase; in particular, visibility errors are correctly
associated.

For the time beeing, we associate visibility root causes only with
labels; it is planned to change that to the more accurate configured
labels in a follow-up change.

Change-Id: I04121a7cd2099fc65171eae0719fd77b98aef09b
PiperOrigin-RevId: 183359798
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
index d737228..ca24fdf 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
@@ -37,6 +37,7 @@
 import com.google.devtools.build.lib.analysis.config.ConfigurationResolver;
 import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
 import com.google.devtools.build.lib.analysis.configuredtargets.MergedConfiguredTarget.DuplicateException;
+import com.google.devtools.build.lib.buildeventstream.BuildEventId;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -174,7 +175,7 @@
       target = pkg.getTarget(label.getName());
     } catch (NoSuchTargetException e) {
       throw new ConfiguredTargetFunctionException(
-          new ConfiguredValueCreationException(e.getMessage(), label));
+          new ConfiguredValueCreationException(e.getMessage(), label, configuration));
     }
     if (pkg.containsErrors()) {
       transitiveLoadingRootCauses.add(label);
@@ -313,16 +314,18 @@
       } else if (e.getCause() instanceof InconsistentAspectOrderException) {
         InconsistentAspectOrderException cause = (InconsistentAspectOrderException) e.getCause();
         throw new ConfiguredTargetFunctionException(
-            new ConfiguredValueCreationException(cause.getMessage(), target.getLabel()));
+            new ConfiguredValueCreationException(
+                cause.getMessage(), target.getLabel(), configuration));
       } else if (e.getCause() instanceof InvalidConfigurationException) {
         InvalidConfigurationException cause = (InvalidConfigurationException) e.getCause();
         env.getListener().handle(Event.error(cause.getMessage()));
         throw new ConfiguredTargetFunctionException(
-            new ConfiguredValueCreationException(cause.getMessage(), target.getLabel()));
+            new ConfiguredValueCreationException(
+                cause.getMessage(), target.getLabel(), configuration));
       } else {
         // Unknown exception type.
         throw new ConfiguredTargetFunctionException(
-            new ConfiguredValueCreationException(e.getMessage(), target.getLabel()));
+            new ConfiguredValueCreationException(e.getMessage(), target.getLabel(), configuration));
       }
     } catch (AspectCreationException e) {
       // getAnalysisRootCause may be null if the analysis of the aspect itself failed.
@@ -331,14 +334,16 @@
         analysisRootCause = e.getAnalysisRootCause();
       }
       throw new ConfiguredTargetFunctionException(
-          new ConfiguredValueCreationException(e.getMessage(), analysisRootCause));
+          new ConfiguredValueCreationException(e.getMessage(), analysisRootCause, configuration));
     } catch (ToolchainContextException e) {
       // We need to throw a ConfiguredValueCreationException, so either find one or make one.
       ConfiguredValueCreationException cvce;
       if (e.getCause() instanceof ConfiguredValueCreationException) {
         cvce = (ConfiguredValueCreationException) e.getCause();
       } else {
-        cvce = new ConfiguredValueCreationException(e.getCause().getMessage(), target.getLabel());
+        cvce =
+            new ConfiguredValueCreationException(
+                e.getCause().getMessage(), target.getLabel(), configuration);
       }
 
       env.getListener()
@@ -702,9 +707,11 @@
     events.replayOn(env.getListener());
     if (events.hasErrors()) {
       analysisEnvironment.disable(target);
-      throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(
-          "Analysis of target '" + target.getLabel() + "' failed; build aborted",
-          target.getLabel()));
+      throw new ConfiguredTargetFunctionException(
+          new ConfiguredValueCreationException(
+              "Analysis of target '" + target.getLabel() + "' failed; build aborted",
+              target.getLabel(),
+              configuration));
     }
     Preconditions.checkState(!analysisEnvironment.hasErrors(),
         "Analysis environment hasError() but no errors reported");
@@ -743,17 +750,29 @@
     private final NestedSet<Label> loadingRootCauses;
     // TODO(ulfjack): Collect all analysis root causes, not just the first one.
     @Nullable private final Label analysisRootCause;
+    @Nullable private final BuildEventId configuration;
 
-    public ConfiguredValueCreationException(String message, Label currentTarget) {
+    public ConfiguredValueCreationException(
+        String message, Label currentTarget, BuildConfiguration configuration) {
       super(message);
       this.loadingRootCauses = NestedSetBuilder.<Label>emptySet(Order.STABLE_ORDER);
       this.analysisRootCause = Preconditions.checkNotNull(currentTarget);
+      if (configuration != null) {
+        this.configuration = configuration.getEventId();
+      } else {
+        this.configuration = null;
+      }
+    }
+
+    public ConfiguredValueCreationException(String message, Label currentTarget) {
+      this(message, currentTarget, null);
     }
 
     public ConfiguredValueCreationException(String message, NestedSet<Label> rootCauses) {
       super(message);
       this.loadingRootCauses = rootCauses;
       this.analysisRootCause = null;
+      this.configuration = null;
     }
 
     public ConfiguredValueCreationException(NestedSet<Label> rootCauses) {
@@ -771,6 +790,10 @@
     public Label getAnalysisRootCause() {
       return analysisRootCause;
     }
+
+    public BuildEventId getConfiguration() {
+      return configuration;
+    }
   }
 
   /**