// 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.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.skyframe.config.BuildConfigurationKey;

/**
 * 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
 * com.google.devtools.build.lib.cmdline.Label} (e.g. <code>//src:bazel</code>) and a {@link
 * BuildConfigurationKey}, which is a key for a {@link BuildConfigurationValue}, 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 exec 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 Starlark 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},
 *           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> {

  /** Adds any rule implementation-specific requirements to the given builder. */
  default void addRuleImplSpecificRequiredConfigFragments(
      RequiredConfigFragmentsProvider.Builder requiredFragments,
      AttributeMap attributes,
      BuildConfigurationValue configuration) {}
}
