blob: bbdf54ac3e51d371e1d9c93b7cdf5aaab1b53265 [file] [log] [blame]
// Copyright 2023 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.analysis.producers;
import com.google.auto.value.AutoOneOf;
import com.google.devtools.build.lib.analysis.InvalidVisibilityDependencyException;
import com.google.devtools.build.lib.analysis.config.DependencyEvaluationException;
import com.google.devtools.build.lib.analysis.starlark.StarlarkTransition.TransitionException;
import com.google.devtools.build.lib.skyframe.ConfiguredValueCreationException;
import com.google.devtools.build.lib.util.DetailedExitCode;
import com.google.devtools.build.lib.util.DetailedExitCode.DetailedExitCodeComparator;
import com.google.devtools.common.options.OptionsParsingException;
/** Tagged union of exceptions thrown by {@link DependencyProducer}. */
@AutoOneOf(DependencyError.Kind.class)
public abstract class DependencyError {
/**
* Tags for different error types.
*
* <p>The earlier in this list, the higher the priority when there are multiple errors. See {@link
* #isSecondErrorMoreImportant}.
*/
public enum Kind {
DEPENDENCY_OPTIONS_PARSING,
DEPENDENCY_TRANSITION,
INVALID_VISIBILITY,
DEPENDENCY_CREATION,
ASPECT_CREATION,
}
public abstract Kind kind();
public abstract OptionsParsingException dependencyOptionsParsing();
public abstract TransitionException dependencyTransition();
public abstract InvalidVisibilityDependencyException invalidVisibility();
public abstract ConfiguredValueCreationException dependencyCreation();
public abstract DependencyEvaluationException aspectCreation();
public static boolean isSecondErrorMoreImportant(DependencyError first, DependencyError second) {
int cmp = first.kind().compareTo(second.kind());
if (cmp == 0) {
switch (first.kind()) {
case DEPENDENCY_OPTIONS_PARSING:
case DEPENDENCY_TRANSITION:
case INVALID_VISIBILITY:
case ASPECT_CREATION:
// There isn't a good way to prioritize these so we just keep the first.
return false;
case DEPENDENCY_CREATION:
DetailedExitCode firstExitCode = first.dependencyCreation().getDetailedExitCode();
DetailedExitCode secondExitCode = second.dependencyCreation().getDetailedExitCode();
return secondExitCode.equals(
DetailedExitCodeComparator.chooseMoreImportantWithFirstIfTie(
secondExitCode, firstExitCode));
}
throw new IllegalStateException("unreachable " + first.kind());
}
return cmp > 0;
}
public Exception getException() {
switch (kind()) {
case DEPENDENCY_OPTIONS_PARSING:
return dependencyOptionsParsing();
case DEPENDENCY_TRANSITION:
return dependencyTransition();
case INVALID_VISIBILITY:
return invalidVisibility();
case DEPENDENCY_CREATION:
return dependencyCreation();
case ASPECT_CREATION:
return aspectCreation();
}
throw new IllegalStateException("unreachable");
}
static DependencyError of(TransitionException e) {
return AutoOneOf_DependencyError.dependencyTransition(e);
}
static DependencyError of(OptionsParsingException e) {
return AutoOneOf_DependencyError.dependencyOptionsParsing(e);
}
static DependencyError of(InvalidVisibilityDependencyException e) {
return AutoOneOf_DependencyError.invalidVisibility(e);
}
static DependencyError of(ConfiguredValueCreationException e) {
return AutoOneOf_DependencyError.dependencyCreation(e);
}
static DependencyError of(DependencyEvaluationException e) {
return AutoOneOf_DependencyError.aspectCreation(e);
}
}