// Copyright 2014 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;

import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;

/**
 * A shortcut class to the appropriate specialization of {@code RuleClass.ConfiguredTargetFactory}.
 *
 * <p>Here follows an overview of how loading and analysis works in Bazel:
 *
 * <p>Actions (i.e. commands that are run during the build) are created by configured targets (see
 * {@link ConfiguredTarget}), which are a pair of a {@link Label} (e.g. <code>//src:bazel</code>)
 * and a {@link BuildConfigurationValue#Key}, which is a key for a {@link BuildConfiguration}, which
 * is a blob of data that contains extra information about how the target should be built (for
 * example, for which platform or with which C++ preprocessor definitions). Accordingly, a target
 * can give rise to multiple configured targets, for example, if it needs to be built both for the
 * host and the target configuration.
 *
 * <p>The process of creating the appropriate {@link com.google.devtools.build.lib.actions.Action}s
 * for a configured target is called "analysis". The analysis of a configured target is composed of
 * the following steps (which process is orchestrated by {@link
 * com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction}):
 *
 * <ol>
 *   <li>The corresponding {@link com.google.devtools.build.lib.packages.Target} is loaded, i.e. the
 *       BUILD file is parsed.
 *   <li>Its direct dependencies are analyzed, during which in turn indirect dependencies are also
 *       analyzed.
 *   <li>Aspects specified by the configured target are analyzed. These can be thought of as
 *       visitations of the transitive dependencies of the target. For more information, see {@link
 *       com.google.devtools.build.lib.packages.AspectClass}.
 *   <li>The configured target and the actions it generates are created based on the data from the
 *       previous two steps.
 * </ol>
 *
 * Targets can be of three main kinds (plus a few special ones which are not important for
 * understanding the big picture):
 *
 * <p>
 * <li>Input and output files. These represent either a file that is in the source tree or a file
 *     produced by during the build. Not every file produced during the build has a corresponding
 *     output file target.
 * <li>Rules. These describe things a build actually does. Each rule has a class (e.g. <code>
 *     cc_binary</code>). Rule classes can be defined either in Skylark using the <code>rule()
 *     </code> function or in Java code by implementing {@link
 *     com.google.devtools.build.lib.analysis.RuleDefinition}.
 *
 *     <p>During the analysis of a configured target, the following pieces of data are available:
 *
 *     <ul>
 *       <li>The corresponding target itself. This is necessary so that the analysis has access to
 *           e.g. the attributes a rule has in the BUILD file.
 *       <li>The {@link com.google.devtools.build.lib.analysis.TransitiveInfoCollection}s of direct
 *           dependencies. They are used to gather information from the transitive closure, for
 *           example, the include path entries for C++ compilation or all the object files that need
 *           to be compiled into a C++ binary.
 *       <li>The configuration, which is used to determine which compiler to use and to get access
 *           to some command line options of Bazel that influence analysis.
 *       <li>Skyframe, for requesting arbitrary Skyframe nodes. This is an escape hatch that should
 *           be used when other mechanisms provided are not suitable and allows one to e.g. read
 *           arbitrary files. With great power...
 *     </ul>
 *
 *     <p>Analysis of non-rule configured targets is special-cased and is not covered here.
 *
 *     <p>The analysis of a rule itself is done by implementations {@link
 *     RuleConfiguredTargetFactory} (there should be one for each rule class). The data above is
 *     available using the {@link RuleContext} argument passed into its create() method. It should
 *     result in three things:
 *
 *     <ul>
 *       <li>A set of actions. These should be passed to {@link
 *           RuleContext#registerAction(ActionAnalysisMetadata...)}, although for more common cases
 *           (e.g. {@link com.google.devtools.build.lib.analysis.actions.SpawnAction}), shortcuts
 *           are provided.
 *       <li>A set of artifacts (files produced by actions). These should be created using methods
 *           of {@link RuleContext}. Each artifact thus created must have a generating action.
 *       <li>A set of {@link com.google.devtools.build.lib.analysis.TransitiveInfoProvider}s that
 *           are passed on to direct dependencies. These must be registered using {@link
 *           com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder#add( Class,
 *           com.google.devtools.build.lib.analysis.TransitiveInfoProvider)}
 *     </ul>
 *
 *     <p>Configured targets are currently allowed to create artifacts at any exec path. It would be
 *     better if they could be constrained to a subtree based on the label of the configured target,
 *     but this is currently not feasible because multiple rules violate this constraint and the
 *     output format is part of its interface.
 *
 *     <p>In principle, multiple configured targets should not create actions with conflicting
 *     outputs. There are still a few exceptions to this rule that are slated to be eventually
 *     removed, we have provisions to handle this case (Action instances that share at least one
 *     output file are required to be exactly the same), but this does put some pressure on the
 *     design and we are eventually planning to eliminate this option.
 *
 *     <p>These restrictions together make it possible to:
 *
 *     <ul>
 *       <li>Correctly cache the analysis phase; by tightly constraining what a configured target is
 *           allowed to access and what it is not, we can know when it needs to invalidate a
 *           particular one and when it can reuse an already existing one.
 *       <li>Serialize / deserialize individual configured targets at will, making it possible for
 *           example to swap out part of the analysis state if there is memory pressure or to move
 *           them in persistent storage so that the state can be reconstructed at a different time
 *           or in a different process. The stretch goal is to eventually facilitate cross-user
 *           caching of this information.
 *     </ul>
 */
public interface RuleConfiguredTargetFactory
    extends RuleClass.ConfiguredTargetFactory<
        ConfiguredTarget, RuleContext, ActionConflictException> {}
