// Copyright 2021 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.bazel.bzlmod;

import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.docgen.annot.GlobalMethods;
import com.google.devtools.build.docgen.annot.GlobalMethods.Environment;
import com.google.devtools.build.lib.bazel.bzlmod.InterimModule.DepSpec;
import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileGlobals.ModuleExtensionUsageBuilder.ModuleExtensionProxy;
import com.google.devtools.build.lib.bazel.bzlmod.Version.ParseException;
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.cmdline.RepositoryMapping;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.StarlarkExportable;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import net.starlark.java.annot.Param;
import net.starlark.java.annot.ParamType;
import net.starlark.java.annot.StarlarkBuiltin;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.Dict;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkInt;
import net.starlark.java.eval.StarlarkThread;
import net.starlark.java.eval.StarlarkValue;
import net.starlark.java.eval.Structure;
import net.starlark.java.eval.Tuple;
import net.starlark.java.syntax.Location;

/** A collection of global Starlark build API functions that apply to MODULE.bazel files. */
@GlobalMethods(environment = Environment.MODULE)
public class ModuleFileGlobals {

  /* Valid bazel compatibility argument must 1) start with (<,<=,>,>=,-);
     2) then contain a version number in form of X.X.X where X has one or two digits
  */
  private static final Pattern VALID_BAZEL_COMPATIBILITY_VERSION =
      Pattern.compile("(>|<|-|<=|>=)(\\d+\\.){2}\\d+");

  private boolean moduleCalled = false;
  private boolean hadNonModuleCall = false;
  private final boolean ignoreDevDeps;
  private final InterimModule.Builder module;
  private final ImmutableMap<String, NonRegistryOverride> builtinModules;
  private final Map<String, DepSpec> deps = new LinkedHashMap<>();
  private final List<ModuleExtensionUsageBuilder> extensionUsageBuilders = new ArrayList<>();
  private final Map<String, ModuleOverride> overrides = new HashMap<>();
  private final Map<String, RepoNameUsage> repoNameUsages = new HashMap<>();

  public ModuleFileGlobals(
      ImmutableMap<String, NonRegistryOverride> builtinModules,
      ModuleKey key,
      @Nullable Registry registry,
      boolean ignoreDevDeps) {
    module = InterimModule.builder().setKey(key).setRegistry(registry);
    this.ignoreDevDeps = ignoreDevDeps;
    this.builtinModules = builtinModules;
  }

  @AutoValue
  abstract static class RepoNameUsage {
    abstract String getHow();

    abstract Location getWhere();
  }

  private void addRepoNameUsage(String repoName, String how, Location where) throws EvalException {
    RepoNameUsage collision =
        repoNameUsages.put(repoName, new AutoValue_ModuleFileGlobals_RepoNameUsage(how, where));
    if (collision != null) {
      throw Starlark.errorf(
          "The repo name '%s' is already being used %s at %s",
          repoName, collision.getHow(), collision.getWhere());
    }
  }

  @VisibleForTesting
  static void validateModuleName(String moduleName) throws EvalException {
    if (!RepositoryName.VALID_MODULE_NAME.matcher(moduleName).matches()) {
      throw Starlark.errorf(
          "invalid module name '%s': valid names must 1) only contain lowercase letters (a-z),"
              + " digits (0-9), dots (.), hyphens (-), and underscores (_); 2) begin with a"
              + " lowercase letter; 3) end with a lowercase letter or digit.",
          moduleName);
    }
  }

  @StarlarkMethod(
      name = "module",
      doc =
          "Declares certain properties of the Bazel module represented by the current Bazel repo."
              + " These properties are either essential metadata of the module (such as the name"
              + " and version), or affect behavior of the current module and its dependents.  <p>It"
              + " should be called at most once. It can be omitted only if this module is the root"
              + " module (as in, if it's not going to be depended on by another module).",
      parameters = {
        @Param(
            name = "name",
            doc =
                "The name of the module. Can be omitted only if this module is the root module (as"
                    + " in, if it's not going to be depended on by another module). A valid module"
                    + " name must: 1) only contain lowercase letters (a-z), digits (0-9), dots (.),"
                    + " hyphens (-), and underscores (_); 2) begin with a lowercase letter; 3) end"
                    + " with a lowercase letter or digit.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "version",
            doc =
                "The version of the module. Can be omitted only if this module is the root module"
                    + " (as in, if it's not going to be depended on by another module). The version"
                    + " must be in a relaxed SemVer format; see <a"
                    + " href=\"/external/module#version_format\">the documentation</a> for more"
                    + " details.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "compatibility_level",
            doc =
                "The compatibility level of the module; this should be changed every time a major"
                    + " incompatible change is introduced. This is essentially the \"major"
                    + " version\" of the module in terms of SemVer, except that it's not embedded"
                    + " in the version string itself, but exists as a separate field. Modules with"
                    + " different compatibility levels participate in version resolution as if"
                    + " they're modules with different names, but the final dependency graph cannot"
                    + " contain multiple modules with the same name but different compatibility"
                    + " levels (unless <code>multiple_version_override</code> is in effect). See <a"
                    + " href=\"/external/module#compatibility_level\">the documentation</a> for"
                    + " more details.",
            named = true,
            positional = false,
            defaultValue = "0"),
        @Param(
            name = "repo_name",
            doc =
                "The name of the repository representing this module, as seen by the module itself."
                    + " By default, the name of the repo is the name of the module. This can be"
                    + " specified to ease migration for projects that have been using a repo name"
                    + " for itself that differs from its module name.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "bazel_compatibility",
            doc =
                "A list of bazel versions that allows users to declare which Bazel versions"
                    + " are compatible with this module. It does NOT affect dependency resolution,"
                    + " but bzlmod will use this information to check if your current Bazel version"
                    + " is compatible. The format of this value is a string of some constraint"
                    + " values separated by comma. Three constraints are supported: <=X.X.X: The"
                    + " Bazel version must be equal or older than X.X.X. Used when there is a known"
                    + " incompatible change in a newer version. >=X.X.X: The Bazel version must be"
                    + " equal or newer than X.X.X.Used when you depend on some features that are"
                    + " only available since X.X.X. -X.X.X: The Bazel version X.X.X is not"
                    + " compatible. Used when there is a bug in X.X.X that breaks you, but fixed in"
                    + " later versions.",
            named = true,
            positional = false,
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            defaultValue = "[]"),
      },
      useStarlarkThread = true)
  public void module(
      String name,
      String version,
      StarlarkInt compatibilityLevel,
      String repoName,
      Iterable<?> bazelCompatibility,
      StarlarkThread thread)
      throws EvalException {
    if (moduleCalled) {
      throw Starlark.errorf("the module() directive can only be called once");
    }
    if (hadNonModuleCall) {
      throw Starlark.errorf("if module() is called, it must be called before any other functions");
    }
    moduleCalled = true;
    if (!name.isEmpty()) {
      validateModuleName(name);
    }
    if (repoName.isEmpty()) {
      repoName = name;
      addRepoNameUsage(name, "as the current module name", thread.getCallerLocation());
    } else {
      RepositoryName.validateUserProvidedRepoName(repoName);
      addRepoNameUsage(repoName, "as the module's own repo name", thread.getCallerLocation());
    }
    Version parsedVersion;
    try {
      parsedVersion = Version.parse(version);
    } catch (ParseException e) {
      throw new EvalException("Invalid version in module()", e);
    }
    module
        .setName(name)
        .setVersion(parsedVersion)
        .setCompatibilityLevel(compatibilityLevel.toInt("compatibility_level"))
        .addBazelCompatibilityValues(
            checkAllCompatibilityVersions(bazelCompatibility, "bazel_compatibility"))
        .setRepoName(repoName);
  }

  private static ImmutableList<String> checkAllAbsolutePatterns(Iterable<?> iterable, String where)
      throws EvalException {
    Sequence<String> list = Sequence.cast(iterable, String.class, where);
    for (String item : list) {
      if (!item.startsWith("//") && !item.startsWith("@")) {
        throw Starlark.errorf(
            "Expected absolute target patterns (must begin with '//' or '@') for '%s' argument, but"
                + " got '%s' as an argument",
            where, item);
      }
    }
    return list.getImmutableList();
  }

  private static ImmutableList<String> checkAllCompatibilityVersions(
      Iterable<?> iterable, String where) throws EvalException {
    Sequence<String> list = Sequence.cast(iterable, String.class, where);
    for (String version : list) {
      if (!VALID_BAZEL_COMPATIBILITY_VERSION.matcher(version).matches()) {
        throw Starlark.errorf(
            "invalid version argument '%s': valid argument must 1) start with (<,<=,>,>=,-); "
                + "2) contain a version number in form of X.X.X where X is a number",
            version);
      }
    }
    return list.getImmutableList();
  }

  @StarlarkMethod(
      name = "bazel_dep",
      doc = "Declares a direct dependency on another Bazel module.",
      parameters = {
        @Param(
            name = "name",
            doc = "The name of the module to be added as a direct dependency.",
            named = true,
            positional = false),
        @Param(
            name = "version",
            doc = "The version of the module to be added as a direct dependency.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "max_compatibility_level",
            doc =
                "The maximum <code>compatibility_level</code> supported for the module to be added"
                    + " as a direct dependency. The version of the module implies the minimum"
                    + " compatibility_level supported, as well as the maximum if this attribute is"
                    + " not specified.",
            named = true,
            positional = false,
            defaultValue = "-1"),
        @Param(
            name = "repo_name",
            doc =
                "The name of the external repo representing this dependency. This is by default the"
                    + " name of the module.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "dev_dependency",
            doc =
                "If true, this dependency will be ignored if the current module is not the root"
                    + " module or `--ignore_dev_dependency` is enabled.",
            named = true,
            positional = false,
            defaultValue = "False"),
      },
      useStarlarkThread = true)
  public void bazelDep(
      String name,
      String version,
      StarlarkInt maxCompatibilityLevel,
      String repoName,
      boolean devDependency,
      StarlarkThread thread)
      throws EvalException {
    hadNonModuleCall = true;
    if (repoName.isEmpty()) {
      repoName = name;
    }
    validateModuleName(name);
    Version parsedVersion;
    try {
      parsedVersion = Version.parse(version);
    } catch (ParseException e) {
      throw new EvalException("Invalid version in bazel_dep()", e);
    }
    RepositoryName.validateUserProvidedRepoName(repoName);

    if (!(ignoreDevDeps && devDependency)) {
      deps.put(
          repoName,
          DepSpec.create(
              name, parsedVersion, maxCompatibilityLevel.toInt("max_compatibility_level")));
    }

    addRepoNameUsage(repoName, "by a bazel_dep", thread.getCallerLocation());
  }

  @StarlarkMethod(
      name = "register_execution_platforms",
      doc =
          "Specifies already-defined execution platforms to be registered when this module is"
              + " selected. Should be absolute target patterns (ie. beginning with either"
              + " <code>@</code> or <code>//</code>). See <a href=\"${link toolchains}\">toolchain"
              + " resolution</a> for more information.",
      parameters = {
        @Param(
            name = "dev_dependency",
            doc =
                "If true, the execution platforms will not be registered if the current module is"
                    + " not the root module or `--ignore_dev_dependency` is enabled.",
            named = true,
            positional = false,
            defaultValue = "False"),
      },
      extraPositionals =
          @Param(
              name = "platform_labels",
              allowedTypes = {@ParamType(type = Sequence.class, generic1 = String.class)},
              doc = "The labels of the platforms to register."))
  public void registerExecutionPlatforms(boolean devDependency, Sequence<?> platformLabels)
      throws EvalException {
    hadNonModuleCall = true;
    if (ignoreDevDeps && devDependency) {
      return;
    }
    module.addExecutionPlatformsToRegister(
        checkAllAbsolutePatterns(platformLabels, "register_execution_platforms"));
  }

  @StarlarkMethod(
      name = "register_toolchains",
      doc =
          "Specifies already-defined toolchains to be registered when this module is selected."
              + " Should be absolute target patterns (ie. beginning with either <code>@</code> or"
              + " <code>//</code>). See <a href=\"${link toolchains}\">toolchain resolution</a> for"
              + " more information.",
      parameters = {
        @Param(
            name = "dev_dependency",
            doc =
                "If true, the toolchains will not be registered if the current module is not the"
                    + " root module or `--ignore_dev_dependency` is enabled.",
            named = true,
            positional = false,
            defaultValue = "False"),
      },
      extraPositionals =
          @Param(
              name = "toolchain_labels",
              allowedTypes = {@ParamType(type = Sequence.class, generic1 = String.class)},
              doc =
                  "The labels of the toolchains to register. Labels can include "
                      + "<code>:all</code>, in which case, all toolchain-providing targets in the "
                      + "package will be registered in lexicographical order by name."))
  public void registerToolchains(boolean devDependency, Sequence<?> toolchainLabels)
      throws EvalException {
    hadNonModuleCall = true;
    if (ignoreDevDeps && devDependency) {
      return;
    }
    module.addToolchainsToRegister(
        checkAllAbsolutePatterns(toolchainLabels, "register_toolchains"));
  }

  @StarlarkMethod(
      name = "use_extension",
      doc =
          "Returns a proxy object representing a module extension; its methods can be invoked to"
              + " create module extension tags.",
      parameters = {
        @Param(
            name = "extension_bzl_file",
            doc = "A label to the Starlark file defining the module extension."),
        @Param(
            name = "extension_name",
            doc =
                "The name of the module extension to use. A symbol with this name must be exported"
                    + " by the Starlark file."),
        @Param(
            name = "dev_dependency",
            doc =
                "If true, this usage of the module extension will be ignored if the current module"
                    + " is not the root module or `--ignore_dev_dependency` is enabled.",
            named = true,
            positional = false,
            defaultValue = "False"),
        @Param(
            name = "isolate",
            doc =
                "If true, this usage of the module extension will be isolated from all other "
                    + "usages, both in this and other modules. Tags created for this usage do not "
                    + "affect other usages and the repositories generated by the extension for "
                    + "this usage will be distinct from all other repositories generated by the "
                    + "extension."
                    + "<p>This parameter is currently experimental and only available with the "
                    + "flag <code>--experimental_isolated_extension_usages</code>.",
            named = true,
            positional = false,
            defaultValue = "False",
            enableOnlyWithFlag = "-experimental_isolated_extension_usages",
            valueWhenDisabled = "False"),
      },
      useStarlarkThread = true)
  public ModuleExtensionProxy useExtension(
      String rawExtensionBzlFile,
      String extensionName,
      boolean devDependency,
      boolean isolate,
      StarlarkThread thread)
      throws EvalException {
    hadNonModuleCall = true;

    if (extensionName.equals(ModuleExtensionId.INNATE_EXTENSION_NAME)) {
      throw Starlark.errorf(
          "innate extensions cannot be directly used; try `use_repo_rule` instead");
    }

    String extensionBzlFile = normalizeLabelString(rawExtensionBzlFile);
    ModuleExtensionUsageBuilder newUsageBuilder =
        new ModuleExtensionUsageBuilder(
            extensionBzlFile, extensionName, isolate, thread.getCallerLocation());

    if (ignoreDevDeps && devDependency) {
      // This is a no-op proxy.
      return newUsageBuilder.getProxy(devDependency);
    }

    // Find an existing usage builder corresponding to this extension. Isolated usages need to get
    // their own proxy.
    if (!isolate) {
      for (ModuleExtensionUsageBuilder usageBuilder : extensionUsageBuilders) {
        if (usageBuilder.extensionBzlFile.equals(extensionBzlFile)
            && usageBuilder.extensionName.equals(extensionName)
            && !usageBuilder.isolate) {
          return usageBuilder.getProxy(devDependency);
        }
      }
    }

    // If no such proxy exists, we can just use a new one.
    extensionUsageBuilders.add(newUsageBuilder);
    return newUsageBuilder.getProxy(devDependency);
  }

  private String normalizeLabelString(String rawExtensionBzlFile) {
    // Normalize the label by parsing and stringifying it with a repo mapping that preserves the
    // apparent repository name, except that a reference to the main repository via the empty
    // repo name is translated to using the module repo name. This is necessary as
    // ModuleExtensionUsages are grouped by the string value of this label, but later mapped to
    // their Label representation. If multiple strings map to the same Label, this would result in a
    // crash.
    // ownName can't change anymore as calling module() after this results in an error.
    String ownName = module.getRepoName().orElse(module.getName());
    RepositoryName ownRepoName = RepositoryName.createUnvalidated(ownName);
    try {
      ImmutableMap<String, RepositoryName> repoMapping = ImmutableMap.of();
      if (module.getKey().equals(ModuleKey.ROOT)) {
        repoMapping = ImmutableMap.of("", ownRepoName);
      }
      Label label =
          Label.parseWithPackageContext(
              rawExtensionBzlFile,
              Label.PackageContext.of(
                  PackageIdentifier.create(ownRepoName, PathFragment.EMPTY_FRAGMENT),
                  RepositoryMapping.createAllowingFallback(repoMapping)));
      // Skip over the leading "@" of the unambiguous form.
      return label.getUnambiguousCanonicalForm().substring(1);
    } catch (LabelSyntaxException ignored) {
      // Preserve backwards compatibility by not failing eagerly, rather keep the invalid label and
      // let the extension fail when evaluated.
      return rawExtensionBzlFile;
    }
  }

  /**
   * Returns a {@link Label} when the given string is a valid label, otherwise the string itself.
   */
  private Object parseOverrideLabelAttribute(String rawLabel) {
    RepositoryMapping repoMapping =
        RepositoryMapping.create(
            ImmutableMap.<String, RepositoryName>builder()
                .put("", RepositoryName.MAIN)
                .put(module.getRepoName().orElse(module.getName()), RepositoryName.MAIN)
                .buildKeepingLast(),
            RepositoryName.MAIN);
    try {
      return Label.parseWithPackageContext(
          rawLabel, Label.PackageContext.of(PackageIdentifier.EMPTY_PACKAGE_ID, repoMapping));
    } catch (LabelSyntaxException e) {
      // Preserve backwards compatibility by not failing eagerly, rather keep the invalid label and
      // let the module repo fail when fetched.
      return rawLabel;
    }
  }

  class ModuleExtensionUsageBuilder {
    private final String extensionBzlFile;
    private final String extensionName;
    private final boolean isolate;
    private final Location location;
    private final HashBiMap<String, String> imports;
    private final ImmutableSet.Builder<String> devImports;
    private final ImmutableList.Builder<Tag> tags;

    private boolean hasNonDevUseExtension;
    private boolean hasDevUseExtension;
    private String exportedName;

    ModuleExtensionUsageBuilder(
        String extensionBzlFile, String extensionName, boolean isolate, Location location) {
      this.extensionBzlFile = extensionBzlFile;
      this.extensionName = extensionName;
      this.isolate = isolate;
      this.location = location;
      this.imports = HashBiMap.create();
      this.devImports = ImmutableSet.builder();
      this.tags = ImmutableList.builder();
    }

    ModuleExtensionUsage buildUsage() throws EvalException {
      var builder =
          ModuleExtensionUsage.builder()
              .setExtensionBzlFile(extensionBzlFile)
              .setExtensionName(extensionName)
              .setUsingModule(module.getKey())
              .setLocation(location)
              .setImports(ImmutableBiMap.copyOf(imports))
              .setDevImports(devImports.build())
              .setHasDevUseExtension(hasDevUseExtension)
              .setHasNonDevUseExtension(hasNonDevUseExtension)
              .setTags(tags.build());
      if (isolate) {
        if (exportedName == null) {
          throw Starlark.errorf(
              "Isolated extension usage at %s must be assigned to a top-level variable", location);
        }
        builder.setIsolationKey(
            Optional.of(ModuleExtensionId.IsolationKey.create(module.getKey(), exportedName)));
      } else {
        builder.setIsolationKey(Optional.empty());
      }
      return builder.build();
    }

    /**
     * Creates a proxy with the specified dev_dependency bit that shares accumulated imports and
     * tags with all other such proxies, thus preserving their order across dev/non-dev deps.
     */
    ModuleExtensionProxy getProxy(boolean devDependency) {
      if (devDependency) {
        hasDevUseExtension = true;
      } else {
        hasNonDevUseExtension = true;
      }
      return new ModuleExtensionProxy(devDependency);
    }

    @StarlarkBuiltin(name = "module_extension_proxy", documented = false)
    class ModuleExtensionProxy implements Structure, StarlarkExportable {

      private final boolean devDependency;

      private ModuleExtensionProxy(boolean devDependency) {
        this.devDependency = devDependency;
      }

      void addImport(String localRepoName, String exportedName, String byWhat, Location location)
          throws EvalException {
        RepositoryName.validateUserProvidedRepoName(localRepoName);
        RepositoryName.validateUserProvidedRepoName(exportedName);
        addRepoNameUsage(localRepoName, byWhat, location);
        if (imports.containsValue(exportedName)) {
          String collisionRepoName = imports.inverse().get(exportedName);
          throw Starlark.errorf(
              "The repo exported as '%s' by module extension '%s' is already imported at %s",
              exportedName, extensionName, repoNameUsages.get(collisionRepoName).getWhere());
        }
        imports.put(localRepoName, exportedName);
        if (devDependency) {
          devImports.add(exportedName);
        }
      }

      class TagCallable implements StarlarkValue {
        final String tagName;

        TagCallable(String tagName) {
          this.tagName = tagName;
        }

        @StarlarkMethod(
            name = "call",
            selfCall = true,
            documented = false,
            extraKeywords = @Param(name = "kwargs"),
            useStarlarkThread = true)
        public void call(Dict<String, Object> kwargs, StarlarkThread thread) {
          tags.add(
              Tag.builder()
                  .setTagName(tagName)
                  .setAttributeValues(AttributeValues.create(kwargs))
                  .setDevDependency(devDependency)
                  .setLocation(thread.getCallerLocation())
                  .build());
        }
      }

      @Override
      public TagCallable getValue(String tagName) throws EvalException {
        return new TagCallable(tagName);
      }

      @Override
      public ImmutableCollection<String> getFieldNames() {
        return ImmutableList.of();
      }

      @Nullable
      @Override
      public String getErrorMessageForUnknownField(String field) {
        return null;
      }

      @Override
      public boolean isExported() {
        return exportedName != null;
      }

      @Override
      public void export(EventHandler handler, Label bzlFileLabel, String name) {
        exportedName = name;
      }
    }
  }

  @StarlarkMethod(
      name = "use_repo",
      doc =
          "Imports one or more repos generated by the given module extension into the scope of the"
              + " current module.",
      parameters = {
        @Param(
            name = "extension_proxy",
            doc = "A module extension proxy object returned by a <code>use_extension</code> call."),
      },
      extraPositionals = @Param(name = "args", doc = "The names of the repos to import."),
      extraKeywords =
          @Param(
              name = "kwargs",
              doc =
                  "Specifies certain repos to import into the scope of the current module with"
                      + " different names. The keys should be the name to use in the current scope,"
                      + " whereas the values should be the original names exported by the module"
                      + " extension."),
      useStarlarkThread = true)
  public void useRepo(
      ModuleExtensionProxy extensionProxy,
      Tuple args,
      Dict<String, Object> kwargs,
      StarlarkThread thread)
      throws EvalException {
    hadNonModuleCall = true;
    Location location = thread.getCallerLocation();
    for (String arg : Sequence.cast(args, String.class, "args")) {
      extensionProxy.addImport(arg, arg, "by a use_repo() call", location);
    }
    for (Map.Entry<String, String> entry :
        Dict.cast(kwargs, String.class, String.class, "kwargs").entrySet()) {
      extensionProxy.addImport(entry.getKey(), entry.getValue(), "by a use_repo() call", location);
    }
  }

  @StarlarkMethod(
      name = "use_repo_rule",
      doc =
          "Returns a proxy value that can be directly invoked in the MODULE.bazel file as a"
              + " repository rule, one or more times. Repos created in such a way are only visible"
              + " to the current module, under the name declared using the <code>name</code>"
              + " attribute on the proxy. The implicit Boolean <code>dev_dependency</code>"
              + " attribute can also be used on the proxy to denote that a certain repo is only to"
              + " be created when the current module is the root module.",
      parameters = {
        @Param(
            name = "repo_rule_bzl_file",
            doc = "A label to the Starlark file defining the repo rule."),
        @Param(
            name = "repo_rule_name",
            doc =
                "The name of the repo rule to use. A symbol with this name must be exported by the"
                    + " Starlark file."),
      },
      useStarlarkThread = true)
  public RepoRuleProxy useRepoRule(String bzlFile, String ruleName, StarlarkThread thread) {
    hadNonModuleCall = true;
    // The builder for the singular "innate" extension of this module. Note that there's only one
    // such usage (and it's fabricated), so the usage location just points to this file.
    ModuleExtensionUsageBuilder newUsageBuilder =
        new ModuleExtensionUsageBuilder(
            "//:MODULE.bazel",
            ModuleExtensionId.INNATE_EXTENSION_NAME,
            /* isolate= */ false,
            Location.fromFile(thread.getCallerLocation().file()));
    for (ModuleExtensionUsageBuilder usageBuilder : extensionUsageBuilders) {
      if (usageBuilder.extensionBzlFile.equals(newUsageBuilder.extensionBzlFile)
          && usageBuilder.extensionName.equals(newUsageBuilder.extensionName)) {
        return new RepoRuleProxy(usageBuilder, bzlFile + '%' + ruleName);
      }
    }
    extensionUsageBuilders.add(newUsageBuilder);
    return new RepoRuleProxy(newUsageBuilder, bzlFile + '%' + ruleName);
  }

  @StarlarkBuiltin(name = "repo_rule_proxy", documented = false)
  class RepoRuleProxy implements StarlarkValue {
    private final ModuleExtensionUsageBuilder usageBuilder;
    private final String tagName;

    private RepoRuleProxy(ModuleExtensionUsageBuilder usageBuilder, String tagName) {
      this.usageBuilder = usageBuilder;
      this.tagName = tagName;
    }

    @StarlarkMethod(
        name = "call",
        selfCall = true,
        documented = false,
        parameters = {
          @Param(name = "name", positional = false, named = true),
          @Param(name = "dev_dependency", positional = false, named = true, defaultValue = "False")
        },
        extraKeywords = @Param(name = "kwargs"),
        useStarlarkThread = true)
    public void call(
        String name, boolean devDependency, Dict<String, Object> kwargs, StarlarkThread thread)
        throws EvalException {
      RepositoryName.validateUserProvidedRepoName(name);
      if (ignoreDevDeps && devDependency) {
        return;
      }
      kwargs.putEntry("name", name);
      ModuleExtensionProxy extensionProxy = usageBuilder.getProxy(devDependency);
      extensionProxy.getValue(tagName).call(kwargs, thread);
      extensionProxy.addImport(name, name, "by a repo rule", thread.getCallerLocation());
    }
  }

  private void addOverride(String moduleName, ModuleOverride override) throws EvalException {
    validateModuleName(moduleName);
    ModuleOverride existingOverride = overrides.putIfAbsent(moduleName, override);
    if (existingOverride != null) {
      throw Starlark.errorf("multiple overrides for dep %s found", moduleName);
    }
  }

  @StarlarkMethod(
      name = "single_version_override",
      doc =
          "Specifies that a dependency should still come from a registry, but its version should"
              + " be pinned, or its registry overridden, or a list of patches applied. This"
              + " directive only takes effect in the root module; in other words, if a module"
              + " is used as a dependency by others, its own overrides are ignored.",
      parameters = {
        @Param(
            name = "module_name",
            doc = "The name of the Bazel module dependency to apply this override to.",
            named = true,
            positional = false),
        @Param(
            name = "version",
            doc =
                "Overrides the declared version of this module in the dependency graph. In other"
                    + " words, this module will be \"pinned\" to this override version. This"
                    + " attribute can be omitted if all one wants to override is the registry or"
                    + " the patches. ",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "registry",
            doc =
                "Overrides the registry for this module; instead of finding this module from the"
                    + " default list of registries, the given registry should be used.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "patches",
            doc =
                "A list of labels pointing to patch files to apply for this module. The patch files"
                    + " must exist in the source tree of the top level project. They are applied in"
                    + " the list order.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_cmds",
            doc =
                "Sequence of Bash commands to be applied on Linux/Macos after patches are applied.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_strip",
            doc = "Same as the --strip argument of Unix patch.",
            named = true,
            positional = false,
            defaultValue = "0"),
      })
  public void singleVersionOverride(
      String moduleName,
      String version,
      String registry,
      Iterable<?> patches,
      Iterable<?> patchCmds,
      StarlarkInt patchStrip)
      throws EvalException {
    hadNonModuleCall = true;
    Version parsedVersion;
    try {
      parsedVersion = Version.parse(version);
    } catch (ParseException e) {
      throw new EvalException("Invalid version in single_version_override()", e);
    }
    addOverride(
        moduleName,
        SingleVersionOverride.create(
            parsedVersion,
            registry,
            Sequence.cast(patches, String.class, "patches").stream()
                .map(this::parseOverrideLabelAttribute)
                .collect(toImmutableList()),
            Sequence.cast(patchCmds, String.class, "patchCmds").getImmutableList(),
            patchStrip.toInt("single_version_override.patch_strip")));
  }

  @StarlarkMethod(
      name = "multiple_version_override",
      doc =
          "Specifies that a dependency should still come from a registry, but multiple versions of"
              + " it should be allowed to coexist. See <a"
              + " href=\"/external/module#multiple-version_override\">the documentation</a> for"
              + " more details. This"
              + " directive only takes effect in the root module; in other words, if a module"
              + " is used as a dependency by others, its own overrides are ignored.",
      parameters = {
        @Param(
            name = "module_name",
            doc = "The name of the Bazel module dependency to apply this override to.",
            named = true,
            positional = false),
        @Param(
            name = "versions",
            doc =
                "Explicitly specifies the versions allowed to coexist. These versions must already"
                    + " be present in the dependency graph pre-selection. Dependencies on this"
                    + " module will be \"upgraded\" to the nearest higher allowed version at the"
                    + " same compatibility level, whereas dependencies that have a higher version"
                    + " than any allowed versions at the same compatibility level will cause an"
                    + " error.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false),
        @Param(
            name = "registry",
            doc =
                "Overrides the registry for this module; instead of finding this module from the"
                    + " default list of registries, the given registry should be used.",
            named = true,
            positional = false,
            defaultValue = "''"),
      })
  public void multipleVersionOverride(String moduleName, Iterable<?> versions, String registry)
      throws EvalException {
    hadNonModuleCall = true;
    ImmutableList.Builder<Version> parsedVersionsBuilder = new ImmutableList.Builder<>();
    try {
      for (String version : Sequence.cast(versions, String.class, "versions").getImmutableList()) {
        parsedVersionsBuilder.add(Version.parse(version));
      }
    } catch (ParseException e) {
      throw new EvalException("Invalid version in multiple_version_override()", e);
    }
    ImmutableList<Version> parsedVersions = parsedVersionsBuilder.build();
    if (parsedVersions.size() < 2) {
      throw new EvalException("multiple_version_override() must specify at least 2 versions");
    }
    addOverride(moduleName, MultipleVersionOverride.create(parsedVersions, registry));
  }

  @StarlarkMethod(
      name = "archive_override",
      doc =
          "Specifies that this dependency should come from an archive file (zip, gzip, etc) at a"
              + " certain location, instead of from a registry. This"
              + " directive only takes effect in the root module; in other words, if a module"
              + " is used as a dependency by others, its own overrides are ignored.",
      parameters = {
        @Param(
            name = "module_name",
            doc = "The name of the Bazel module dependency to apply this override to.",
            named = true,
            positional = false),
        @Param(
            name = "urls",
            allowedTypes = {
              @ParamType(type = String.class),
              @ParamType(type = Iterable.class, generic1 = String.class),
            },
            doc = "The URLs of the archive; can be http(s):// or file:// URLs.",
            named = true,
            positional = false),
        @Param(
            name = "integrity",
            doc = "The expected checksum of the archive file, in Subresource Integrity format.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "strip_prefix",
            doc = "A directory prefix to strip from the extracted files.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "patches",
            doc =
                "A list of labels pointing to patch files to apply for this module. The patch files"
                    + " must exist in the source tree of the top level project. They are applied in"
                    + " the list order.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_cmds",
            doc =
                "Sequence of Bash commands to be applied on Linux/Macos after patches are applied.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_strip",
            doc = "Same as the --strip argument of Unix patch.",
            named = true,
            positional = false,
            defaultValue = "0"),
      })
  public void archiveOverride(
      String moduleName,
      Object urls,
      String integrity,
      String stripPrefix,
      Iterable<?> patches,
      Iterable<?> patchCmds,
      StarlarkInt patchStrip)
      throws EvalException {
    hadNonModuleCall = true;
    ImmutableList<String> urlList =
        urls instanceof String
            ? ImmutableList.of((String) urls)
            : Sequence.cast(urls, String.class, "urls").getImmutableList();
    addOverride(
        moduleName,
        ArchiveOverride.create(
            urlList,
            Sequence.cast(patches, String.class, "patches").stream()
                .map(this::parseOverrideLabelAttribute)
                .collect(toImmutableList()),
            Sequence.cast(patchCmds, String.class, "patchCmds").getImmutableList(),
            integrity,
            stripPrefix,
            patchStrip.toInt("archive_override.patch_strip")));
  }

  @StarlarkMethod(
      name = "git_override",
      doc =
          "Specifies that a dependency should come from a certain commit of a Git repository. This"
              + " directive only takes effect in the root module; in other words, if a module"
              + " is used as a dependency by others, its own overrides are ignored.",
      parameters = {
        @Param(
            name = "module_name",
            doc = "The name of the Bazel module dependency to apply this override to.",
            named = true,
            positional = false),
        @Param(
            name = "remote",
            doc = "The URL of the remote Git repository.",
            named = true,
            positional = false),
        @Param(
            name = "commit",
            doc = "The commit that should be checked out.",
            named = true,
            positional = false,
            defaultValue = "''"),
        @Param(
            name = "patches",
            doc =
                "A list of labels pointing to patch files to apply for this module. The patch files"
                    + " must exist in the source tree of the top level project. They are applied in"
                    + " the list order.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_cmds",
            doc =
                "Sequence of Bash commands to be applied on Linux/Macos after patches are applied.",
            allowedTypes = {@ParamType(type = Iterable.class, generic1 = String.class)},
            named = true,
            positional = false,
            defaultValue = "[]"),
        @Param(
            name = "patch_strip",
            doc = "Same as the --strip argument of Unix patch.",
            named = true,
            positional = false,
            defaultValue = "0"),
        @Param(
            name = "init_submodules",
            doc = "Whether submodules in the fetched repo should be recursively initialized.",
            named = true,
            positional = false,
            defaultValue = "False"),
      })
  public void gitOverride(
      String moduleName,
      String remote,
      String commit,
      Iterable<?> patches,
      Iterable<?> patchCmds,
      StarlarkInt patchStrip,
      boolean initSubmodules)
      throws EvalException {
    hadNonModuleCall = true;
    addOverride(
        moduleName,
        GitOverride.create(
            remote,
            commit,
            Sequence.cast(patches, String.class, "patches").stream()
                .map(this::parseOverrideLabelAttribute)
                .collect(toImmutableList()),
            Sequence.cast(patchCmds, String.class, "patchCmds").getImmutableList(),
            patchStrip.toInt("git_override.patch_strip"),
            initSubmodules));
  }

  @StarlarkMethod(
      name = "local_path_override",
      doc =
          "Specifies that a dependency should come from a certain directory on local disk. This"
              + " directive only takes effect in the root module; in other words, if a module"
              + " is used as a dependency by others, its own overrides are ignored.",
      parameters = {
        @Param(
            name = "module_name",
            doc = "The name of the Bazel module dependency to apply this override to.",
            named = true,
            positional = false),
        @Param(
            name = "path",
            doc = "The path to the directory where this module is.",
            named = true,
            positional = false),
      })
  public void localPathOverride(String moduleName, String path) throws EvalException {
    hadNonModuleCall = true;
    addOverride(moduleName, LocalPathOverride.create(path));
  }

  public InterimModule buildModule() throws EvalException {
    // Add builtin modules as default deps of the current module.
    for (String builtinModule : builtinModules.keySet()) {
      if (module.getKey().getName().equals(builtinModule)) {
        // The built-in module does not depend on itself.
        continue;
      }
      deps.put(builtinModule, DepSpec.create(builtinModule, Version.EMPTY, -1));
      try {
        addRepoNameUsage(builtinModule, "as a built-in dependency", Location.BUILTIN);
      } catch (EvalException e) {
        throw new EvalException(
            e.getMessage()
                + String.format(
                    ", '%s' is a built-in dependency and cannot be used by any 'bazel_dep' or"
                        + " 'use_repo' directive",
                    builtinModule),
            e);
      }
    }
    // Build module extension usages and the rest of the module.
    var extensionUsages = ImmutableList.<ModuleExtensionUsage>builder();
    for (var extensionUsageBuilder : extensionUsageBuilders) {
      extensionUsages.add(extensionUsageBuilder.buildUsage());
    }
    return module
        .setDeps(ImmutableMap.copyOf(deps))
        .setOriginalDeps(ImmutableMap.copyOf(deps))
        .setExtensionUsages(extensionUsages.build())
        .build();
  }

  public ImmutableMap<String, ModuleOverride> buildOverrides() {
    // Add overrides for builtin modules if there is no existing override for them.
    if (ModuleKey.ROOT.equals(module.getKey())) {
      for (String moduleName : builtinModules.keySet()) {
        overrides.putIfAbsent(moduleName, builtinModules.get(moduleName));
      }
    }
    return ImmutableMap.copyOf(overrides);
  }
}
