// 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 static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType.ABSTRACT;
import static com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType.TEST;

import com.google.common.base.Preconditions;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigurationFragmentFactory;
import com.google.devtools.build.lib.analysis.config.DefaultsPackage;
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.analysis.skylark.SkylarkModules;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.graph.Digraph;
import com.google.devtools.build.lib.graph.Node;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.NativeAspectClass;
import com.google.devtools.build.lib.packages.NativeProvider;
import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
import com.google.devtools.build.lib.packages.OutputFile;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClassProvider;
import com.google.devtools.build.lib.packages.RuleErrorConsumer;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.Environment.Extension;
import com.google.devtools.build.lib.syntax.Environment.Phase;
import com.google.devtools.build.lib.syntax.Mutability;
import com.google.devtools.build.lib.syntax.SkylarkSemantics;
import com.google.devtools.build.lib.syntax.SkylarkUtils;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.common.options.OptionsClassProvider;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.Nullable;

/**
 * Knows about every rule Blaze supports and the associated configuration options.
 *
 * <p>This class is initialized on server startup and the set of rules, build info factories
 * and configuration options is guarantees not to change over the life time of the Blaze server.
 */
public class ConfiguredRuleClassProvider implements RuleClassProvider {

  /**
   * Custom dependency validation logic.
   */
  public interface PrerequisiteValidator {
    /**
     * Checks whether the rule in {@code contextBuilder} is allowed to depend on {@code
     * prerequisite} through the attribute {@code attribute}.
     *
     * <p>Can be used for enforcing any organization-specific policies about the layout of the
     * workspace.
     */
    void validate(
        RuleContext.Builder contextBuilder,
        ConfiguredTargetAndData prerequisite,
        Attribute attribute);
  }

  /** Validator to check for and warn on the deprecation of dependencies. */
  public static final class DeprecationValidator implements PrerequisiteValidator {
    /** Checks if the given prerequisite is deprecated and prints a warning if so. */
    @Override
    public void validate(
        RuleContext.Builder contextBuilder,
        ConfiguredTargetAndData prerequisite,
        Attribute attribute) {
      validateDirectPrerequisiteForDeprecation(
          contextBuilder, contextBuilder.getRule(), prerequisite, contextBuilder.forAspect());
    }

    /**
     * Returns whether two packages are considered the same for purposes of deprecation warnings.
     * Dependencies within the same package do not print deprecation warnings; a package in the
     * javatests directory may also depend on its corresponding java package without a warning.
     */
    public static boolean isSameLogicalPackage(
        PackageIdentifier thisPackage, PackageIdentifier prerequisitePackage) {
      if (thisPackage.equals(prerequisitePackage)) {
        // If the packages are equal, they are the same logical package (and just the same package).
        return true;
      }
      if (!thisPackage.getRepository().equals(prerequisitePackage.getRepository())) {
        // If the packages are in different repositories, they are not the same logical package.
        return false;
      }
      // If the packages are in the same repository, it's allowed iff this package is the javatests
      // companion to the prerequisite java package.
      String thisPackagePath = thisPackage.getPackageFragment().getPathString();
      String prerequisitePackagePath = prerequisitePackage.getPackageFragment().getPathString();
      return thisPackagePath.startsWith("javatests/")
          && prerequisitePackagePath.startsWith("java/")
          && thisPackagePath.substring("javatests/".length()).equals(
              prerequisitePackagePath.substring("java/".length()));
    }

    /** Returns whether a deprecation warning should be printed for the prerequisite described. */
    private static boolean shouldEmitDeprecationWarningFor(
        String thisDeprecation, PackageIdentifier thisPackage,
        String prerequisiteDeprecation, PackageIdentifier prerequisitePackage,
        boolean forAspect) {
      // Don't report deprecation edges from javatests to java or within a package;
      // otherwise tests of deprecated code generate nuisance warnings.
      // Don't report deprecation if the current target is also deprecated,
      // or if the current context is evaluating an aspect,
      // as the base target would have already printed the deprecation warnings.
      return (!forAspect
          && prerequisiteDeprecation != null
          && !isSameLogicalPackage(thisPackage, prerequisitePackage)
          && thisDeprecation == null);
    }

    /** Checks if the given prerequisite is deprecated and prints a warning if so. */
    public static void validateDirectPrerequisiteForDeprecation(
        RuleErrorConsumer errors,
        Rule rule,
        ConfiguredTargetAndData prerequisite,
        boolean forAspect) {
      Target prerequisiteTarget = prerequisite.getTarget();
      Label prerequisiteLabel = prerequisiteTarget.getLabel();
      PackageIdentifier thatPackage = prerequisiteLabel.getPackageIdentifier();
      PackageIdentifier thisPackage = rule.getLabel().getPackageIdentifier();

      if (prerequisiteTarget instanceof Rule) {
        Rule prerequisiteRule = (Rule) prerequisiteTarget;
        String thisDeprecation =
            NonconfigurableAttributeMapper.of(rule).has("deprecation", Type.STRING)
                ? NonconfigurableAttributeMapper.of(rule).get("deprecation", Type.STRING)
                : null;
        String thatDeprecation =
            NonconfigurableAttributeMapper.of(prerequisiteRule).has("deprecation", Type.STRING)
                ? NonconfigurableAttributeMapper.of(prerequisiteRule)
                    .get("deprecation", Type.STRING)
                : null;
        if (shouldEmitDeprecationWarningFor(
            thisDeprecation, thisPackage, thatDeprecation, thatPackage, forAspect)) {
          errors.ruleWarning("target '" + rule.getLabel() +  "' depends on deprecated target '"
              + prerequisiteLabel + "': " + thatDeprecation);
        }
      }

      if (prerequisiteTarget instanceof OutputFile) {
        Rule generatingRule = ((OutputFile) prerequisiteTarget).getGeneratingRule();
        String thisDeprecation =
            NonconfigurableAttributeMapper.of(rule).get("deprecation", Type.STRING);
        String thatDeprecation =
            NonconfigurableAttributeMapper.of(generatingRule).get("deprecation", Type.STRING);
        if (shouldEmitDeprecationWarningFor(
            thisDeprecation, thisPackage, thatDeprecation, thatPackage, forAspect)) {
          errors.ruleWarning("target '" + rule.getLabel() + "' depends on the output file "
              + prerequisiteLabel + " of a deprecated rule " + generatingRule.getLabel()
              + "': " + thatDeprecation);
        }
      }
    }
  }

  /**
   * A coherent set of options, fragments, aspects and rules; each of these may declare a dependency
   * on other such sets.
   */
  public interface RuleSet {
    /** Add stuff to the configured rule class provider builder. */
    void init(ConfiguredRuleClassProvider.Builder builder);

    /** List of required modules. */
    ImmutableList<RuleSet> requires();
  }

  /** Builder for {@link ConfiguredRuleClassProvider}. */
  public static class Builder implements RuleDefinitionEnvironment {
    private final StringBuilder defaultWorkspaceFilePrefix = new StringBuilder();
    private final StringBuilder defaultWorkspaceFileSuffix = new StringBuilder();
    private Label preludeLabel;
    private String runfilesPrefix;
    private String toolsRepository;
    private final List<ConfigurationFragmentFactory> configurationFragmentFactories =
        new ArrayList<>();
    private final List<BuildInfoFactory> buildInfoFactories = new ArrayList<>();
    private final List<Class<? extends FragmentOptions>> configurationOptions = new ArrayList<>();

    private final Map<String, RuleClass> ruleClassMap = new HashMap<>();
    private final Map<String, RuleDefinition> ruleDefinitionMap = new HashMap<>();
    private final Map<String, NativeAspectClass> nativeAspectClassMap =
        new HashMap<>();
    private final Map<Class<? extends RuleDefinition>, RuleClass> ruleMap = new HashMap<>();
    private final Digraph<Class<? extends RuleDefinition>> dependencyGraph =
        new Digraph<>();
    private PatchTransition lipoDataTransition;
    private Class<? extends BuildConfiguration.Fragment> universalFragment;
    private PrerequisiteValidator prerequisiteValidator;
    private ImmutableMap.Builder<String, Object> skylarkAccessibleTopLevels =
        ImmutableMap.builder();
    private ImmutableList.Builder<Class<?>> skylarkModules =
        ImmutableList.<Class<?>>builder().addAll(SkylarkModules.MODULES);
    private ImmutableList.Builder<NativeProvider> nativeProviders = ImmutableList.builder();
    private ImmutableBiMap.Builder<String, Class<? extends TransitiveInfoProvider>>
        registeredSkylarkProviders = ImmutableBiMap.builder();
    private Map<String, String> platformRegexps = new TreeMap<>();

    // TODO(pcloudy): Remove this field after Bazel rule definitions are not used internally.
    private String nativeLauncherLabel;

    public Builder setNativeLauncherLabel(String label) {
      this.nativeLauncherLabel = label;
      return this;
    }

    public Builder addWorkspaceFilePrefix(String contents) {
      defaultWorkspaceFilePrefix.append(contents);
      return this;
    }

    public Builder addWorkspaceFileSuffix(String contents) {
      defaultWorkspaceFileSuffix.append(contents);
      return this;
    }

    public Builder setPrelude(String preludeLabelString) {
      try {
        this.preludeLabel = Label.parseAbsolute(preludeLabelString);
      } catch (LabelSyntaxException e) {
        String errorMsg =
            String.format("Prelude label '%s' is invalid: %s", preludeLabelString, e.getMessage());
        throw new IllegalArgumentException(errorMsg);
      }
      return this;
    }

    public Builder setRunfilesPrefix(String runfilesPrefix) {
      this.runfilesPrefix = runfilesPrefix;
      return this;
    }

    public Builder setToolsRepository(String toolsRepository) {
      this.toolsRepository = toolsRepository;
      return this;
    }

    public Builder setPrerequisiteValidator(PrerequisiteValidator prerequisiteValidator) {
      this.prerequisiteValidator = prerequisiteValidator;
      return this;
    }

    public Builder addBuildInfoFactory(BuildInfoFactory factory) {
      buildInfoFactories.add(factory);
      return this;
    }

    public Builder addRuleDefinition(RuleDefinition ruleDefinition) {
      Class<? extends RuleDefinition> ruleDefinitionClass = ruleDefinition.getClass();
      ruleDefinitionMap.put(ruleDefinitionClass.getName(), ruleDefinition);
      dependencyGraph.createNode(ruleDefinitionClass);
      for (Class<? extends RuleDefinition> ancestor : ruleDefinition.getMetadata().ancestors()) {
        dependencyGraph.addEdge(ancestor, ruleDefinitionClass);
      }

      return this;
    }

    public Builder addNativeAspectClass(NativeAspectClass aspectFactoryClass) {
      nativeAspectClassMap.put(aspectFactoryClass.getName(), aspectFactoryClass);
      return this;
    }

    public Builder addConfigurationOptions(Class<? extends FragmentOptions> configurationOptions) {
      this.configurationOptions.add(configurationOptions);
      return this;
    }

    /**
     * Adds an options class and a corresponding factory. There's usually a 1:1:1 correspondence
     * between option classes, factories, and fragments, such that the factory depends only on the
     * options class and creates the fragment. This method provides a convenient way of adding both
     * the options class and the factory in a single call.
     *
     * <p>Note that configuration fragments annotated with a Skylark name must have a unique
     * name; no two different configuration fragments can share the same name.
     */
    public Builder addConfig(
        Class<? extends FragmentOptions> options, ConfigurationFragmentFactory factory) {
      // Enforce that the factory requires the options.
      Preconditions.checkState(factory.requiredOptions().contains(options));
      this.configurationOptions.add(options);
      this.configurationFragmentFactories.add(factory);
      return this;
    }

    public Builder addConfigurationOptions(
        Collection<Class<? extends FragmentOptions>> optionsClasses) {
      this.configurationOptions.addAll(optionsClasses);
      return this;
    }

    /**
     * Adds a configuration fragment factory.
     *
     * <p>Note that configuration fragments annotated with a Skylark name must have a unique
     * name; no two different configuration fragments can share the same name.
     */
    public Builder addConfigurationFragment(ConfigurationFragmentFactory factory) {
      configurationFragmentFactories.add(factory);
      return this;
    }

    public Builder setUniversalConfigurationFragment(
        Class<? extends BuildConfiguration.Fragment> fragment) {
      this.universalFragment = fragment;
      return this;
    }

    public Builder addSkylarkAccessibleTopLevels(String name, Object object) {
      this.skylarkAccessibleTopLevels.put(name, object);
      return this;
    }

    public Builder addSkylarkModule(Class<?>... modules) {
      this.skylarkModules.add(modules);
      return this;
    }

    public Builder addNativeProvider(NativeProvider provider) {
      this.nativeProviders.add(provider);
      return this;
    }

    /**
     * Do not use - this only exists for backwards compatibility! Platform regexps are part of a
     * legacy mechanism - {@code vardef} - that is not exposed in Bazel.
     *
     * <p>{@code vardef} needs explicit support in the rule implementations, and cannot express
     * conditional dependencies, only conditional attribute values. This mechanism will be
     * supplanted by configuration dependent attributes, and its effect can usually also be achieved
     * with select().
     *
     * <p>This is a map of platform names to regexps. When a name is used as the third argument to
     * {@code vardef}, the corresponding regexp is used to match on the C++ abi, and the variable is
     * only set to that value if the regexp matches. For example, the entry
     * {@code "oldlinux": "i[34]86-libc[345]-linux"} might define a set of platforms representing
     * certain older linux releases.
     */
    public Builder addPlatformRegexps(Map<String, String> platformRegexps) {
      this.platformRegexps.putAll(Preconditions.checkNotNull(platformRegexps));
      return this;
    }

    /**
     * Sets the C++ LIPO data transition, as defined in {@link
     * com.google.devtools.build.lib.rules.cpp.transitions.DisableLipoTransition}.
     *
     * <p>This is language-specific, so doesn't really belong here. But since non-C++ rules declare
     * this transition, we need universal access to it. The need for this interface should go away
     * on the deprecation of LIPO for
     * <a href="https://clang.llvm.org/docs/ThinLTO.html">ThinLTO</a>.
     */
    public Builder setLipoDataTransition(PatchTransition transition) {
      Preconditions.checkState(lipoDataTransition == null, "LIPO data transition already set");
      lipoDataTransition = Preconditions.checkNotNull(transition);
      return this;
    }

    @Override
    public PatchTransition getLipoDataTransition() {
      Preconditions.checkState(lipoDataTransition != null);
      return lipoDataTransition;
    }

    private RuleConfiguredTargetFactory createFactory(
        Class<? extends RuleConfiguredTargetFactory> factoryClass) {
      try {
        Constructor<? extends RuleConfiguredTargetFactory> ctor = factoryClass.getConstructor();
        return ctor.newInstance();
      } catch (NoSuchMethodException | IllegalAccessException | InstantiationException
          | InvocationTargetException e) {
        throw new IllegalStateException(e);
      }
    }

    private RuleClass commitRuleDefinition(Class<? extends RuleDefinition> definitionClass) {
      RuleDefinition instance = checkNotNull(ruleDefinitionMap.get(definitionClass.getName()),
          "addRuleDefinition(new %s()) should be called before build()", definitionClass.getName());

      RuleDefinition.Metadata metadata = instance.getMetadata();
      checkArgument(
          ruleClassMap.get(metadata.name()) == null,
          "The rule " + metadata.name() + " was committed already, use another name");

      List<Class<? extends RuleDefinition>> ancestors = metadata.ancestors();

      checkArgument(
          metadata.type() == ABSTRACT ^ metadata.factoryClass()
              != RuleConfiguredTargetFactory.class);
      checkArgument(
          (metadata.type() != TEST)
          || ancestors.contains(BaseRuleClasses.TestBaseRule.class));

      RuleClass[] ancestorClasses = new RuleClass[ancestors.size()];
      for (int i = 0; i < ancestorClasses.length; i++) {
        ancestorClasses[i] = ruleMap.get(ancestors.get(i));
        if (ancestorClasses[i] == null) {
          // Ancestors should have been initialized by now
          throw new IllegalStateException("Ancestor " + ancestors.get(i) + " of "
              + metadata.name() + " is not initialized");
        }
      }

      RuleConfiguredTargetFactory factory = null;
      if (metadata.type() != ABSTRACT) {
        factory = createFactory(metadata.factoryClass());
      }

      RuleClass.Builder builder = new RuleClass.Builder(
          metadata.name(), metadata.type(), false, ancestorClasses);
      builder.factory(factory);
      RuleClass ruleClass = instance.build(builder, this);
      ruleMap.put(definitionClass, ruleClass);
      ruleClassMap.put(ruleClass.getName(), ruleClass);
      ruleDefinitionMap.put(ruleClass.getName(), instance);

      return ruleClass;
    }

    public ConfiguredRuleClassProvider build() {
      for (Node<Class<? extends RuleDefinition>> ruleDefinition :
          dependencyGraph.getTopologicalOrder()) {
        commitRuleDefinition(ruleDefinition.getLabel());
      }

      return new ConfiguredRuleClassProvider(
          preludeLabel,
          runfilesPrefix,
          toolsRepository,
          ImmutableMap.copyOf(ruleClassMap),
          ImmutableMap.copyOf(ruleDefinitionMap),
          ImmutableMap.copyOf(nativeAspectClassMap),
          defaultWorkspaceFilePrefix.toString(),
          defaultWorkspaceFileSuffix.toString(),
          ImmutableList.copyOf(buildInfoFactories),
          ImmutableList.copyOf(configurationOptions),
          ImmutableList.copyOf(configurationFragmentFactories),
          lipoDataTransition,
          universalFragment,
          prerequisiteValidator,
          skylarkAccessibleTopLevels.build(),
          skylarkModules.build(),
          nativeProviders.build());
    }

    @Override
    public Label getLabel(String labelValue) {
      return LABELS.getUnchecked(labelValue);
    }

    @Override
    public Label getToolsLabel(String labelValue) {
      return getLabel(toolsRepository + labelValue);
    }

    @Override
    public Label getLauncherLabel() {
      if (nativeLauncherLabel == null) {
        return null;
      }
      return getToolsLabel(nativeLauncherLabel);
    }

    @Override
    public String getToolsRepository() {
      return toolsRepository;
    }

    @Nullable
    public Map<String, String> getPlatformRegexps() {
      return platformRegexps.isEmpty() ? null : ImmutableMap.copyOf(platformRegexps);
    }
  }

  /**
   * Used to make the label instances unique, so that we don't create a new
   * instance for every rule.
   */
  private static final LoadingCache<String, Label> LABELS = CacheBuilder.newBuilder().build(
      new CacheLoader<String, Label>() {
    @Override
    public Label load(String from) {
      try {
        return Label.parseAbsolute(from);
      } catch (LabelSyntaxException e) {
        throw new IllegalArgumentException(from, e);
      }
    }
  });

  /**
   * Default content that should be added at the beginning of the WORKSPACE file.
   */
  private final String defaultWorkspaceFilePrefix;

  /**
   * Default content that should be added at the end of the WORKSPACE file.
   */
  private final String defaultWorkspaceFileSuffix;


  /**
   * Label for the prelude file.
   */
  private final Label preludeLabel;

  /**
   * The default runfiles prefix.
   */
  private final String runfilesPrefix;

  /**
   * The path to the tools repository.
   */
  private final String toolsRepository;

  /**
   * Maps rule class name to the metaclass instance for that rule.
   */
  private final ImmutableMap<String, RuleClass> ruleClassMap;

  /**
   * Maps rule class name to the rule definition objects.
   */
  private final ImmutableMap<String, RuleDefinition> ruleDefinitionMap;

  /**
   * Maps aspect name to the aspect factory meta class.
   */
  private final ImmutableMap<String, NativeAspectClass> nativeAspectClassMap;

  /**
   * The configuration options that affect the behavior of the rules.
   */
  private final ImmutableList<Class<? extends FragmentOptions>> configurationOptions;

  /** The set of configuration fragment factories. */
  private final ImmutableList<ConfigurationFragmentFactory> configurationFragmentFactories;

  private final PatchTransition lipoDataTransition;

  /**
   * A configuration fragment that should be available to all rules even when they don't
   * explicitly require it.
   */
  private final Class<? extends BuildConfiguration.Fragment> universalFragment;

  private final ImmutableList<BuildInfoFactory> buildInfoFactories;

  private final PrerequisiteValidator prerequisiteValidator;

  private final Environment.GlobalFrame globals;

  private final ImmutableList<NativeProvider> nativeProviders;

  private final ImmutableMap<String, Class<?>> configurationFragmentMap;

  private ConfiguredRuleClassProvider(
      Label preludeLabel,
      String runfilesPrefix,
      String toolsRepository,
      ImmutableMap<String, RuleClass> ruleClassMap,
      ImmutableMap<String, RuleDefinition> ruleDefinitionMap,
      ImmutableMap<String, NativeAspectClass> nativeAspectClassMap,
      String defaultWorkspaceFilePrefix,
      String defaultWorkspaceFileSuffix,
      ImmutableList<BuildInfoFactory> buildInfoFactories,
      ImmutableList<Class<? extends FragmentOptions>> configurationOptions,
      ImmutableList<ConfigurationFragmentFactory> configurationFragments,
      PatchTransition lipoDataTransition,
      Class<? extends BuildConfiguration.Fragment> universalFragment,
      PrerequisiteValidator prerequisiteValidator,
      ImmutableMap<String, Object> skylarkAccessibleJavaClasses,
      ImmutableList<Class<?>> skylarkModules,
      ImmutableList<NativeProvider> nativeProviders) {
    this.preludeLabel = preludeLabel;
    this.runfilesPrefix = runfilesPrefix;
    this.toolsRepository = toolsRepository;
    this.ruleClassMap = ruleClassMap;
    this.ruleDefinitionMap = ruleDefinitionMap;
    this.nativeAspectClassMap = nativeAspectClassMap;
    this.defaultWorkspaceFilePrefix = defaultWorkspaceFilePrefix;
    this.defaultWorkspaceFileSuffix = defaultWorkspaceFileSuffix;
    this.buildInfoFactories = buildInfoFactories;
    this.configurationOptions = configurationOptions;
    this.configurationFragmentFactories = configurationFragments;
    this.lipoDataTransition = lipoDataTransition;
    this.universalFragment = universalFragment;
    this.prerequisiteValidator = prerequisiteValidator;
    this.globals = createGlobals(skylarkAccessibleJavaClasses, skylarkModules);
    this.nativeProviders = nativeProviders;
    this.configurationFragmentMap = createFragmentMap(configurationFragmentFactories);
  }

  public PrerequisiteValidator getPrerequisiteValidator() {
    return prerequisiteValidator;
  }

  @Override
  public Label getPreludeLabel() {
    return preludeLabel;
  }

  @Override
  public String getRunfilesPrefix() {
    return runfilesPrefix;
  }

  @Override
  public String getToolsRepository() {
    return toolsRepository;
  }

  @Override
  public Map<String, RuleClass> getRuleClassMap() {
    return ruleClassMap;
  }

  @Override
  public Map<String, NativeAspectClass> getNativeAspectClassMap() {
    return nativeAspectClassMap;
  }

  @Override
  public NativeAspectClass getNativeAspectClass(String key) {
    return nativeAspectClassMap.get(key);
  }

  /**
   * Returns a list of build info factories that are needed for the supported languages.
   */
  public ImmutableList<BuildInfoFactory> getBuildInfoFactories() {
    return buildInfoFactories;
  }

  /**
   * Returns the set of configuration fragments provided by this module.
   */
  public ImmutableList<ConfigurationFragmentFactory> getConfigurationFragments() {
    return configurationFragmentFactories;
  }

  /**
   * Returns the C++ LIPO data transition, as defined in {@link
   * com.google.devtools.build.lib.rules.cpp.transitions.DisableLipoTransition}.
   *
   * <p>This is language-specific, so doesn't really belong here. But since non-C++ rules declare
   * this transition, we need universal access to it. The need for this interface should go away on
   * the deprecation of LIPO for <a href="https://clang.llvm.org/docs/ThinLTO.html">ThinLTO</a>.
   */
  public PatchTransition getLipoDataTransition() {
    return lipoDataTransition;
  }

  /**
   * Returns the set of configuration options that are supported in this module.
   */
  public ImmutableList<Class<? extends FragmentOptions>> getConfigurationOptions() {
    return configurationOptions;
  }

  /**
   * Returns the definition of the rule class definition with the specified name.
   */
  public RuleDefinition getRuleClassDefinition(String ruleClassName) {
    return ruleDefinitionMap.get(ruleClassName);
  }

  /**
   * Returns the configuration fragment that should be available to all rules even when they
   * don't explicitly require it.
   */
  public Class<? extends BuildConfiguration.Fragment> getUniversalFragment() {
    return universalFragment;
  }

  /**
   * Returns the defaults package for the default settings.
   */
  public String getDefaultsPackageContent(InvocationPolicy invocationPolicy) {
    return DefaultsPackage.getDefaultsPackageContent(configurationOptions, invocationPolicy);
  }

  /**
   * Returns the defaults package for the given options taken from an optionsProvider.
   */
  public String getDefaultsPackageContent(OptionsClassProvider optionsProvider) {
    return DefaultsPackage.getDefaultsPackageContent(
        BuildOptions.of(configurationOptions, optionsProvider));
  }

  /**
   * Creates a BuildOptions class for the given options taken from an optionsProvider.
   */
  public BuildOptions createBuildOptions(OptionsClassProvider optionsProvider) {
    return BuildOptions.of(configurationOptions, optionsProvider);
  }

  private Environment.GlobalFrame createGlobals(
      ImmutableMap<String, Object> skylarkAccessibleToplLevels,
      ImmutableList<Class<?>> modules) {
    try (Mutability mutability = Mutability.create("ConfiguredRuleClassProvider globals")) {
      Environment env = createSkylarkRuleClassEnvironment(
          mutability,
          SkylarkModules.getGlobals(modules),
          SkylarkSemantics.DEFAULT_SEMANTICS,
          /*eventHandler=*/ null,
          /*astFileContentHashCode=*/ null,
          /*importMap=*/ null);
      for (Map.Entry<String, Object> entry : skylarkAccessibleToplLevels.entrySet()) {
        env.setup(entry.getKey(), entry.getValue());
      }
      return env.getGlobals();
    }
  }

  private static ImmutableMap<String, Class<?>> createFragmentMap(
      Iterable<ConfigurationFragmentFactory> configurationFragmentFactories) {
    ImmutableMap.Builder<String, Class<?>> mapBuilder = ImmutableMap.builder();
    for (ConfigurationFragmentFactory fragmentFactory : configurationFragmentFactories) {
      Class<? extends Fragment> fragmentClass = fragmentFactory.creates();
      String fragmentName = SkylarkModule.Resolver.resolveName(fragmentClass);
      if (fragmentName != null) {
        mapBuilder.put(fragmentName, fragmentClass);
      }
    }
    return mapBuilder.build();
  }

  private Environment createSkylarkRuleClassEnvironment(
      Mutability mutability,
      Environment.GlobalFrame globals,
      SkylarkSemantics skylarkSemantics,
      EventHandler eventHandler,
      String astFileContentHashCode,
      Map<String, Extension> importMap) {
    Environment env =
        Environment.builder(mutability)
            .setGlobals(globals)
            .setSemantics(skylarkSemantics)
            .setEventHandler(eventHandler)
            .setFileContentHashCode(astFileContentHashCode)
            .setImportedExtensions(importMap)
            .setPhase(Phase.LOADING)
            .build();
    SkylarkUtils.setToolsRepository(env, toolsRepository);
    SkylarkUtils.setFragmentMap(env, configurationFragmentMap);
    SkylarkUtils.setLipoDataTransition(env, getLipoDataTransition());
    return env;
  }

  @Override
  public Environment createSkylarkRuleClassEnvironment(
      Label extensionLabel,
      Mutability mutability,
      SkylarkSemantics skylarkSemantics,
      EventHandler eventHandler,
      String astFileContentHashCode,
      Map<String, Extension> importMap) {
    return createSkylarkRuleClassEnvironment(
        mutability,
        globals.withLabel(extensionLabel),
        skylarkSemantics,
        eventHandler,
        astFileContentHashCode,
        importMap);
  }

  @Override
  public String getDefaultWorkspacePrefix() {
    return defaultWorkspaceFilePrefix;
  }

  @Override
  public String getDefaultWorkspaceSuffix() {
    return defaultWorkspaceFileSuffix;
  }

  @Override
  public Map<String, Class<?>> getConfigurationFragmentMap() {
    return configurationFragmentMap;
  }

  /** Returns all skylark objects in global scope for this RuleClassProvider. */
  public Map<String, Object> getTransitiveGlobalBindings() {
    return globals.getTransitiveBindings();
  }

  /** Returns all registered {@link BuildConfiguration.Fragment} classes. */
  public ImmutableSortedSet<Class<? extends BuildConfiguration.Fragment>> getAllFragments() {
    ImmutableSortedSet.Builder<Class<? extends BuildConfiguration.Fragment>> fragmentsBuilder =
        ImmutableSortedSet.orderedBy(BuildConfiguration.lexicalFragmentSorter);
    for (ConfigurationFragmentFactory factory : getConfigurationFragments()) {
      fragmentsBuilder.add(factory.creates());
    }
    fragmentsBuilder.add(getUniversalFragment());
    return fragmentsBuilder.build();
  }

  /**
   * Returns all registered {@link NativeProvider} instances, i.e. all built-in provider types that
   * are based on {@link Provider} rather than {@link TransitiveInfoProvider}.
   */
  public ImmutableList<NativeProvider> getNativeProviders() {
    return nativeProviders;
  }
}
