Document declared providers.

Change-Id: Ifdc1773fb1439c16327bb84961998793a942e666
PiperOrigin-RevId: 154151084
diff --git a/site/designs/index.md b/site/designs/index.md
index 67656da..6792ee2 100644
--- a/site/designs/index.md
+++ b/site/designs/index.md
@@ -18,6 +18,10 @@
 Always go to the [documentation](/versions/master/docs/bazel-overview.md) for
 descriptions of current Bazel functionality.
 
+## Bazel Code Style and Best Practices
+
+* [Implementing Native Declared Provders](https://docs.google.com/document/d/1BKCBuYvf6fwmMnFu3KMWdRFysDgGCzdMiNxY_foosAM/preview) 12 April 2017
+
 ## Bazel Design Documents
 
 <ul>
diff --git a/site/versions/master/docs/skylark/cookbook.md b/site/versions/master/docs/skylark/cookbook.md
index 4e17364..b71ce51 100644
--- a/site/versions/master/docs/skylark/cookbook.md
+++ b/site/versions/master/docs/skylark/cookbook.md
@@ -503,7 +503,7 @@
       content=command,
       executable=True)
 
-  return struct(
+  return [DefaultInfo(
       # Create runfiles from the files specified in the data attribute.
       # The shell executable - the output of this rule - can use them at runtime.
       # It is also possible to define data_runfiles and default_runfiles.
@@ -513,7 +513,7 @@
       # to have a field named "runfiles" in order to create the actual runfiles
       # symlink tree.
       runfiles=ctx.runfiles(files=ctx.files.data)
-  )
+  )]
 
 execute = rule(
   implementation=_impl,
@@ -661,14 +661,16 @@
 `sum.bzl`:
 
 ```python
+NumberInfo = provider()
+
 def _impl(ctx):
   result = ctx.attr.number
-  for i in ctx.attr.deps:
-    result += i.number
+  for dep in ctx.attr.deps:
+    result += dep[NumberInfo].number
   ctx.file_action(output=ctx.outputs.out, content=str(result))
 
-  # Fields in the struct will be visible by other rules.
-  return struct(number=result)
+  # Return the provider with result, visible to other rules.
+  return [NumberInfo(number=result)]
 
 sum = rule(
   implementation=_impl,
@@ -709,15 +711,17 @@
 `sum.bzl`:
 
 ```python
+NumberInfo = provider()
+
 def _impl(ctx):
   result = ctx.attr.number
-  for i in ctx.attr.deps:
-    if hasattr(i, "number"):
-      result += i.number
+  for dep in ctx.attr.deps:
+    if NumberInfo in dep:
+      result += dep[NumberInfo].number
   ctx.file_action(output=ctx.outputs.out, content=str(result))
 
-  # Fields in the struct will be visible by other rules.
-  return struct(number=result)
+  # Return the provider with result, visible to other rules.
+  return [NumberInfo(number=result)]
 
 sum = rule(
   implementation=_impl,
@@ -864,7 +868,7 @@
   files = depset()
   files += ctx.attr.dep_rule_1.files
   files += ctx.attr.dep_rule_2.files
-  return struct(files=files)
+  return [DefaultInfo(files=files)]
 
 # This rule binds the depending rules together
 master_rule = rule(
diff --git a/site/versions/master/docs/skylark/rules.md b/site/versions/master/docs/skylark/rules.md
index 5db62cf..56ef328 100644
--- a/site/versions/master/docs/skylark/rules.md
+++ b/site/versions/master/docs/skylark/rules.md
@@ -114,11 +114,7 @@
 ```python
 def _impl(ctx):
   ...
-  return struct(
-      runfiles = ...,
-      my_provider = ...,
-      ...
-  )
+  return [DefaultInfo(runfiles=...),  MyInfo(...)]
 
 my_rule = rule(
     implementation = _impl,
@@ -350,46 +346,72 @@
 using [depsets](depsets.md) to hold the data more efficiently without excessive
 copying.
 
-The following data types can be passed using providers:
+Providers can be declared using the [provider()](lib/globals.html#provider) function:
 
-* [bool](lib/bool.html)
-* [integer](lib/int.html)
-* [string](lib/string.html)
-* [file](lib/File.html)
-* [label](lib/Label.html)
-* [None](lib/globals.html#None)
-* anything composed of these types and [lists](lib/list.html),
- [dicts](lib/dict.html),  [depsets](lib/depset.html) or
- [structs](lib/struct.html).
+```python
+TransitiveDataInfo = provider()
+```
 
-Providers are created from the return value of the rule implementation function:
+Rule implementation function can then construct and return provider instances:
 
 ```python
 def rule_implementation(ctx):
   ...
-  return struct(
-    transitive_data = depset(["a", "b", "c"])
-  )
+  return [TransitiveDataInfo(value = ["a", "b", "c"])]
 ```
 
-A dependent rule might access these data as struct fields of the `target` being
-depended upon:
+`TransitiveDataInfo` acts both as a constructor for provider instances and as a key to access them.
+A [target](lib/Target.html) serves as a map from each provider that the target supports, to the
+target's corresponding instance of that provider.
+A rule can access the providers of its dependencies using the square bracket notation (`[]`):
 
 ```python
 def dependent_rule_implementation(ctx):
   ...
   s = depset()
   for dep_target in ctx.attr.deps:
-    # Use `print(dir(dep_target))` to see the list of providers.
-    s += dep_target.transitive_data
+    s += dep_target[TransitiveDataInfo].value
   ...
 ```
 
+All targets have a [`DefaultInfo`](lib/globals.html#DefaultInfo) provider that can be used to access
+some information relevant to all targets.
+
 Providers are only available during the analysis phase. Examples of usage:
 
 * [mandatory providers](cookbook.md#mandatory-providers)
 * [optional providers](cookbook.md#optional-providers)
 
+> *Note:*
+> Historically, Bazel also supported provider instances that are identified by strings and
+> accessed as fields on the `target` object instead of as keys. This style is deprecated
+> but still supported. Return legacy providers as follows:
+>
+```python
+def rule_implementation(ctx):
+  ...
+  modern_provider = TransitiveDataInfo(value = ["a", "b", "c"])
+  # Legacy style.
+  return struct(legacy_provider = struct(...),
+                another_legacy_provider = struct(...),
+                # The `providers` field contains provider instances that can be accessed
+                # the "modern" way.
+                providers = [modern_provider])
+```
+> To access legacy providers, use the dot notation.
+> Note that the same target can define both modern and legacy providers:
+>
+```python
+def dependent_rule_implementation(ctx):
+  ...
+  s = depset()
+  for dep_target in ctx.attr.deps:
+    x = dep_target.legacy_provider            # legacy style
+    s += dep_target[TransitiveDataInfo].value # modern style
+  ...
+```
+> **We recommend using modern providers for all future code.**
+
 ## Runfiles
 
 Runfiles are a set of files used by the (often executable) output of a rule
@@ -418,9 +440,9 @@
       # deps and data attributes.
       collect_default = True,
   )
-  # Add a field named "runfiles" to the return struct in order to actually
+  # Add a field named "runfiles" to the DefaultInfo provider in order to actually
   # create the symlink tree.
-  return struct(runfiles = runfiles)
+  return [DefaultInfo(runfiles=runfiles)]
 ```
 
 Note that non-executable rule outputs can also have runfiles. For example, a
diff --git a/src/main/java/com/google/devtools/build/lib/packages/ClassObjectConstructor.java b/src/main/java/com/google/devtools/build/lib/packages/ClassObjectConstructor.java
index e2e0ccf..8275e6a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/ClassObjectConstructor.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/ClassObjectConstructor.java
@@ -27,19 +27,37 @@
 /**
  * Declared Provider (a constructor for {@link SkylarkClassObject}).
  *
- * Declared providers can be declared either natively ({@link NativeClassObjectConstructor}
- * or in Skylark {@link SkylarkClassObjectConstructor}.
+ * <p>Declared providers can be declared either natively ({@link NativeClassObjectConstructor} or in
+ * Skylark {@link SkylarkClassObjectConstructor}.
  *
- * {@link ClassObjectConstructor} serves both as "type identifier" for declared provider
+ * <p>{@link ClassObjectConstructor} serves both as "type identifier" for declared provider
  * instances and as a function that can be called to construct a provider.
  *
- * Prefer to use {@link Key} as a serializable identifier of {@link ClassObjectConstructor}.
- * In particular, {@link Key} should be used in all data structures exposed to Skyframe.
+ * <p>Prefer to use {@link Key} as a serializable identifier of {@link ClassObjectConstructor}. In
+ * particular, {@link Key} should be used in all data structures exposed to Skyframe.
  */
-@SkylarkModule(name = "provider",
-    doc = "A constructor for simple value objects. "
-        + "See the global <a href=\"globals.html#provider\">provider</a> function "
-        + "for more details."
+@SkylarkModule(
+  name = "Provider",
+  doc =
+      "A constructor for simple value objects, known as provider instances."
+          + "<br>"
+          + "This value has a dual purpose:"
+          + "  <ul>"
+          + "     <li>It is a function that can be called to construct 'struct'-like values:"
+          + "<pre class=\"language-python\">DataInfo = provider()\n"
+          + "d = DataInfo(x = 2, y = 3)\n"
+          + "print(d.x + d.y) # prints 5</pre>"
+          + "     <i>Some providers, defined internally, do not allow instance creation</i>"
+          + "     </li>"
+          + "     <li>It is a <i>key</i> to access a provider instance on a"
+          + "        <a href=\"lib/Target.html\">Target</a>"
+          + "<pre class=\"language-python\">DataInfo = provider()\n"
+          + "def _rule_impl(ctx)\n"
+          + "  ... ctx.attr.dep[DataInfo]</pre>"
+          + "     </li>"
+          + "  </ul>"
+          + "Create a new <code>Provider</code> using the "
+          + "<a href=\"globals.html#provider\">provider</a> function."
 )
 @Immutable
 public abstract class ClassObjectConstructor extends BaseFunction {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
index 24803c1..aefdfaf 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
@@ -194,16 +194,18 @@
   @SkylarkSignature(
     name = "DefaultInfo",
     returnType = ClassObjectConstructor.class,
-    doc = "A provider that is provided by every rule, even if it iss not returned explicitly. "
-        + "A <code>DefaultInfo</code> accepts all special parameters that can be returned "
-        + "from rule implementation function in a struct, which are <code>runfiles</code>, "
-        + "<code>data_runfiles</code>, <code>default_runfiles</code>, "
-        + "<code>output_groups</code>, <code>instrumented_files</code>, and all "
-        + "<a href=\"skylark-provider.html\">providers</a> that are available on built-in rules. "
-        + "Each instance of the default provider contains the following standard fields: "
-        + "<code>data_runfiles</code>, <code>default_runfiles</code>, <code>files</code>, "
-        + "and <code>files_to_run</code>. The values of these fields are equivalent to the "
-        + "values of the corresponding fields of the target the default provider belongs to."
+    doc =
+        "A provider that is provided by every rule, even if it iss not returned explicitly. "
+            + "A <code>DefaultInfo</code> accepts all special parameters that can be returned "
+            + "from rule implementation function in a struct, which are <code>runfiles</code>, "
+            + "<code>data_runfiles</code>, <code>default_runfiles</code>, <code>files</code>, "
+            + "<code>output_groups</code>, <code>instrumented_files</code>, and all "
+            + "<a href=\"skylark-provider.html\">providers</a> that are available on built-in " 
+            + "rules. Each instance of the default provider contains the following standard "
+            + "fields: <code>data_runfiles</code>, <code>default_runfiles</code>, "
+            + "<code>files</code>, and <code>files_to_run</code>. The values of these fields "
+            + "are equivalent to the values of the corresponding fields of the target "
+            + "the default provider belongs to."
   )
   private static final ClassObjectConstructor defaultInfo = DefaultProvider.SKYLARK_CONSTRUCTOR;
 
@@ -226,7 +228,7 @@
   )
   private static final ClassObjectConstructor actions = ActionsProvider.SKYLARK_CONSTRUCTOR;
 
-  @SkylarkSignature(name = "provider", returnType = SkylarkClassObjectConstructor.class, doc =
+  @SkylarkSignature(name = "provider", returnType = ClassObjectConstructor.class, doc =
       "Creates a declared provider 'constructor'. The return value of this"
           + "function can be used to create \"struct-like\" values. Example:<br>"
           + "<pre class=\"language-python\">data = provider()\n"
@@ -236,7 +238,7 @@
   )
   private static final BuiltinFunction provider =
       new BuiltinFunction("provider") {
-        public SkylarkClassObjectConstructor invoke(Location location) {
+        public ClassObjectConstructor invoke(Location location) {
           return new SkylarkClassObjectConstructor(
               "<no name>", // name is set on export.
               location);