// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.lib.analysis.skylark;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
import com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTemplate;
import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
import com.google.devtools.build.lib.packages.Attribute.SplitTransitionProvider;
import com.google.devtools.build.lib.packages.AttributeValueSource;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.Provider;
import com.google.devtools.build.lib.packages.SkylarkAspect;
import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.ParamType;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.BuiltinFunction;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.EvalUtils;
import com.google.devtools.build.lib.syntax.FuncallExpression;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkCallbackFunction;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
import com.google.devtools.build.lib.syntax.SkylarkType;
import com.google.devtools.build.lib.syntax.SkylarkUtils;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.syntax.Type.ConversionException;
import com.google.devtools.build.lib.syntax.Type.LabelClass;
import com.google.devtools.build.lib.syntax.UserDefinedFunction;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * A helper class to provide Attr module in Skylark.
 *
 * <p>It exposes functions (e.g. 'attr.string', 'attr.label_list', etc.) to Skylark users. The
 * functions are executed through reflection. As everywhere in Skylark, arguments are type-checked
 * with the signature and cannot be null.
 */
@SkylarkModule(
  name = "attr",
  namespace = true,
  category = SkylarkModuleCategory.BUILTIN,
  doc =
      "Module for creating new attributes. "
          + "They are only for use with <a href=\"globals.html#rule\">rule</a> or "
          + "<a href=\"globals.html#aspect\">aspect</a>."
)
public final class SkylarkAttr implements SkylarkValue {

  // Arguments

  private static final String ALLOW_FILES_ARG = "allow_files";
  private static final String ALLOW_FILES_DOC =
      "whether File targets are allowed. Can be True, False (default), or a list of file "
      + "extensions that are allowed (e.g. <code>[\".cc\", \".cpp\"]</code>).";

  private static final String ALLOW_RULES_ARG = "allow_rules";
  private static final String ALLOW_RULES_DOC =
      "which rule targets (name of the classes) are allowed. This is deprecated (kept only for "
          + "compatibility), use providers instead.";

  private static final String ASPECTS_ARG = "aspects";
  private static final String ASPECTS_ARG_DOC =
      "aspects that should be applied to the dependency or dependencies specified by this "
          + "attribute";

  private static final String CONFIGURATION_ARG = "cfg";
  private static final String CONFIGURATION_DOC =
      "configuration of the attribute. It can be either \"data\", \"host\", or \"target\". "
          + "This parameter is required if <code>executable</code> is True.";

  private static final String DEFAULT_ARG = "default";
  private static final String DEFAULT_DOC = "the default value of the attribute.";

  private static final String DOC_ARG = "doc";
  private static final String DOC_DOC =
      "a description of the attribute that can be extracted by documentation generating tools.";

  private static final String EXECUTABLE_ARG = "executable";
  private static final String EXECUTABLE_DOC =
      "True if the labels have to be executable. This means the label must refer to an "
          + "executable file, or to a rule that outputs an executable file. Access the labels "
          + "with <code>ctx.executable.&lt;attribute_name&gt;</code>.";

  private static final String FLAGS_ARG = "flags";
  private static final String FLAGS_DOC = "deprecated, will be removed";

  private static final String MANDATORY_ARG = "mandatory";
  private static final String MANDATORY_DOC = "True if the value must be explicitly specified";

  private static final String NON_EMPTY_ARG = "non_empty";
  private static final String NON_EMPTY_DOC =
      "True if the attribute must not be empty. Deprecated: Use allow_empty instead.";

  private static final String ALLOW_EMPTY_ARG = "allow_empty";
  private static final String ALLOW_EMPTY_DOC = "True if the attribute can be empty";

  private static final String PROVIDERS_ARG = "providers";
  private static final String PROVIDERS_DOC =
      "mandatory providers list. It should be either a list of providers, or a "
          + "list of lists of providers. Every dependency should provide ALL providers "
          + "from at least ONE of these lists. A single list of providers will be "
          + "automatically converted to a list containing one list of providers.";

  private static final String SINGLE_FILE_ARG = "single_file";
  private static final String ALLOW_SINGLE_FILE_ARG = "allow_single_file";

  private static final String VALUES_ARG = "values";
  private static final String VALUES_DOC =
      "the list of allowed values for the attribute. An error is raised if any other "
          + "value is given.";

  private static boolean containsNonNoneKey(SkylarkDict<String, Object> arguments, String key) {
    return arguments.containsKey(key) && arguments.get(key) != Runtime.NONE;
  }

  private static void setAllowedFileTypes(
      String attr, Object fileTypesObj, FuncallExpression ast, Attribute.Builder<?> builder)
      throws EvalException {
    if (fileTypesObj == Boolean.TRUE) {
      builder.allowedFileTypes(FileTypeSet.ANY_FILE);
    } else if (fileTypesObj == Boolean.FALSE) {
      builder.allowedFileTypes(FileTypeSet.NO_FILE);
    } else if (fileTypesObj instanceof SkylarkFileType) {
      // TODO(laurentlb): deprecated, to be removed
      builder.allowedFileTypes(((SkylarkFileType) fileTypesObj).getFileTypeSet());
    } else if (fileTypesObj instanceof SkylarkList) {
      List<String> arg =
          SkylarkList.castSkylarkListOrNoneToList(
              fileTypesObj, String.class, "allow_files argument");
      builder.allowedFileTypes(FileType.of(arg));
    } else {
      throw new EvalException(
          ast.getLocation(), attr + " should be a boolean or a string list");
    }
  }

  private static Attribute.Builder<?> createAttribute(
      Type<?> type, SkylarkDict<String, Object> arguments, FuncallExpression ast, Environment env)
      throws EvalException {
    // We use an empty name now so that we can set it later.
    // This trick makes sense only in the context of Skylark (builtin rules should not use it).
    return createAttribute(type, arguments, ast, env, "");
  }

  private static Attribute.Builder<?> createAttribute(
      Type<?> type,
      SkylarkDict<String, Object> arguments,
      FuncallExpression ast,
      Environment env,
      String name)
      throws EvalException {
    Attribute.Builder<?> builder = Attribute.attr(name, type);

    Object defaultValue = arguments.get(DEFAULT_ARG);
    if (!EvalUtils.isNullOrNone(defaultValue)) {
      if (defaultValue instanceof UserDefinedFunction) {
        // Computed attribute. Non label type attributes already caused a type check error.
        SkylarkCallbackFunction callback =
            new SkylarkCallbackFunction((UserDefinedFunction) defaultValue, ast, env);
        // SkylarkComputedDefaultTemplate needs to know the names of all attributes that it depends
        // on. However, this method does not know anything about other attributes.
        // We solve this problem by asking the SkylarkCallbackFunction for the parameter names used
        // in the function definition, which must be the names of attributes used by the callback.
        builder.value(
            new SkylarkComputedDefaultTemplate(
                type, callback.getParameterNames(), callback, ast.getLocation()));
      } else if (defaultValue instanceof SkylarkLateBoundDefault) {
        builder.value((SkylarkLateBoundDefault) defaultValue);
      } else {
        builder.defaultValue(defaultValue, env.getGlobals().getTransitiveLabel(), DEFAULT_ARG);
      }
    }

    for (String flag : SkylarkList.castSkylarkListOrNoneToList(
        arguments.get(FLAGS_ARG), String.class, FLAGS_ARG)) {
      builder.setPropertyFlag(flag);
    }

    if (containsNonNoneKey(arguments, MANDATORY_ARG) && (Boolean) arguments.get(MANDATORY_ARG)) {
      builder.setPropertyFlag("MANDATORY");
    }

    // TODO(laurentlb): Deprecated, remove in August 2016 (use allow_empty instead).
    if (containsNonNoneKey(arguments, NON_EMPTY_ARG) && (Boolean) arguments.get(NON_EMPTY_ARG)) {
      builder.setPropertyFlag("NON_EMPTY");
    }

    if (containsNonNoneKey(arguments, ALLOW_EMPTY_ARG)
        && !(Boolean) arguments.get(ALLOW_EMPTY_ARG)) {
      builder.setPropertyFlag("NON_EMPTY");
    }

    if (containsNonNoneKey(arguments, EXECUTABLE_ARG) && (Boolean) arguments.get(EXECUTABLE_ARG)) {
      builder.setPropertyFlag("EXECUTABLE");
      if (!containsNonNoneKey(arguments, CONFIGURATION_ARG)) {
        throw new EvalException(
            ast.getLocation(),
            "cfg parameter is mandatory when executable=True is provided. Please see "
            + "https://www.bazel.build/versions/master/docs/skylark/rules.html#configurations "
            + "for more details.");
      }
    }

    // TODO(laurentlb): Deprecated, remove in August 2016 (use allow_single_file).
    if (containsNonNoneKey(arguments, SINGLE_FILE_ARG)
        && (Boolean) arguments.get(SINGLE_FILE_ARG)) {
      if (containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
        throw new EvalException(
            ast.getLocation(),
            "Cannot specify both single_file (deprecated) and allow_single_file");
      }
      builder.setPropertyFlag("SINGLE_ARTIFACT");
    }

    if (containsNonNoneKey(arguments, ALLOW_FILES_ARG)
        && containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
      throw new EvalException(
          ast.getLocation(), "Cannot specify both allow_files and allow_single_file");
    }

    if (containsNonNoneKey(arguments, ALLOW_FILES_ARG)) {
      Object fileTypesObj = arguments.get(ALLOW_FILES_ARG);
      setAllowedFileTypes(ALLOW_FILES_ARG, fileTypesObj, ast, builder);
    } else if (containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
      Object fileTypesObj = arguments.get(ALLOW_SINGLE_FILE_ARG);
      setAllowedFileTypes(ALLOW_SINGLE_FILE_ARG, fileTypesObj, ast, builder);
      builder.setPropertyFlag("SINGLE_ARTIFACT");
    } else if (type.getLabelClass() == LabelClass.DEPENDENCY) {
      builder.allowedFileTypes(FileTypeSet.NO_FILE);
    }

    Object ruleClassesObj = arguments.get(ALLOW_RULES_ARG);
    if (ruleClassesObj != null && ruleClassesObj != Runtime.NONE) {
      builder.allowedRuleClasses(
          SkylarkList.castSkylarkListOrNoneToList(
              ruleClassesObj, String.class, "allowed rule classes for attribute definition"));
    }

    List<Object> values = SkylarkList.castSkylarkListOrNoneToList(
        arguments.get(VALUES_ARG), Object.class, VALUES_ARG);
    if (!Iterables.isEmpty(values)) {
      builder.allowedValues(new AllowedValueSet(values));
    }

    if (containsNonNoneKey(arguments, PROVIDERS_ARG)) {
      Object obj = arguments.get(PROVIDERS_ARG);
      SkylarkType.checkType(obj, SkylarkList.class, PROVIDERS_ARG);
      ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> providersList = buildProviderPredicate(
          (SkylarkList<?>) obj, PROVIDERS_ARG, ast.getLocation());

      // If there is at least one empty set, there is no restriction.
      if (providersList.stream().noneMatch(ImmutableSet::isEmpty)) {
        builder.mandatoryProvidersList(providersList);
      }
    }

    if (containsNonNoneKey(arguments, CONFIGURATION_ARG)) {
      Object trans = arguments.get(CONFIGURATION_ARG);
      if (trans.equals("data")) {
        builder.cfg(ConfigurationTransition.DATA);
      } else if (trans.equals("host")) {
        builder.cfg(ConfigurationTransition.HOST);
      } else if (trans instanceof SplitTransition<?>) {
        builder.cfg((SplitTransition<?>) trans);
      } else if (trans instanceof SplitTransitionProvider) {
        builder.cfg((SplitTransitionProvider) trans);
      } else if (!trans.equals("target")) {
        throw new EvalException(ast.getLocation(),
            "cfg must be either 'data', 'host', or 'target'.");
      }
    }

    if (containsNonNoneKey(arguments, ASPECTS_ARG)) {
      Object obj = arguments.get(ASPECTS_ARG);
      SkylarkType.checkType(obj, SkylarkList.class, ASPECTS_ARG);

      List<SkylarkAspect> aspects =
          ((SkylarkList<?>) obj).getContents(SkylarkAspect.class, "aspects");
      for (SkylarkAspect aspect : aspects) {
        if (!aspect.isExported()) {
          throw new EvalException(
              ast.getLocation(),
              "Aspects should be top-level values in extension files that define them.");
        }
        builder.aspect(aspect, ast.getLocation());
      }
    }

    return builder;
  }

  /**
   * Builds a list of sets of accepted providers from Skylark list {@code obj}.
   * The list can either be a list of providers (in that case the result is a list with one
   * set) or a list of lists of providers (then the result is the list of sets).
   * @param argumentName used in error messages.
   * @param location location for error messages.
   */
  static ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> buildProviderPredicate(
      SkylarkList<?> obj, String argumentName, Location location) throws EvalException {
    if (obj.isEmpty()) {
      return ImmutableList.of();
    }
    boolean isListOfProviders = true;
    for (Object o : obj) {
      if (!isProvider(o)) {
        isListOfProviders = false;
        break;
      }
    }
    if (isListOfProviders) {
      return ImmutableList.of(getSkylarkProviderIdentifiers(obj, location));
    } else {
      return getProvidersList(obj, argumentName, location);
    }
  }

  /**
   * Returns true if {@code o} is a Skylark provider (either a declared provider or
   * a legacy provider name.
   */
  static boolean isProvider(Object o) {
    return o instanceof String || o instanceof Provider;
  }

  /**
   * Converts Skylark identifiers of providers (either a string or a provider value)
   * to their internal representations.
   */
  static ImmutableSet<SkylarkProviderIdentifier> getSkylarkProviderIdentifiers(
      SkylarkList<?> list, Location location) throws EvalException {
    ImmutableList.Builder<SkylarkProviderIdentifier> result = ImmutableList.builder();

    for (Object obj : list) {
      if (obj instanceof String) {
        result.add(SkylarkProviderIdentifier.forLegacy((String) obj));
      } else if (obj instanceof Provider) {
        Provider constructor = (Provider) obj;
        if (!constructor.isExported()) {
          throw new EvalException(location,
              "Providers should be top-level values in extension files that define them.");
        }
        result.add(SkylarkProviderIdentifier.forKey(constructor.getKey()));
      }
    }
    return ImmutableSet.copyOf(result.build());
  }

  private static ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> getProvidersList(
      SkylarkList<?> skylarkList, String argumentName, Location location) throws EvalException {
    ImmutableList.Builder<ImmutableSet<SkylarkProviderIdentifier>> providersList =
        ImmutableList.builder();
    String errorMsg = "Illegal argument: element in '%s' is of unexpected type. "
        + "Either all elements should be providers, "
        + "or all elements should be lists of providers, but got %s.";

    for (Object o : skylarkList) {
      if (!(o instanceof SkylarkList)) {
        throw new EvalException(location, String.format(errorMsg, PROVIDERS_ARG,
            "an element of type " + EvalUtils.getDataTypeName(o, true)));
      }
      for (Object value : (SkylarkList) o) {
        if (!isProvider(value)) {
          throw new EvalException(location, String.format(errorMsg, argumentName,
              "list with an element of type "
                  + EvalUtils.getDataTypeNameFromClass(value.getClass())));
        }
      }
      providersList.add(getSkylarkProviderIdentifiers((SkylarkList<?>) o, location));
    }
    return providersList.build();
  }

  private static Descriptor createAttrDescriptor(
      String name,
      SkylarkDict<String, Object> kwargs,
      Type<?> type,
      FuncallExpression ast,
      Environment env)
      throws EvalException {
    try {
      return new Descriptor(name, createAttribute(type, kwargs, ast, env));
    } catch (ConversionException e) {
      throw new EvalException(ast.getLocation(), e.getMessage());
    }
  }

  private static final Map<Type<?>, String> whyNotConfigurable =
      ImmutableMap.<Type<?>, String>builder()
          .put(BuildType.LICENSE,
              "loading phase license checking logic assumes non-configurable values")
          .put(BuildType.OUTPUT, "output paths are part of the static graph structure")
          .build();

  /**
   * If the given attribute type is non-configurable, returns the reason why. Otherwise, returns
   * {@code null}.
   */
  @Nullable
  public static String maybeGetNonConfigurableReason(Type<?> type) {
    return whyNotConfigurable.get(type);
  }

  private static Descriptor createNonconfigurableAttrDescriptor(
      String name,
      SkylarkDict<String, Object> kwargs,
      Type<?> type,
      FuncallExpression ast,
      Environment env)
      throws EvalException {
    String whyNotConfigurableReason =
        Preconditions.checkNotNull(maybeGetNonConfigurableReason(type), type);
    try {
      return new Descriptor(
          name, createAttribute(type, kwargs, ast, env).nonconfigurable(whyNotConfigurableReason));
    } catch (ConversionException e) {
      throw new EvalException(ast.getLocation(), e.getMessage());
    }
  }

  @Override
  public void repr(SkylarkPrinter printer) {
    printer.append("<attr>");
  }

  @SkylarkSignature(
    name = "int",
    doc = "Creates an attribute of type int.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        type = Integer.class,
        defaultValue = "0",
        doc = DEFAULT_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        doc = MANDATORY_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = VALUES_ARG,
        type = SkylarkList.class,
        generic1 = Integer.class,
        defaultValue = "[]",
        doc = VALUES_DOC,
        named = true,
        positional = false
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction integer =
      new BuiltinFunction("int") {
        public Descriptor invoke(
            Integer defaultInt,
            String doc,
            Boolean mandatory,
            SkylarkList<?> values,
            FuncallExpression ast,
            Environment env)
            throws EvalException {
          // TODO(bazel-team): Replace literal strings with constants.
          env.checkLoadingOrWorkspacePhase("attr.int", ast.getLocation());
          return createAttrDescriptor(
              getName(),
              EvalUtils.<String, Object>optionMap(
                  env, DEFAULT_ARG, defaultInt, MANDATORY_ARG, mandatory, VALUES_ARG, values),
              Type.INTEGER,
              ast,
              env);
        }
      };

  @SkylarkSignature(
    name = "configuration_field",
    returnType = SkylarkLateBoundDefault.class,
    // TODO(cparsons): Provide a link to documentation for available SkylarkConfigurationFields.
    doc = "References a late-bound default value for an attribute of type "
      + "<a href=\"attr.html#label\">label</a>. A value is 'late-bound' if it requires "
      + "the configuration to be built before determining the value. Any attribute using this "
      + "as a value must <a href=\"../rules.html#private-attributes\">be private</a>.",
    parameters = {
        @Param(
            name = "fragment",
            type = String.class,
            doc = "The name of a configuration fragment which contains the late-bound value."
        ),
        @Param(
            name = "name",
            type = String.class,
            doc = "The name of the value to obtain from the configuration fragment."),
    },
    useLocation = true,
    useEnvironment = true
  )
  private static final BuiltinFunction configurationField =
      new BuiltinFunction("configuration_field") {
        public SkylarkLateBoundDefault<?> invoke(
            String fragment, String name, Location loc, Environment env)
            throws EvalException {
          Class<?> fragmentClass = SkylarkUtils.getFragmentMap(env).get(fragment);

          if (fragmentClass == null) {
            throw new EvalException(
                loc,
                String.format("invalid configuration fragment name '%s'", fragment));
          }
          try {
            return SkylarkLateBoundDefault.forConfigurationField(
                fragmentClass, name, SkylarkUtils.getToolsRepository(env));
          } catch (SkylarkLateBoundDefault.InvalidConfigurationFieldException exception) {
            throw new EvalException(loc, exception);
          }
        }
      };

  @SkylarkSignature(
    name = "string",
    doc = "Creates an attribute of type <a href=\"string.html\">string</a>.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DEFAULT_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        doc = MANDATORY_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = VALUES_ARG,
        type = SkylarkList.class,
        generic1 = String.class,
        defaultValue = "[]",
        doc = VALUES_DOC,
        named = true,
        positional = false
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction string =
      new BuiltinFunction("string") {
        public Descriptor invoke(
            String defaultString,
            String doc,
            Boolean mandatory,
            SkylarkList<?> values,
            FuncallExpression ast,
            Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.string", ast.getLocation());
          return createAttrDescriptor(
              getName(),
              EvalUtils.<String, Object>optionMap(
                  env, DEFAULT_ARG, defaultString, MANDATORY_ARG, mandatory, VALUES_ARG, values),
              Type.STRING,
              ast,
              env);
        }
      };

  @SkylarkSignature(
    name = "label",
    doc =
        "Creates an attribute of type <a href=\"Target.html\">Target</a> which is the target "
            + "referred to by the label. "
            + "It is the only way to specify a dependency to another target. "
            + "If you need a dependency that the user cannot overwrite, "
            + "<a href=\"../rules.html#private-attributes\">make the attribute private</a>.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        allowedTypes = {
          @ParamType(type = Label.class),
          @ParamType(type = String.class),
          @ParamType(type = SkylarkLateBoundDefault.class)
        },
        callbackEnabled = true,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc =
            DEFAULT_DOC
                + "Use a string or the <a href=\"globals.html#Label\"><code>Label</code></a> "
                + "function to specify a default value ex: "
                + "<code>attr.label(default = \"//a:b\")</code>"
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = EXECUTABLE_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = EXECUTABLE_DOC
      ),
      @Param(
        name = ALLOW_FILES_ARG,
        defaultValue = "None",
        named = true,
        positional = false,
        doc = ALLOW_FILES_DOC
      ),
      @Param(
        name = ALLOW_SINGLE_FILE_ARG,
        defaultValue = "None",
        named = true,
        positional = false,
        doc =
            "This is similar to <code>allow_files</code>, with the restriction that the label must "
                + "correspond to a single <a href=\"File.html\">File</a>. "
                + "Access it through <code>ctx.file.&lt;attribute_name&gt;</code>."
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = MANDATORY_DOC
      ),
      @Param(
        name = PROVIDERS_ARG,
        type = SkylarkList.class,
        defaultValue = "[]",
        named = true,
        positional = false,
        doc = PROVIDERS_DOC
      ),
      @Param(
        name = ALLOW_RULES_ARG,
        type = SkylarkList.class,
        generic1 = String.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc = ALLOW_RULES_DOC
      ),
      @Param(
        name = SINGLE_FILE_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc =
            "Deprecated: Use <code>allow_single_file</code> instead. "
                + "If True, the label must correspond to a single <a href=\"File.html\">File</a>. "
                + "Access it through <code>ctx.file.&lt;attribute_name&gt;</code>."
      ),
      @Param(
        name = CONFIGURATION_ARG,
        type = Object.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc = CONFIGURATION_DOC
      ),
      @Param(
        name = ASPECTS_ARG,
        type = SkylarkList.class,
        generic1 = SkylarkAspect.class,
        defaultValue = "[]",
        named = true,
        positional = false,
        doc = ASPECTS_ARG_DOC
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction label =
      new BuiltinFunction("label") {
        public Descriptor invoke(
            Object defaultO,
            String doc,
            Boolean executable,
            Object allowFiles,
            Object allowSingleFile,
            Boolean mandatory,
            SkylarkList<?> providers,
            Object allowRules,
            Boolean singleFile,
            Object cfg,
            SkylarkList<?> aspects,
            FuncallExpression ast,
            Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.label", ast.getLocation());
          try {
            Attribute.Builder<?> attribute =
                createAttribute(
                    BuildType.LABEL,
                    EvalUtils.<String, Object>optionMap(
                        env,
                        DEFAULT_ARG,
                        defaultO,
                        EXECUTABLE_ARG,
                        executable,
                        ALLOW_FILES_ARG,
                        allowFiles,
                        ALLOW_SINGLE_FILE_ARG,
                        allowSingleFile,
                        MANDATORY_ARG,
                        mandatory,
                        PROVIDERS_ARG,
                        providers,
                        ALLOW_RULES_ARG,
                        allowRules,
                        SINGLE_FILE_ARG,
                        singleFile,
                        CONFIGURATION_ARG,
                        cfg,
                        ASPECTS_ARG,
                        aspects),
                    ast,
                    env,
                    "label");
            return new Descriptor(getName(), attribute);
          } catch (EvalException e) {
            throw new EvalException(ast.getLocation(), e.getMessage(), e);
          }
        }
      };

  @SkylarkSignature(
    name = "string_list",
    doc =
        "Creates an attribute which is a <a href=\"list.html\">list</a> of "
            + "<a href=\"string.html\">strings</a>.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        type = SkylarkList.class,
        generic1 = String.class,
        defaultValue = "[]",
        doc = DEFAULT_DOC
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        doc = MANDATORY_DOC
      ),
      @Param(
        name = NON_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        doc = NON_EMPTY_DOC
      ),
      @Param(
        name = ALLOW_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "True",
        doc = ALLOW_EMPTY_DOC
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction stringList =
      new BuiltinFunction("string_list") {
        public Descriptor invoke(
            SkylarkList<?> defaultList,
            String doc,
            Boolean mandatory,
            Boolean nonEmpty,
            Boolean allowEmpty,
            FuncallExpression ast,
            Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.string_list", ast.getLocation());
          return createAttrDescriptor(
              getName(),
              EvalUtils.<String, Object>optionMap(
                  env,
                  DEFAULT_ARG,
                  defaultList,
                  MANDATORY_ARG,
                  mandatory,
                  NON_EMPTY_ARG,
                  nonEmpty,
                  ALLOW_EMPTY_ARG,
                  allowEmpty),
              Type.STRING_LIST,
              ast,
              env);
        }
      };

  @SkylarkSignature(
    name = "int_list",
    doc = "Creates an attribute which is a <a href=\"list.html\">list</a> of ints.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        type = SkylarkList.class,
        generic1 = Integer.class,
        defaultValue = "[]",
        doc = DEFAULT_DOC
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        doc = MANDATORY_DOC
      ),
      @Param(
        name = NON_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        doc = NON_EMPTY_DOC
      ),
      @Param(
        name = ALLOW_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "True",
        doc = ALLOW_EMPTY_DOC
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction intList =
      new BuiltinFunction("int_list") {
        public Descriptor invoke(
            SkylarkList<?> defaultList,
            String doc,
            Boolean mandatory,
            Boolean nonEmpty,
            Boolean allowEmpty,
            FuncallExpression ast,
            Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.int_list", ast.getLocation());
          return createAttrDescriptor(
              getName(),
              EvalUtils.<String, Object>optionMap(
                  env,
                  DEFAULT_ARG,
                  defaultList,
                  MANDATORY_ARG,
                  mandatory,
                  NON_EMPTY_ARG,
                  nonEmpty,
                  ALLOW_EMPTY_ARG,
                  allowEmpty),
              Type.INTEGER_LIST,
              ast,
              env);
        }
      };

  @SkylarkSignature(
    name = "label_list",
    doc =
        "Creates an attribute which is a <a href=\"list.html\">list</a> of type "
            + "<a href=\"Target.html\">Target</a> which are specified by the labels in the list. "
            + "See <a href=\"attr.html#label\">label</a> for more information.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        type = SkylarkList.class,
        generic1 = Label.class,
        callbackEnabled = true,
        defaultValue = "[]",
        named = true,
        positional = false,
        doc =
            DEFAULT_DOC
                + "Use strings or the <a href=\"globals.html#Label\"><code>Label</code></a> "
                + "function to specify default values ex: "
                + "<code>attr.label_list(default = [\"//a:b\", \"//a:c\"])</code>"
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = ALLOW_FILES_ARG, // bool or FileType filter
        defaultValue = "None",
        named = true,
        positional = false,
        doc = ALLOW_FILES_DOC
      ),
      @Param(
        name = ALLOW_RULES_ARG,
        type = SkylarkList.class,
        generic1 = String.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc = ALLOW_RULES_DOC
      ),
      @Param(
        name = PROVIDERS_ARG,
        type = SkylarkList.class,
        defaultValue = "[]",
        named = true,
        positional = false,
        doc = PROVIDERS_DOC
      ),
      @Param(
        name = FLAGS_ARG,
        type = SkylarkList.class,
        generic1 = String.class,
        defaultValue = "[]",
        named = true,
        positional = false,
        doc = FLAGS_DOC
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = MANDATORY_DOC
      ),
      @Param(
        name = NON_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = NON_EMPTY_DOC
      ),
      @Param(
        name = ALLOW_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "True",
        doc = ALLOW_EMPTY_DOC
      ),
      @Param(
        name = CONFIGURATION_ARG,
        type = Object.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc = CONFIGURATION_DOC
      ),
      @Param(
        name = ASPECTS_ARG,
        type = SkylarkList.class,
        generic1 = SkylarkAspect.class,
        defaultValue = "[]",
        named = true,
        positional = false,
        doc = ASPECTS_ARG_DOC
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction labelList =
      new BuiltinFunction("label_list") {
        public Descriptor invoke(
            Object defaultList,
            String doc,
            Object allowFiles,
            Object allowRules,
            SkylarkList<?> providers,
            SkylarkList<?> flags,
            Boolean mandatory,
            Boolean nonEmpty,
            Boolean allowEmpty,
            Object cfg,
            SkylarkList<?> aspects,
            FuncallExpression ast,
            Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.label_list", ast.getLocation());
          SkylarkDict<String, Object> kwargs =
              EvalUtils.<String, Object>optionMap(
                  env,
                  DEFAULT_ARG,
                  defaultList,
                  ALLOW_FILES_ARG,
                  allowFiles,
                  ALLOW_RULES_ARG,
                  allowRules,
                  PROVIDERS_ARG,
                  providers,
                  FLAGS_ARG,
                  flags,
                  MANDATORY_ARG,
                  mandatory,
                  NON_EMPTY_ARG,
                  nonEmpty,
                  ALLOW_EMPTY_ARG,
                  allowEmpty,
                  CONFIGURATION_ARG,
                  cfg,
                  ASPECTS_ARG,
                  aspects);
          try {
            Attribute.Builder<?> attribute =
                createAttribute(BuildType.LABEL_LIST, kwargs, ast, env, "label_list");
            return new Descriptor(getName(), attribute);
          } catch (EvalException e) {
            throw new EvalException(ast.getLocation(), e.getMessage(), e);
          }
        }
      };

  @SkylarkSignature(
    name = "label_keyed_string_dict",
    doc =
        "Creates an attribute which is a <a href=\"dict.html\">dict</a>. Its keys are type "
            + "<a href=\"Target.html\">Target</a> and are specified by the label keys of the "
            + "input dict. Its values are <a href=\"string.html\">strings</a>. See "
            + "<a href=\"attr.html#label\">label</a> for more information.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        type = SkylarkDict.class,
        callbackEnabled = true,
        defaultValue = "{}",
        named = true,
        positional = false,
        doc =
            DEFAULT_DOC
                + "Use strings or the <a href=\"globals.html#Label\"><code>Label</code></a> "
                + "function to specify default values ex: "
                + "<code>attr.label_keyed_string_dict(default = "
                + "{\"//a:b\": \"value\", \"//a:c\": \"string\"})</code>"
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = ALLOW_FILES_ARG, // bool or FileType filter
        defaultValue = "None",
        named = true,
        positional = false,
        doc = ALLOW_FILES_DOC
      ),
      @Param(
        name = ALLOW_RULES_ARG,
        type = SkylarkList.class,
        generic1 = String.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc = ALLOW_RULES_DOC
      ),
      @Param(
        name = PROVIDERS_ARG,
        type = SkylarkList.class,
        defaultValue = "[]",
        named = true,
        positional = false,
        doc = PROVIDERS_DOC
      ),
      @Param(
        name = FLAGS_ARG,
        type = SkylarkList.class,
        generic1 = String.class,
        defaultValue = "[]",
        named = true,
        positional = false,
        doc = FLAGS_DOC
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = MANDATORY_DOC
      ),
      @Param(
        name = NON_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = NON_EMPTY_DOC
      ),
      @Param(
        name = ALLOW_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "True",
        doc = ALLOW_EMPTY_DOC
      ),
      @Param(
        name = CONFIGURATION_ARG,
        type = Object.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc = CONFIGURATION_DOC
      ),
      @Param(
        name = ASPECTS_ARG,
        type = SkylarkList.class,
        generic1 = SkylarkAspect.class,
        defaultValue = "[]",
        named = true,
        positional = false,
        doc = ASPECTS_ARG_DOC
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction labelKeyedStringDict =
      new BuiltinFunction("label_keyed_string_dict") {
        public Descriptor invoke(
            Object defaultList,
            String doc,
            Object allowFiles,
            Object allowRules,
            SkylarkList<?> providers,
            SkylarkList<?> flags,
            Boolean mandatory,
            Boolean nonEmpty,
            Boolean allowEmpty,
            Object cfg,
            SkylarkList<?> aspects,
            FuncallExpression ast,
            Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.label_keyed_string_dict", ast.getLocation());
          SkylarkDict<String, Object> kwargs =
              EvalUtils.<String, Object>optionMap(
                  env,
                  DEFAULT_ARG,
                  defaultList,
                  ALLOW_FILES_ARG,
                  allowFiles,
                  ALLOW_RULES_ARG,
                  allowRules,
                  PROVIDERS_ARG,
                  providers,
                  FLAGS_ARG,
                  flags,
                  MANDATORY_ARG,
                  mandatory,
                  NON_EMPTY_ARG,
                  nonEmpty,
                  ALLOW_EMPTY_ARG,
                  allowEmpty,
                  CONFIGURATION_ARG,
                  cfg,
                  ASPECTS_ARG,
                  aspects);
          try {
            Attribute.Builder<?> attribute =
                createAttribute(
                    BuildType.LABEL_KEYED_STRING_DICT, kwargs, ast, env, "label_keyed_string_dict");
            return new Descriptor(this.getName(), attribute);
          } catch (EvalException e) {
            throw new EvalException(ast.getLocation(), e.getMessage(), e);
          }
        }
      };

  @SkylarkSignature(
    name = "bool",
    doc = "Creates an attribute of type bool.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = DEFAULT_DOC
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = MANDATORY_DOC
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction bool =
      new BuiltinFunction("bool") {
        public Descriptor invoke(
            Boolean defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.bool", ast.getLocation());
          return createAttrDescriptor(
              getName(),
              EvalUtils.<String, Object>optionMap(
                  env, DEFAULT_ARG, defaultO, MANDATORY_ARG, mandatory),
              Type.BOOLEAN,
              ast,
              env);
        }
      };

  @SkylarkSignature(
    name = "output",
    doc =
        "Creates an attribute of type output. "
            + "The user provides a file name (string) and the rule must create an action that "
            + "generates the file.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        type = Label.class,
        noneable = true,
        defaultValue = "None",
        named = true,
        positional = false,
        doc = DEFAULT_DOC
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = MANDATORY_DOC
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction output =
      new BuiltinFunction("output") {
        public Descriptor invoke(
            Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.output", ast.getLocation());
          return createNonconfigurableAttrDescriptor(
              getName(),
              EvalUtils.<String, Object>optionMap(
                  env, DEFAULT_ARG, defaultO, MANDATORY_ARG, mandatory),
              BuildType.OUTPUT,
              ast,
              env);
        }
      };

  @SkylarkSignature(
    name = "output_list",
    doc =
        "Creates an attribute which is a <a href=\"list.html\">list</a> of outputs. "
            + "See <a href=\"attr.html#output\">output</a> for more information.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        type = SkylarkList.class,
        generic1 = Label.class,
        defaultValue = "[]",
        named = true,
        positional = false,
        doc = DEFAULT_DOC
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = MANDATORY_DOC
      ),
      @Param(
        name = NON_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = NON_EMPTY_DOC
      ),
      @Param(
        name = ALLOW_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "True",
        doc = ALLOW_EMPTY_DOC
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction outputList =
      new BuiltinFunction("output_list") {
        public Descriptor invoke(
            SkylarkList defaultList,
            String doc,
            Boolean mandatory,
            Boolean nonEmpty,
            Boolean allowEmpty,
            FuncallExpression ast,
            Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.output_list", ast.getLocation());
          return createAttrDescriptor(
              getName(),
              EvalUtils.<String, Object>optionMap(
                  env,
                  DEFAULT_ARG,
                  defaultList,
                  MANDATORY_ARG,
                  mandatory,
                  NON_EMPTY_ARG,
                  nonEmpty,
                  ALLOW_EMPTY_ARG,
                  allowEmpty),
              BuildType.OUTPUT_LIST,
              ast,
              env);
        }
      };

  @SkylarkSignature(
    name = "string_dict",
    doc =
        "Creates an attribute of type <a href=\"dict.html\">dict</a>, mapping from "
            + "<a href=\"string.html\">string</a> to <a href=\"string.html\">string</a>.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        type = SkylarkDict.class,
        named = true,
        positional = false,
        defaultValue = "{}",
        doc = DEFAULT_DOC
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        named = true,
        positional = false,
        defaultValue = "False",
        doc = MANDATORY_DOC
      ),
      @Param(
        name = NON_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = NON_EMPTY_DOC
      ),
      @Param(
        name = ALLOW_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "True",
        doc = ALLOW_EMPTY_DOC
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction stringDict =
      new BuiltinFunction("string_dict") {
        public Descriptor invoke(
            SkylarkDict<?, ?> defaultO,
            String doc,
            Boolean mandatory,
            Boolean nonEmpty,
            Boolean allowEmpty,
            FuncallExpression ast,
            Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.string_dict", ast.getLocation());
          return createAttrDescriptor(
              getName(),
              EvalUtils.<String, Object>optionMap(
                  env,
                  DEFAULT_ARG,
                  defaultO,
                  MANDATORY_ARG,
                  mandatory,
                  NON_EMPTY_ARG,
                  nonEmpty,
                  ALLOW_EMPTY_ARG,
                  allowEmpty),
              Type.STRING_DICT,
              ast,
              env);
        }
      };

  @SkylarkSignature(
    name = "string_list_dict",
    doc =
        "Creates an attribute of type <a href=\"dict.html\">dict</a>, mapping from "
            + "<a href=\"string.html\">string</a> to <a href=\"list.html\">list</a> of "
            + "<a href=\"string.html\">string</a>.",
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      @Param(
        name = DEFAULT_ARG,
        type = SkylarkDict.class,
        defaultValue = "{}",
        named = true,
        positional = false,
        doc = DEFAULT_DOC
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = MANDATORY_DOC
      ),
      @Param(
        name = NON_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = NON_EMPTY_DOC
      ),
      @Param(
        name = ALLOW_EMPTY_ARG,
        type = Boolean.class,
        defaultValue = "True",
        doc = ALLOW_EMPTY_DOC
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction stringListDict =
      new BuiltinFunction("string_list_dict") {
        public Descriptor invoke(
            SkylarkDict<?, ?> defaultO,
            String doc,
            Boolean mandatory,
            Boolean nonEmpty,
            Boolean allowEmpty,
            FuncallExpression ast,
            Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.string_list_dict", ast.getLocation());
          return createAttrDescriptor(
              getName(),
              EvalUtils.<String, Object>optionMap(
                  env,
                  DEFAULT_ARG,
                  defaultO,
                  MANDATORY_ARG,
                  mandatory,
                  NON_EMPTY_ARG,
                  nonEmpty,
                  ALLOW_EMPTY_ARG,
                  allowEmpty),
              Type.STRING_LIST_DICT,
              ast,
              env);
        }
      };

  @SkylarkSignature(
    name = "license",
    doc = "Creates an attribute of type license.",
    // TODO(bazel-team): Implement proper license support for Skylark.
    objectType = SkylarkAttr.class,
    returnType = Descriptor.class,
    parameters = {
      // TODO(bazel-team): ensure this is the correct default value
      @Param(
        name = DEFAULT_ARG,
        defaultValue = "None",
        noneable = true,
        named = true,
        positional = false,
        doc = DEFAULT_DOC
      ),
      @Param(
        name = DOC_ARG,
        type = String.class,
        defaultValue = "''",
        doc = DOC_DOC,
        named = true,
        positional = false
      ),
      @Param(
        name = MANDATORY_ARG,
        type = Boolean.class,
        defaultValue = "False",
        named = true,
        positional = false,
        doc = MANDATORY_DOC
      )
    },
    useAst = true,
    useEnvironment = true
  )
  private static BuiltinFunction license =
      new BuiltinFunction("license") {
        public Descriptor invoke(
            Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
            throws EvalException {
          env.checkLoadingOrWorkspacePhase("attr.license", ast.getLocation());
          return createNonconfigurableAttrDescriptor(
              getName(),
              EvalUtils.<String, Object>optionMap(
                  env, DEFAULT_ARG, defaultO, MANDATORY_ARG, mandatory),
              BuildType.LICENSE,
              ast,
              env);
        }
      };

  /** A descriptor of an attribute defined in Skylark. */
  @SkylarkModule(
    name = "Attribute",
    category = SkylarkModuleCategory.NONE,
    doc =
        "Representation of a definition of an attribute. Use the <a href=\"attr\"> module to "
            + "create an Attribute. They are only for use with "
            + "<a href=\"globals.html#rule\">rule</a> or "
            + "<a href=\"globals.html#aspect\">aspect</a>."
  )
  public static final class Descriptor implements SkylarkValue {
    private final Attribute.Builder<?> attributeBuilder;

    /**
     * This lock guards {@code attributeBuilder} field.
     *
     * {@link Attribute.Builder} class is not thread-safe for concurrent modification.
     */
    private final Object lock = new Object();

    private final String name;

    public Descriptor(String name, Attribute.Builder<?> attributeBuilder) {
      this.attributeBuilder = attributeBuilder;
      this.name = name;
    }

    public boolean hasDefault() {
      synchronized (lock) {
        return attributeBuilder.isValueSet();
      }
    }

    public AttributeValueSource getValueSource() {
      synchronized (lock) {
        return attributeBuilder.getValueSource();
      }
    }

    public Attribute build(String name) {
      synchronized (lock) {
        return attributeBuilder.build(name);
      }
    }

    @Override
    public void repr(SkylarkPrinter printer) {
      printer.append("<attr." + name + ">");
    }
  }

  static {
    SkylarkSignatureProcessor.configureSkylarkFunctions(SkylarkAttr.class);
  }
}
