// 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.syntax;

import static java.util.stream.Collectors.joining;

import com.google.common.base.Ascii;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.syntax.EvalUtils.ComparisonException;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeSet;
import javax.annotation.Nullable;

/** A helper class containing built in functions for the Skylark language. */
@SkylarkGlobalLibrary
public class MethodLibrary {

  @SkylarkCallable(
      name = "min",
      doc =
          "Returns the smallest one of all given arguments. "
              + "If only one argument is provided, it must be a non-empty iterable. "
              + "It is an error if elements are not comparable (for example int with string). "
              + "<pre class=\"language-python\">min(2, 5, 4) == 2\n"
              + "min([5, 6, 3]) == 3</pre>",
      extraPositionals =
          @Param(name = "args", type = SkylarkList.class, doc = "The elements to be checked."),
      useLocation = true,
      useEnvironment = true)
  public Object min(SkylarkList<?> args, Location loc, Environment env) throws EvalException {
    try {
      return findExtreme(args, EvalUtils.SKYLARK_COMPARATOR.reverse(), loc, env);
    } catch (ComparisonException e) {
      throw new EvalException(loc, e);
    }
  }

  @SkylarkCallable(
      name = "max",
      doc =
          "Returns the largest one of all given arguments. "
              + "If only one argument is provided, it must be a non-empty iterable."
              + "It is an error if elements are not comparable (for example int with string). "
              + "<pre class=\"language-python\">max(2, 5, 4) == 5\n"
              + "max([5, 6, 3]) == 6</pre>",
      extraPositionals =
          @Param(name = "args", type = SkylarkList.class, doc = "The elements to be checked."),
      useLocation = true,
      useEnvironment = true)
  public Object max(SkylarkList<?> args, Location loc, Environment env) throws EvalException {
    try {
      return findExtreme(args, EvalUtils.SKYLARK_COMPARATOR, loc, env);
    } catch (ComparisonException e) {
      throw new EvalException(loc, e);
    }
  }

  /** Returns the maximum element from this list, as determined by maxOrdering. */
  private static Object findExtreme(
      SkylarkList<?> args, Ordering<Object> maxOrdering, Location loc, Environment env)
      throws EvalException {
    // Args can either be a list of items to compare, or a singleton list whose element is an
    // iterable of items to compare. In either case, there must be at least one item to compare.
    try {
      Iterable<?> items = (args.size() == 1) ? EvalUtils.toIterable(args.get(0), loc, env) : args;
      return maxOrdering.max(items);
    } catch (NoSuchElementException ex) {
      throw new EvalException(loc, "expected at least one item", ex);
    }
  }

  @SkylarkCallable(
      name = "all",
      doc =
          "Returns true if all elements evaluate to True or if the collection is empty. "
              + "Elements are converted to boolean using the <a href=\"#bool\">bool</a> function."
              + "<pre class=\"language-python\">all([\"hello\", 3, True]) == True\n"
              + "all([-1, 0, 1]) == False</pre>",
      parameters = {
        @Param(
            name = "elements",
            type = Object.class,
            noneable = true,
            doc = "A string or a collection of elements.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public Boolean all(Object collection, Location loc, Environment env) throws EvalException {
    return !hasElementWithBooleanValue(collection, false, loc, env);
  }

  @SkylarkCallable(
      name = "any",
      doc =
          "Returns true if at least one element evaluates to True. "
              + "Elements are converted to boolean using the <a href=\"#bool\">bool</a> function."
              + "<pre class=\"language-python\">any([-1, 0, 1]) == True\n"
              + "any([False, 0, \"\"]) == False</pre>",
      parameters = {
        @Param(
            name = "elements",
            type = Object.class,
            noneable = true,
            doc = "A string or a collection of elements.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public Boolean any(Object collection, Location loc, Environment env) throws EvalException {
    return hasElementWithBooleanValue(collection, true, loc, env);
  }

  private static boolean hasElementWithBooleanValue(
      Object collection, boolean value, Location loc, Environment env) throws EvalException {
    Iterable<?> iterable = EvalUtils.toIterable(collection, loc, env);
    for (Object obj : iterable) {
      if (EvalUtils.toBoolean(obj) == value) {
        return true;
      }
    }
    return false;
  }

  @SkylarkCallable(
      name = "sorted",
      doc =
          "Sort a collection. Elements should all belong to the same orderable type, they are "
              + "sorted by their value (in ascending order). "
              + "It is an error if elements are not comparable (for example int with string)."
              + "<pre class=\"language-python\">sorted([3, 5, 4]) == [3, 4, 5]</pre>",
      parameters = {
        @Param(
            name = "self",
            type = Object.class,
            doc = "This collection.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
        @Param(
            name = "key",
            doc = "An optional function applied to each element before comparison.",
            named = true,
            defaultValue = "None",
            positional = false,
            noneable = true),
        @Param(
            name = "reverse",
            type = Boolean.class,
            doc = "Return results in descending order.",
            named = true,
            defaultValue = "False",
            positional = false,
            noneable = true)
      },
      useLocation = true,
      useEnvironment = true)
  public MutableList<?> sorted(
      Object self, final Object key, Boolean reverse, final Location loc, final Environment env)
      throws EvalException, InterruptedException {

    ArrayList list = new ArrayList(EvalUtils.toCollection(self, loc, env));
    if (key == Runtime.NONE) {
      try {
        Collections.sort(list, EvalUtils.SKYLARK_COMPARATOR);
      } catch (EvalUtils.ComparisonException e) {
        throw new EvalException(loc, e);
      }
    } else if (key instanceof StarlarkFunction) {
      final StarlarkFunction keyfn = (StarlarkFunction) key;
      final FuncallExpression ast = new FuncallExpression(Identifier.of(""), ImmutableList.of());

      class KeyComparator implements Comparator<Object> {
        Exception e;

        @Override
        public int compare(Object x, Object y) {
          try {
            return EvalUtils.SKYLARK_COMPARATOR.compare(callKeyFunc(x), callKeyFunc(y));
          } catch (InterruptedException | EvalException e) {
            if (this.e == null) {
              this.e = e;
            }
            return 0;
          }
        }

        Object callKeyFunc(Object x) throws EvalException, InterruptedException {
          return keyfn.call(Collections.singletonList(x), ImmutableMap.of(), ast, env);
        }
      }

      KeyComparator comp = new KeyComparator();
      try {
        Collections.sort(list, comp);
      } catch (EvalUtils.ComparisonException e) {
        throw new EvalException(loc, e);
      }

      if (comp.e != null) {
        if (comp.e instanceof InterruptedException) {
          throw (InterruptedException) comp.e;
        }
        throw (EvalException) comp.e;
      }
    } else {
      throw new EvalException(
          loc, Printer.format("%r object is not callable", EvalUtils.getDataTypeName(key)));
    }

    if (reverse) {
      Collections.reverse(list);
    }
    return MutableList.wrapUnsafe(env, list);
  }

  @SkylarkCallable(
      name = "reversed",
      doc =
          "Returns a list that contains the elements of the original sequence in reversed order."
              + "<pre class=\"language-python\">reversed([3, 5, 4]) == [4, 5, 3]</pre>",
      parameters = {
        @Param(
            name = "sequence",
            type = Object.class,
            doc = "The sequence to be reversed (string, list or tuple).",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
      },
      useLocation = true,
      useEnvironment = true)
  public MutableList<?> reversed(Object sequence, Location loc, Environment env)
      throws EvalException {
    // We only allow lists and strings.
    if (sequence instanceof SkylarkDict) {
      throw new EvalException(loc, "Argument to reversed() must be a sequence, not a dictionary.");
    } else if (sequence instanceof NestedSet || sequence instanceof SkylarkNestedSet) {
      throw new EvalException(loc, "Argument to reversed() must be a sequence, not a depset.");
    }
    ArrayDeque<Object> tmpList = new ArrayDeque<>();
    for (Object element : EvalUtils.toIterable(sequence, loc, env)) {
      tmpList.addFirst(element);
    }
    return MutableList.copyOf(env, tmpList);
  }

  @SkylarkCallable(
      name = "tuple",
      doc =
          "Converts a collection (e.g. list, tuple or dictionary) to a tuple."
              + "<pre class=\"language-python\">tuple([1, 2]) == (1, 2)\n"
              + "tuple((2, 3, 2)) == (2, 3, 2)\n"
              + "tuple({5: \"a\", 2: \"b\", 4: \"c\"}) == (5, 2, 4)</pre>",
      parameters = {
        @Param(
            name = "x",
            defaultValue = "()",
            doc = "The object to convert.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public Tuple<?> tuple(Object x, Location loc, Environment env) throws EvalException {
    return Tuple.copyOf(EvalUtils.toCollection(x, loc, env));
  }

  @SkylarkCallable(
      name = "list",
      doc =
          "Converts a collection (e.g. list, tuple or dictionary) to a list."
              + "<pre class=\"language-python\">list([1, 2]) == [1, 2]\n"
              + "list((2, 3, 2)) == [2, 3, 2]\n"
              + "list({5: \"a\", 2: \"b\", 4: \"c\"}) == [5, 2, 4]</pre>",
      parameters = {
        @Param(
            name = "x",
            defaultValue = "[]",
            doc = "The object to convert.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public MutableList<?> list(Object x, Location loc, Environment env) throws EvalException {
    return MutableList.copyOf(env, EvalUtils.toCollection(x, loc, env));
  }

  @SkylarkCallable(
      name = "len",
      doc = "Returns the length of a string, list, tuple, depset, or dictionary.",
      parameters = {
        @Param(
            name = "x",
            doc = "The object to check length of.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public Integer len(Object x, Location loc, Environment env) throws EvalException {
    if (x instanceof String) {
      return ((String) x).length();
    } else if (x instanceof Map) {
      return ((Map<?, ?>) x).size();
    } else if (x instanceof SkylarkList) {
      return ((SkylarkList<?>) x).size();
    } else if (x instanceof SkylarkNestedSet) {
      if (env.getSemantics().incompatibleDepsetIsNotIterable()) {
        throw new EvalException(
            loc,
            EvalUtils.getDataTypeName(x)
                + " is not iterable. You may use `len(<depset>.to_list())` instead. Use "
                + "--incompatible_depset_is_not_iterable=false to temporarily disable this "
                + "check.");
      }
      return ((SkylarkNestedSet) x).toCollection().size();
    } else if (x instanceof Iterable) {
      // Iterables.size() checks if x is a Collection so it's efficient in that sense.
      return Iterables.size((Iterable<?>) x);
    } else {
      throw new EvalException(loc, EvalUtils.getDataTypeName(x) + " is not iterable");
    }
  }

  @SkylarkCallable(
      name = "str",
      doc =
          "Converts any object to string. This is useful for debugging."
              + "<pre class=\"language-python\">str(\"ab\") == \"ab\"\n"
              + "str(8) == \"8\"</pre>",
      parameters = {
        @Param(
            name = "x",
            doc = "The object to convert.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      })
  public String str(Object x) {
    return Printer.str(x);
  }

  @SkylarkCallable(
      name = "repr",
      doc =
          "Converts any object to a string representation. This is useful for debugging.<br>"
              + "<pre class=\"language-python\">repr(\"ab\") == '\"ab\"'</pre>",
      parameters = {
        @Param(
            name = "x",
            doc = "The object to convert.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      })
  public String repr(Object x) {
    return Printer.repr(x);
  }

  @SkylarkCallable(
      name = "bool",
      doc =
          "Constructor for the bool type. "
              + "It returns <code>False</code> if the object is <code>None</code>, <code>False"
              + "</code>, an empty string (<code>\"\"</code>), the number <code>0</code>, or an "
              + "empty collection (e.g. <code>()</code>, <code>[]</code>). "
              + "Otherwise, it returns <code>True</code>.",
      parameters = {
        @Param(
            name = "x",
            defaultValue = "False",
            doc = "The variable to convert.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      })
  public Boolean bool(Object x) throws EvalException {
    return EvalUtils.toBoolean(x);
  }

  private final ImmutableMap<String, Integer> intPrefixes =
      ImmutableMap.of("0b", 2, "0o", 8, "0x", 16);

  @SkylarkCallable(
      name = "int",
      doc =
          "Returns x as an int value."
              + "<ul>"
              + "<li>If <code>x</code> is already an int, it is returned as-is."
              + "<li>If <code>x</code> is a boolean, a true value returns 1 and a false value "
              + "    returns 0."
              + "<li>If <code>x</code> is a string, it must have the format "
              + "    <code>&lt;sign&gt;&lt;prefix&gt;&lt;digits&gt;</code>. "
              + "    <code>&lt;sign&gt;</code> is either <code>\"+\"</code>, <code>\"-\"</code>, "
              + "    or empty (interpreted as positive). <code>&lt;digits&gt;</code> are a "
              + "    sequence of digits from 0 up to <code>base</code> - 1, where the letters a-z "
              + "    (or equivalently, A-Z) are used as digits for 10-35. In the case where "
              + "    <code>base</code> is 2/8/16, <code>&lt;prefix&gt;</code> is optional and may "
              + "    be 0b/0o/0x (or equivalently, 0B/0O/0X) respectively; if the "
              + "    <code>base</code> is any other value besides these bases or the special value "
              + "    0, the prefix must be empty. In the case where <code>base</code> is 0, the "
              + "    string is interpreted as an integer literal, in the sense that one of the "
              + "    bases 2/8/10/16 is chosen depending on which prefix if any is used. If "
              + "    <code>base</code> is 0, no prefix is used, and there is more than one digit, "
              + "    the leading digit cannot be 0; this is to avoid confusion between octal and "
              + "    decimal. The magnitude of the number represented by the string must be within "
              + "    the allowed range for the int type."
              + "</ul>"
              + "This function fails if <code>x</code> is any other type, or if the value is a "
              + "string not satisfying the above format. Unlike Python's <code>int()</code> "
              + "function, this function does not allow zero arguments, and does not allow "
              + "extraneous whitespace for string arguments."
              + "<p>Examples:"
              + "<pre class=\"language-python\">"
              + "int(\"123\") == 123\n"
              + "int(\"-123\") == -123\n"
              + "int(\"+123\") == 123\n"
              + "int(\"FF\", 16) == 255\n"
              + "int(\"0xFF\", 16) == 255\n"
              + "int(\"10\", 0) == 10\n"
              + "int(\"-0x10\", 0) == -16"
              + "</pre>",
      parameters = {
        @Param(
            name = "x",
            type = Object.class,
            doc = "The string to convert.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
        @Param(
            name = "base",
            type = Object.class,
            defaultValue = "unbound",
            doc =
                "The base used to interpret a string value; defaults to 10. Must be between 2 "
                    + "and 36 (inclusive), or 0 to detect the base as if <code>x</code> were an "
                    + "integer literal. This parameter must not be supplied if the value is not a "
                    + "string.",
            named = true)
      },
      useLocation = true)
  public Integer convertToInt(Object x, Object base, Location loc) throws EvalException {
    if (x instanceof String) {
      if (base == Runtime.UNBOUND) {
        base = 10;
      } else if (!(base instanceof Integer)) {
        throw new EvalException(
            loc, "base must be an integer (got '" + EvalUtils.getDataTypeName(base) + "')");
      }
      return fromString((String) x, loc, (Integer) base);
    } else {
      if (base != Runtime.UNBOUND) {
        throw new EvalException(loc, "int() can't convert non-string with explicit base");
      }
      if (x instanceof Boolean) {
        return ((Boolean) x).booleanValue() ? 1 : 0;
      } else if (x instanceof Integer) {
        return (Integer) x;
      }
      throw new EvalException(loc, Printer.format("%r is not of type string or int or bool", x));
    }
  }

  private int fromString(String string, Location loc, int base) throws EvalException {
    String stringForErrors = string;

    boolean isNegative = false;
    if (string.isEmpty()) {
      throw new EvalException(loc, Printer.format("string argument to int() cannot be empty"));
    }
    char c = string.charAt(0);
    if (c == '+') {
      string = string.substring(1);
    } else if (c == '-') {
      string = string.substring(1);
      isNegative = true;
    }

    String prefix = getIntegerPrefix(string);
    String digits;
    if (prefix == null) {
      // Nothing to strip. Infer base 10 if autodetection was requested (base == 0).
      digits = string;
      if (base == 0) {
        if (string.length() > 1 && string.startsWith("0")) {
          // We don't infer the base when input starts with '0' (due
          // to confusion between octal and decimal).
          throw new EvalException(
              loc,
              Printer.format(
                  "cannot infer base for int() when value begins with a 0: %r", stringForErrors));
        }
        base = 10;
      }
    } else {
      // Strip prefix. Infer base from prefix if unknown (base == 0), or else verify its
      // consistency.
      digits = string.substring(prefix.length());
      int expectedBase = intPrefixes.get(prefix);
      if (base == 0) {
        base = expectedBase;
      } else if (base != expectedBase) {
        throw new EvalException(
            loc,
            Printer.format("invalid literal for int() with base %d: %r", base, stringForErrors));
      }
    }

    if (base < 2 || base > 36) {
      throw new EvalException(loc, "int() base must be >= 2 and <= 36");
    }
    try {
      // Negate by prepending a negative symbol, rather than by using arithmetic on the
      // result, to handle the edge case of -2^31 correctly.
      String parseable = isNegative ? "-" + digits : digits;
      return Integer.parseInt(parseable, base);
    } catch (NumberFormatException | ArithmeticException e) {
      throw new EvalException(
          loc,
          Printer.format("invalid literal for int() with base %d: %r", base, stringForErrors),
          e);
    }
  }

  @Nullable
  private String getIntegerPrefix(String value) {
    value = Ascii.toLowerCase(value);
    for (String prefix : intPrefixes.keySet()) {
      if (value.startsWith(prefix)) {
        return prefix;
      }
    }
    return null;
  }

  @SkylarkCallable(
      name = "dict",
      doc =
          "Creates a <a href=\"dict.html\">dictionary</a> from an optional positional "
              + "argument and an optional set of keyword arguments. In the case where the same key "
              + "is given multiple times, the last value will be used. Entries supplied via "
              + "keyword arguments are considered to come after entries supplied via the "
              + "positional argument.",
      parameters = {
        @Param(
            name = "args",
            type = Object.class,
            defaultValue = "[]",
            doc =
                "Either a dictionary or a list of entries. Entries must be tuples or lists with "
                    + "exactly two elements: key, value.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
      },
      extraKeywords = @Param(name = "kwargs", doc = "Dictionary of additional entries."),
      useLocation = true,
      useEnvironment = true)
  public SkylarkDict<?, ?> dict(
      Object args, SkylarkDict<?, ?> kwargs, Location loc, Environment env) throws EvalException {
    SkylarkDict<?, ?> argsDict =
        (args instanceof SkylarkDict)
            ? (SkylarkDict<?, ?>) args
            : SkylarkDict.getDictFromArgs(args, loc, env);
    return SkylarkDict.plus(argsDict, kwargs, env);
  }

  @SkylarkCallable(
      name = "enumerate",
      doc =
          "Returns a list of pairs (two-element tuples), with the index (int) and the item from"
              + " the input list.\n<pre class=\"language-python\">"
              + "enumerate([24, 21, 84]) == [(0, 24), (1, 21), (2, 84)]</pre>\n",
      parameters = {
        // Note Python uses 'sequence' keyword instead of 'list'. We may want to change tihs
        // some day.
        @Param(name = "list", type = SkylarkList.class, doc = "input list.", named = true),
        @Param(
            name = "start",
            type = Integer.class,
            doc = "start index.",
            defaultValue = "0",
            named = true)
      },
      useEnvironment = true)
  public MutableList<?> enumerate(SkylarkList<?> input, Integer start, Environment env)
      throws EvalException {
    int count = start;
    ArrayList<SkylarkList<?>> result = new ArrayList<>(input.size());
    for (Object obj : input) {
      result.add(Tuple.of(count, obj));
      count++;
    }
    return MutableList.wrapUnsafe(env, result);
  }

  @SkylarkCallable(
      name = "hash",
      doc =
          "Return a hash value for a string. This is computed deterministically using the same "
              + "algorithm as Java's <code>String.hashCode()</code>, namely: "
              + "<pre class=\"language-python\">s[0] * (31^(n-1)) + s[1] * (31^(n-2)) + ... + "
              + "s[n-1]</pre> Hashing of values besides strings is not currently supported.",
      // Deterministic hashing is important for the consistency of builds, hence why we
      // promise a specific algorithm. This is in contrast to Java (Object.hashCode()) and
      // Python, which promise stable hashing only within a given execution of the program.
      parameters = {
        @Param(
            name = "value",
            type = String.class,
            doc = "String value to hash.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      })
  public Integer hash(String value) throws EvalException {
    return value.hashCode();
  }

  @SkylarkCallable(
      name = "range",
      doc =
          "Creates a list where items go from <code>start</code> to <code>stop</code>, using a "
              + "<code>step</code> increment. If a single argument is provided, items will "
              + "range from 0 to that element."
              + "<pre class=\"language-python\">range(4) == [0, 1, 2, 3]\n"
              + "range(3, 9, 2) == [3, 5, 7]\n"
              + "range(3, 0, -1) == [3, 2, 1]</pre>",
      parameters = {
        @Param(
            name = "start_or_stop",
            type = Integer.class,
            doc =
                "Value of the start element if stop is provided, "
                    + "otherwise value of stop and the actual start is 0",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
        @Param(
            name = "stop_or_none",
            type = Integer.class,
            noneable = true,
            defaultValue = "None",
            doc =
                "optional index of the first item <i>not</i> to be included in the resulting "
                    + "list; generation of the list stops before <code>stop</code> is reached.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
        @Param(
            name = "step",
            type = Integer.class,
            defaultValue = "1",
            doc = "The increment (default is 1). It may be negative.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useLocation = true,
      useEnvironment = true)
  public SkylarkList<Integer> range(
      Integer startOrStop, Object stopOrNone, Integer step, Location loc, Environment env)
      throws EvalException {
    int start;
    int stop;
    if (stopOrNone == Runtime.NONE) {
      start = 0;
      stop = startOrStop;
    } else {
      start = startOrStop;
      stop = Type.INTEGER.convert(stopOrNone, "'stop' operand of 'range'");
    }
    if (step == 0) {
      throw new EvalException(loc, "step cannot be 0");
    }
    return RangeList.of(start, stop, step);
  }

  /** Returns true if the object has a field of the given name, otherwise false. */
  @SkylarkCallable(
      name = "hasattr",
      doc =
          "Returns True if the object <code>x</code> has an attribute or method of the given "
              + "<code>name</code>, otherwise False. Example:<br>"
              + "<pre class=\"language-python\">hasattr(ctx.attr, \"myattr\")</pre>",
      parameters = {
        @Param(
            name = "x",
            doc = "The object to check.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true),
        @Param(
            name = "name",
            type = String.class,
            doc = "The name of the attribute.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true)
      },
      useEnvironment = true)
  public Boolean hasAttr(Object obj, String name, Environment env) throws EvalException {
    if (obj instanceof ClassObject && ((ClassObject) obj).getValue(name) != null) {
      return true;
    }
    // shouldn't this filter things with struct_field = false?
    return DotExpression.hasMethod(env.getSemantics(), obj, name);
  }

  @SkylarkCallable(
      name = "getattr",
      doc =
          "Returns the struct's field of the given name if it exists. If not, it either returns "
              + "<code>default</code> (if specified) or raises an error. "
              + "<code>getattr(x, \"foobar\")</code> is equivalent to <code>x.foobar</code>."
              + "<pre class=\"language-python\">getattr(ctx.attr, \"myattr\")\n"
              + "getattr(ctx.attr, \"myattr\", \"mydefault\")</pre>",
      parameters = {
        @Param(
            name = "x",
            doc = "The struct whose attribute is accessed.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true),
        @Param(
            name = "name",
            doc = "The name of the struct attribute.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
        @Param(
            name = "default",
            defaultValue = "unbound",
            doc =
                "The default value to return in case the struct "
                    + "doesn't have an attribute of the given name.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      },
      useLocation = true,
      useEnvironment = true)
  public Object getAttr(Object obj, String name, Object defaultValue, Location loc, Environment env)
      throws EvalException, InterruptedException {
    Object result = DotExpression.eval(obj, name, loc, env);
    if (result == null) {
      if (defaultValue != Runtime.UNBOUND) {
        return defaultValue;
      }
      throw DotExpression.getMissingFieldException(obj, name, loc, env.getSemantics(), "attribute");
    }
    return result;
  }

  @SkylarkCallable(
      name = "dir",
      doc =
          "Returns a list of strings: the names of the attributes and "
              + "methods of the parameter object.",
      parameters = {
        @Param(
            name = "x",
            doc = "The object to check.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      },
      useLocation = true,
      useEnvironment = true)
  public MutableList<?> dir(Object object, Location loc, Environment env) throws EvalException {
    // Order the fields alphabetically.
    Set<String> fields = new TreeSet<>();
    if (object instanceof ClassObject) {
      fields.addAll(((ClassObject) object).getFieldNames());
    }
    fields.addAll(Runtime.getBuiltinRegistry().getFunctionNames(object.getClass()));
    fields.addAll(FuncallExpression.getMethodNames(env.getSemantics(), object.getClass()));
    return MutableList.copyOf(env, fields);
  }

  @SkylarkCallable(
      name = "fail",
      doc =
          "Raises an error that cannot be intercepted. It can be used anywhere, "
              + "both in the loading phase and in the analysis phase.",
      parameters = {
        @Param(
            name = "msg",
            type = Object.class,
            doc = "Error to display for the user. The object is converted to a string.",
            defaultValue = "None",
            named = true,
            noneable = true),
        @Param(
            name = "attr",
            type = String.class,
            noneable = true,
            defaultValue = "None",
            doc =
                "The name of the attribute that caused the error. This is used only for "
                    + "error reporting.",
            named = true)
      },
      useLocation = true)
  public Runtime.NoneType fail(Object msg, Object attr, Location loc) throws EvalException {
    String str = Printer.str(msg);
    if (attr != Runtime.NONE) {
      str = String.format("attribute %s: %s", attr, str);
    }
    throw new EvalException(loc, str);
  }

  @SkylarkCallable(
      name = "print",
      doc =
          "Prints <code>args</code> as debug output. It will be prefixed with the string <code>"
              + "\"DEBUG\"</code> and the location (file and line number) of this call. The "
              + "exact way in which the arguments are converted to strings is unspecified and may "
              + "change at any time. In particular, it may be different from (and more detailed "
              + "than) the formatting done by <a href='#str'><code>str()</code></a> and <a "
              + "href='#repr'><code>repr()</code></a>."
              + "<p>Using <code>print</code> in production code is discouraged due to the spam it "
              + "creates for users. For deprecations, prefer a hard error using <a href=\"#fail\">"
              + "<code>fail()</code></a> whenever possible.",
      parameters = {
        @Param(
            name = "sep",
            type = String.class,
            defaultValue = "\" \"",
            named = true,
            positional = false,
            doc = "The separator string between the objects, default is space (\" \").")
      },
      // NB: as compared to Python3, we're missing optional named-only arguments 'end' and 'file'
      extraPositionals = @Param(name = "args", doc = "The objects to print."),
      useLocation = true,
      useEnvironment = true)
  public Runtime.NoneType print(String sep, SkylarkList<?> starargs, Location loc, Environment env)
      throws EvalException {
    String msg = starargs.stream().map(Printer::debugPrint).collect(joining(sep));
    // As part of the integration test "skylark_flag_test.sh", if the
    // "--internal_skylark_flag_test_canary" flag is enabled, append an extra marker string to
    // the output.
    if (env.getSemantics().internalSkylarkFlagTestCanary()) {
      msg += "<== skylark flag test ==>";
    }
    env.handleEvent(Event.debug(loc, msg));
    return Runtime.NONE;
  }

  @SkylarkCallable(
      name = "type",
      doc =
          "Returns the type name of its argument. This is useful for debugging and "
              + "type-checking. Examples:"
              + "<pre class=\"language-python\">"
              + "type(2) == \"int\"\n"
              + "type([1]) == \"list\"\n"
              + "type(struct(a = 2)) == \"struct\""
              + "</pre>"
              + "This function might change in the future. To write Python-compatible code and "
              + "be future-proof, use it only to compare return values: "
              + "<pre class=\"language-python\">"
              + "if type(x) == type([]):  # if x is a list"
              + "</pre>",
      parameters = {
        @Param(
            name = "x",
            doc = "The object to check type of.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true,
            noneable = true)
      })
  public String type(Object object) {
    // There is no 'type' type in Skylark, so we return a string with the type name.
    return EvalUtils.getDataTypeName(object, false);
  }

  @SkylarkCallable(
      name = "depset",
      doc =
          "Creates a <a href=\"depset.html\">depset</a>. The <code>direct</code> parameter is a "
              + "list of direct elements of the depset, and <code>transitive</code> parameter is "
              + "a list of depsets whose elements become indirect elements of the created depset. "
              + "The order in which elements are returned when the depset is converted to a list "
              + "is specified by the <code>order</code> parameter. "
              + "See the <a href=\"../depsets.md\">Depsets overview</a> for more information. "
              + "<p> All elements (direct and indirect) of a depset must be of the same type. "
              + "<p> The order of the created depset should be <i>compatible</i> with the order of "
              + "its <code>transitive</code> depsets. <code>\"default\"</code> order is compatible "
              + "with any other order, all other orders are only compatible with themselves."
              + "<p> Note on backward/forward compatibility. This function currently accepts a "
              + "positional <code>items</code> parameter. It is deprecated and will be removed "
              + "in the future, and after its removal <code>direct</code> will become a sole "
              + "positional parameter of the <code>depset</code> function. Thus, both of the "
              + "following calls are equivalent and future-proof:<br>"
              + "<pre class=language-python>"
              + "depset(['a', 'b'], transitive = [...])\n"
              + "depset(direct = ['a', 'b'], transitive = [...])\n"
              + "</pre>",
      parameters = {
        @Param(
            name = "items",
            type = Object.class,
            defaultValue = "[]",
            doc =
                "Deprecated: Either an iterable whose items become the direct elements of "
                    + "the new depset, in left-to-right order, or else a depset that becomes "
                    + "a transitive element of the new depset. In the latter case, "
                    + "<code>transitive</code> cannot be specified.",
            named = true),
        @Param(
            name = "order",
            type = String.class,
            defaultValue = "\"default\"",
            doc =
                "The traversal strategy for the new depset. See "
                    + "<a href=\"depset.html\">here</a> for the possible values.",
            named = true),
        @Param(
            name = "direct",
            type = SkylarkList.class,
            defaultValue = "None",
            positional = false,
            named = true,
            noneable = true,
            doc = "A list of <i>direct</i> elements of a depset."),
        @Param(
            name = "transitive",
            named = true,
            positional = false,
            type = SkylarkList.class,
            generic1 = SkylarkNestedSet.class,
            noneable = true,
            doc = "A list of depsets whose elements will become indirect elements of the depset.",
            defaultValue = "None")
      },
      useLocation = true)
  public SkylarkNestedSet depset(
      Object items, String orderString, Object direct, Object transitive, Location loc)
      throws EvalException {
    Order order;
    try {
      order = Order.parse(orderString);
    } catch (IllegalArgumentException ex) {
      throw new EvalException(loc, ex);
    }

    if (transitive == Runtime.NONE && direct == Runtime.NONE) {
      // Legacy behavior.
      return SkylarkNestedSet.of(order, items, loc);
    }

    if (direct != Runtime.NONE && !isEmptySkylarkList(items)) {
      throw new EvalException(
          loc, "Do not pass both 'direct' and 'items' argument to depset constructor.");
    }

    // Non-legacy behavior: either 'transitive' or 'direct' were specified.
    Iterable<Object> directElements;
    if (direct != Runtime.NONE) {
      directElements = ((SkylarkList<?>) direct).getContents(Object.class, "direct");
    } else {
      SkylarkType.checkType(items, SkylarkList.class, "items");
      directElements = ((SkylarkList<?>) items).getContents(Object.class, "items");
    }

    Iterable<SkylarkNestedSet> transitiveList;
    if (transitive != Runtime.NONE) {
      SkylarkType.checkType(transitive, SkylarkList.class, "transitive");
      transitiveList =
          ((SkylarkList<?>) transitive).getContents(SkylarkNestedSet.class, "transitive");
    } else {
      transitiveList = ImmutableList.of();
    }
    SkylarkNestedSet.Builder builder = SkylarkNestedSet.builder(order, loc);
    for (Object directElement : directElements) {
      builder.addDirect(directElement);
    }
    for (SkylarkNestedSet transitiveSet : transitiveList) {
      builder.addTransitive(transitiveSet);
    }
    return builder.build();
  }

  private static boolean isEmptySkylarkList(Object o) {
    return o instanceof SkylarkList && ((SkylarkList) o).isEmpty();
  }

  /**
   * Returns a function-value implementing "select" (i.e. configurable attributes) in the specified
   * package context.
   */
  @SkylarkCallable(
      name = "select",
      doc =
          "<code>select()</code> is the helper function that makes a rule attribute "
              + "<a href=\"$BE_ROOT/common-definitions.html#configurable-attributes\">"
              + "configurable</a>. See "
              + "<a href=\"$BE_ROOT/functions.html#select\">build encyclopedia</a> for details.",
      parameters = {
        @Param(
            name = "x",
            type = SkylarkDict.class,
            doc = "The parameter to convert.",
            // TODO(cparsons): This parameter should be positional-only.
            legacyNamed = true),
        @Param(
            name = "no_match_error",
            type = String.class,
            defaultValue = "''",
            doc = "Optional custom error to report if no condition matches.",
            named = true)
      },
      useLocation = true)
  public Object select(SkylarkDict<?, ?> dict, String noMatchError, Location loc)
      throws EvalException {
    if (dict.isEmpty()) {
      throw new EvalException(
          loc,
          "select({}) with an empty dictionary can never resolve because it includes no conditions "
              + "to match");
    }
    for (Object key : dict.keySet()) {
      if (!(key instanceof String)) {
        throw new EvalException(
            loc, String.format("Invalid key: %s. select keys must be label references", key));
      }
    }
    return SelectorList.of(new SelectorValue(dict, noMatchError));
  }

  @SkylarkCallable(
      name = "zip",
      doc =
          "Returns a <code>list</code> of <code>tuple</code>s, where the i-th tuple contains "
              + "the i-th element from each of the argument sequences or iterables. The list has "
              + "the size of the shortest input. With a single iterable argument, it returns a "
              + "list of 1-tuples. With no arguments, it returns an empty list. Examples:"
              + "<pre class=\"language-python\">"
              + "zip()  # == []\n"
              + "zip([1, 2])  # == [(1,), (2,)]\n"
              + "zip([1, 2], [3, 4])  # == [(1, 3), (2, 4)]\n"
              + "zip([1, 2], [3, 4, 5])  # == [(1, 3), (2, 4)]</pre>",
      extraPositionals = @Param(name = "args", doc = "lists to zip."),
      useLocation = true,
      useEnvironment = true)
  public MutableList<?> zip(SkylarkList<?> args, Location loc, Environment env)
      throws EvalException {
    Iterator<?>[] iterators = new Iterator<?>[args.size()];
    for (int i = 0; i < args.size(); i++) {
      iterators[i] = EvalUtils.toIterable(args.get(i), loc, env).iterator();
    }
    ArrayList<Tuple<?>> result = new ArrayList<>();
    boolean allHasNext;
    do {
      allHasNext = !args.isEmpty();
      List<Object> elem = Lists.newArrayListWithExpectedSize(args.size());
      for (Iterator<?> iterator : iterators) {
        if (iterator.hasNext()) {
          elem.add(iterator.next());
        } else {
          allHasNext = false;
        }
      }
      if (allHasNext) {
        result.add(Tuple.copyOf(elem));
      }
    } while (allHasNext);
    return MutableList.wrapUnsafe(env, result);
  }

  /** Skylark int type. */
  @SkylarkModule(
      name = "int",
      category = SkylarkModuleCategory.BUILTIN,
      doc =
          "A type to represent integers. It can represent any number between -2147483648 and "
              + "2147483647 (included). "
              + "Examples of int values:<br>"
              + "<pre class=\"language-python\">"
              + "153\n"
              + "0x2A  # hexadecimal literal\n"
              + "0o54  # octal literal\n"
              + "23 * 2 + 5\n"
              + "100 / -7\n"
              + "100 % -7  # -5 (unlike in some other languages)\n"
              + "int(\"18\")\n"
              + "</pre>")
  public static final class IntModule {}

  /** Skylark bool type. */
  @SkylarkModule(
      name = "bool",
      category = SkylarkModuleCategory.BUILTIN,
      doc =
          "A type to represent booleans. There are only two possible values: "
              + "<a href=\"globals.html#True\">True</a> and "
              + "<a href=\"globals.html#False\">False</a>. "
              + "Any value can be converted to a boolean using the "
              + "<a href=\"globals.html#bool\">bool</a> function.")
  public static final class BoolModule {}

  /** Adds bindings for all the builtin functions of this class to the given map builder. */
  public static void addBindingsToBuilder(ImmutableMap.Builder<String, Object> builder) {
    Runtime.setupSkylarkLibrary(builder, new MethodLibrary());
  }
}
