// Copyright 2015 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.packages;
import com.google.common.base.Predicate;
import com.google.common.base.Verify;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
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;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.Location;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Model for the "environment_group' rule: the piece of Bazel's rule constraint system that binds
* thematically related environments together and determines which environments a rule supports
* by default. See {@link com.google.devtools.build.lib.analysis.constraints.ConstraintSemantics}
* for precise semantic details of how this information is used.
*
*
Note that "environment_group" is implemented as a loading-time function, not a rule. This is
* to support proper discovery of defaults: Say rule A has no explicit constraints and depends
* on rule B, which is explicitly constrained to environment ":bar". Since A declares nothing
* explicitly, it's implicitly constrained to DEFAULTS (whatever that is). Therefore, the
* dependency is only allowed if DEFAULTS doesn't include environments beyond ":bar". To figure
* that out, we need to be able to look up the environment group for ":bar", which is what this
* class provides.
*
*
If we implemented this as a rule, we'd have to provide that lookup via rule dependencies,
* e.g. something like:
*
*
* environment(
* name = 'bar',
* group = [':sample_environments'],
* is_default = 1
* )
*
*
*
But this won't work. This would let us find the environment group for ":bar", but the only way
* to determine what other environments belong to the group is to have the group somehow reference
* them. That would produce circular dependencies in the build graph, which is no good.
*/
@Immutable
public class EnvironmentGroup implements Target {
private final Label label;
private final Location location;
private final Package containingPackage;
private final Set