Add a helper class to simplify printing of toolchain resolution debug messages.
PiperOrigin-RevId: 698592208
Change-Id: If7a7bb66ef6a2d78667a8980c451d506d3e2ae53
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/BUILD
index a91acc6..995db81 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/BUILD
@@ -313,6 +313,7 @@
name = "toolchain_resolution_function",
srcs = [
"PlatformKeys.java",
+ "ToolchainResolutionDebugPrinter.java",
"ToolchainResolutionFunction.java",
],
deps = [
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/PlatformKeys.java b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/PlatformKeys.java
index cf17760..aada3fb 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/PlatformKeys.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/PlatformKeys.java
@@ -26,7 +26,6 @@
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.analysis.platform.ToolchainTypeInfo;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import com.google.devtools.build.lib.skyframe.config.BuildConfigurationKey;
import com.google.devtools.build.lib.skyframe.toolchains.ConstraintValueLookupUtil.InvalidConstraintValueException;
@@ -50,7 +49,7 @@
private static class Builder {
// Input data.
private final SkyFunction.Environment environment;
- private final boolean debug;
+ private final ToolchainResolutionDebugPrinter debugPrinter;
private final BuildConfigurationKey configurationKey;
// Internal state used during loading.
@@ -62,11 +61,11 @@
private Builder(
SkyFunction.Environment environment,
- boolean debug,
+ ToolchainResolutionDebugPrinter debugPrinter,
BuildConfigurationKey configurationKey,
PlatformConfiguration platformConfiguration) {
this.environment = environment;
- this.debug = debug;
+ this.debugPrinter = debugPrinter;
this.configurationKey = configurationKey;
this.hostPlatformLabel = platformConfiguration.getHostPlatform();
@@ -221,20 +220,7 @@
PlatformInfo platformInfo, List<ConstraintValueInfo> constraints) {
ImmutableList<ConstraintValueInfo> missingConstraints =
platformInfo.constraints().findMissing(constraints);
- if (debug) {
- for (ConstraintValueInfo constraint : missingConstraints) {
- // The value for this setting is not present in the platform, or doesn't match the
- // expected value.
- environment
- .getListener()
- .handle(
- Event.info(
- String.format(
- "ToolchainResolution: Removed execution platform %s from"
- + " available execution platforms, it is missing constraint %s",
- platformInfo.label(), constraint.label())));
- }
- }
+ debugPrinter.reportRemovedExecutionPlatform(platformInfo.label(), missingConstraints);
return missingConstraints.isEmpty();
}
@@ -242,7 +228,7 @@
static PlatformKeys load(
SkyFunction.Environment environment,
- boolean debug,
+ ToolchainResolutionDebugPrinter debugPrinter,
BuildConfigurationKey configurationKey,
PlatformConfiguration platformConfiguration,
ImmutableSet<Label> execConstraintLabels)
@@ -252,7 +238,7 @@
InvalidPlatformException,
InvalidExecutionPlatformLabelException {
- return new Builder(environment, debug, configurationKey, platformConfiguration)
+ return new Builder(environment, debugPrinter, configurationKey, platformConfiguration)
.build(execConstraintLabels);
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionDebugPrinter.java b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionDebugPrinter.java
new file mode 100644
index 0000000..979c7bf
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionDebugPrinter.java
@@ -0,0 +1,109 @@
+// Copyright 2024 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.skyframe.toolchains;
+
+import static java.util.stream.Collectors.joining;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo;
+import com.google.devtools.build.lib.analysis.platform.ToolchainTypeInfo;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.ExtendedEventHandler;
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+/** A helper interface for printing debug messages from toolchain resolution. */
+public sealed interface ToolchainResolutionDebugPrinter {
+
+ static ToolchainResolutionDebugPrinter create(boolean debug, ExtendedEventHandler eventHandler) {
+ if (debug) {
+ return new EventHandlerImpl(eventHandler);
+ }
+ return new NoopPrinter();
+ }
+
+ /** Report on which toolchains were selected. */
+ void reportSelectedToolchains(
+ Label targetPlatform,
+ Label executionPlatform,
+ ImmutableSetMultimap<ToolchainTypeInfo, Label> toolchainTypeToResolved);
+
+ /** Report on an execution platform that was skipped due to constraint mismatches. */
+ void reportRemovedExecutionPlatform(
+ Label label, ImmutableList<ConstraintValueInfo> missingConstraints);
+
+ /** A do-nothing implementation for when debug messages are suppressed. */
+ final class NoopPrinter implements ToolchainResolutionDebugPrinter {
+
+ private NoopPrinter() {}
+
+ @Override
+ public void reportSelectedToolchains(
+ Label targetPlatform,
+ Label executionPlatform,
+ ImmutableSetMultimap<ToolchainTypeInfo, Label> toolchainTypeToResolved) {}
+
+ @Override
+ public void reportRemovedExecutionPlatform(
+ Label label, ImmutableList<ConstraintValueInfo> missingConstraints) {}
+ }
+
+ /** Implement debug printing using the {@link ExtendedEventHandler}. */
+ final class EventHandlerImpl implements ToolchainResolutionDebugPrinter {
+
+ private final ExtendedEventHandler eventHandler;
+
+ private EventHandlerImpl(ExtendedEventHandler eventHandler) {
+ this.eventHandler = eventHandler;
+ }
+
+ @FormatMethod
+ private void debugMessage(@FormatString String template, Object... args) {
+ eventHandler.handle(Event.info(String.format(template, args)));
+ }
+
+ @Override
+ public void reportSelectedToolchains(
+ Label targetPlatform,
+ Label executionPlatform,
+ ImmutableSetMultimap<ToolchainTypeInfo, Label> toolchainTypeToResolved) {
+ String selectedToolchains =
+ toolchainTypeToResolved.entries().stream()
+ .map(
+ e ->
+ String.format(
+ "type %s -> toolchain %s", e.getKey().typeLabel(), e.getValue()))
+ .collect(joining(", "));
+ debugMessage(
+ "ToolchainResolution: Target platform %s: Selected execution platform %s," + " %s",
+ targetPlatform, executionPlatform, selectedToolchains);
+ }
+
+ @Override
+ public void reportRemovedExecutionPlatform(
+ Label label, ImmutableList<ConstraintValueInfo> missingConstraints) {
+ // TODO: jcater - Make this one line listing all constraints.
+ for (ConstraintValueInfo constraint : missingConstraints) {
+ // The value for this setting is not present in the platform, or doesn't match the
+ // expected value.
+ debugMessage(
+ "ToolchainResolution: Removed execution platform %s from"
+ + " available execution platforms, it is missing constraint %s",
+ label, constraint.label());
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java
index 656e28c..c8d2cf9 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainResolutionFunction.java
@@ -15,7 +15,6 @@
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
-import static java.util.stream.Collectors.joining;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashBasedTable;
@@ -30,7 +29,6 @@
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.analysis.platform.ToolchainTypeInfo;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.server.FailureDetails.Toolchain.Code;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import com.google.devtools.build.lib.skyframe.config.BuildConfigurationKey;
@@ -86,12 +84,15 @@
.map(ToolchainTypeRequirement::toolchainType)
.collect(toImmutableSet()));
+ ToolchainResolutionDebugPrinter debugPrinter =
+ ToolchainResolutionDebugPrinter.create(debug, env.getListener());
+
// Create keys for all platforms that will be used, and validate them early.
// Do this early, to catch platform errors early.
PlatformKeys platformKeys =
PlatformKeys.load(
env,
- debug,
+ debugPrinter,
configuration.getKey(),
platformConfiguration,
key.execConstraintLabels());
@@ -118,24 +119,10 @@
key.debugTarget());
UnloadedToolchainContext unloadedToolchainContext = builder.build();
- if (debug) {
- String selectedToolchains =
- unloadedToolchainContext.toolchainTypeToResolved().entries().stream()
- .map(
- e ->
- String.format(
- "type %s -> toolchain %s", e.getKey().typeLabel(), e.getValue()))
- .collect(joining(", "));
- env.getListener()
- .handle(
- Event.info(
- String.format(
- "ToolchainResolution: Target platform %s: Selected execution platform %s,"
- + " %s",
- unloadedToolchainContext.targetPlatform().label(),
- unloadedToolchainContext.executionPlatform().label(),
- selectedToolchains)));
- }
+ debugPrinter.reportSelectedToolchains(
+ unloadedToolchainContext.targetPlatform().label(),
+ unloadedToolchainContext.executionPlatform().label(),
+ unloadedToolchainContext.toolchainTypeToResolved());
return unloadedToolchainContext;
} catch (ToolchainException e) {
throw new ToolchainResolutionFunctionException(e);