Render attribute default information

Fixes https://github.com/bazelbuild/skydoc/issues/238

RELNOTES: None.
PiperOrigin-RevId: 273354924
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeDescriptor.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeDescriptor.java
index 30668a4..5d8f6b5 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeDescriptor.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeDescriptor.java
@@ -29,16 +29,19 @@
   private final String docString;
   private final boolean mandatory;
   private final List<List<String>> providerNameGroups;
+  private final String defaultRepresentation;
 
   public FakeDescriptor(
       AttributeType type,
       String docString,
       boolean mandatory,
-      List<List<String>> providerNameGroups) {
+      List<List<String>> providerNameGroups,
+      Object defaultObject) {
     this.type = type;
     this.docString = docString;
     this.mandatory = mandatory;
     this.providerNameGroups = providerNameGroups;
+    this.defaultRepresentation = defaultObject.toString();
   }
 
   @Override
@@ -50,7 +53,8 @@
             .setName(attributeName)
             .setDocString(docString)
             .setType(type)
-            .setMandatory(mandatory);
+            .setMandatory(mandatory)
+            .setDefaultValue(mandatory ? "" : defaultRepresentation);
 
     if (!providerNameGroups.isEmpty()) {
       for (List<String> providerNameGroup : providerNameGroups) {
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAttrApi.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAttrApi.java
index 92552be..25c79b5 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAttrApi.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAttrApi.java
@@ -43,7 +43,7 @@
       FuncallExpression ast,
       StarlarkThread thread)
       throws EvalException {
-    return new FakeDescriptor(AttributeType.INT, doc, mandatory, ImmutableList.of());
+    return new FakeDescriptor(AttributeType.INT, doc, mandatory, ImmutableList.of(), defaultInt);
   }
 
   @Override
@@ -55,7 +55,12 @@
       FuncallExpression ast,
       StarlarkThread thread)
       throws EvalException {
-    return new FakeDescriptor(AttributeType.STRING, doc, mandatory, ImmutableList.of());
+    return new FakeDescriptor(
+        AttributeType.STRING,
+        doc,
+        mandatory,
+        ImmutableList.of(),
+        defaultString != null ? "\"" + defaultString + "\"" : null);
   }
 
   @Override
@@ -78,7 +83,7 @@
     if (providers != null) {
       allNameGroups = allProviderNameGroups(providers, thread);
     }
-    return new FakeDescriptor(AttributeType.LABEL, doc, mandatory, allNameGroups);
+    return new FakeDescriptor(AttributeType.LABEL, doc, mandatory, allNameGroups, defaultO);
   }
 
   @Override
@@ -91,7 +96,8 @@
       FuncallExpression ast,
       StarlarkThread thread)
       throws EvalException {
-    return new FakeDescriptor(AttributeType.STRING_LIST, doc, mandatory, ImmutableList.of());
+    return new FakeDescriptor(
+        AttributeType.STRING_LIST, doc, mandatory, ImmutableList.of(), defaultList);
   }
 
   @Override
@@ -104,7 +110,8 @@
       FuncallExpression ast,
       StarlarkThread thread)
       throws EvalException {
-    return new FakeDescriptor(AttributeType.INT_LIST, doc, mandatory, ImmutableList.of());
+    return new FakeDescriptor(
+        AttributeType.INT_LIST, doc, mandatory, ImmutableList.of(), defaultList);
   }
 
   @Override
@@ -127,7 +134,7 @@
     if (providers != null) {
       allNameGroups = allProviderNameGroups(providers, thread);
     }
-    return new FakeDescriptor(AttributeType.LABEL_LIST, doc, mandatory, allNameGroups);
+    return new FakeDescriptor(AttributeType.LABEL_LIST, doc, mandatory, allNameGroups, defaultList);
   }
 
   @Override
@@ -150,21 +157,27 @@
     if (providers != null) {
       allNameGroups = allProviderNameGroups(providers, thread);
     }
-    return new FakeDescriptor(AttributeType.LABEL_STRING_DICT, doc, mandatory, allNameGroups);
+    return new FakeDescriptor(
+        AttributeType.LABEL_STRING_DICT, doc, mandatory, allNameGroups, defaultList);
   }
 
   @Override
   public Descriptor boolAttribute(
       Boolean defaultO, String doc, Boolean mandatory, FuncallExpression ast, StarlarkThread thread)
       throws EvalException {
-    return new FakeDescriptor(AttributeType.BOOLEAN, doc, mandatory, ImmutableList.of());
+    return new FakeDescriptor(
+        AttributeType.BOOLEAN,
+        doc,
+        mandatory,
+        ImmutableList.of(),
+        Boolean.TRUE.equals(defaultO) ? "True" : "False");
   }
 
   @Override
   public Descriptor outputAttribute(
       Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, StarlarkThread thread)
       throws EvalException {
-    return new FakeDescriptor(AttributeType.OUTPUT, doc, mandatory, ImmutableList.of());
+    return new FakeDescriptor(AttributeType.OUTPUT, doc, mandatory, ImmutableList.of(), defaultO);
   }
 
   @Override
@@ -177,7 +190,8 @@
       FuncallExpression ast,
       StarlarkThread thread)
       throws EvalException {
-    return new FakeDescriptor(AttributeType.OUTPUT_LIST, doc, mandatory, ImmutableList.of());
+    return new FakeDescriptor(
+        AttributeType.OUTPUT_LIST, doc, mandatory, ImmutableList.of(), defaultList);
   }
 
   @Override
@@ -190,7 +204,8 @@
       FuncallExpression ast,
       StarlarkThread thread)
       throws EvalException {
-    return new FakeDescriptor(AttributeType.STRING_DICT, doc, mandatory, ImmutableList.of());
+    return new FakeDescriptor(
+        AttributeType.STRING_DICT, doc, mandatory, ImmutableList.of(), defaultO);
   }
 
   @Override
@@ -203,14 +218,16 @@
       FuncallExpression ast,
       StarlarkThread thread)
       throws EvalException {
-    return new FakeDescriptor(AttributeType.STRING_LIST_DICT, doc, mandatory, ImmutableList.of());
+    return new FakeDescriptor(
+        AttributeType.STRING_LIST_DICT, doc, mandatory, ImmutableList.of(), defaultO);
   }
 
   @Override
   public Descriptor licenseAttribute(
       Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, StarlarkThread thread)
       throws EvalException {
-    return new FakeDescriptor(AttributeType.STRING_LIST, doc, mandatory, ImmutableList.of());
+    return new FakeDescriptor(
+        AttributeType.STRING_LIST, doc, mandatory, ImmutableList.of(), defaultO);
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java
index 711bd23..0d1d28d 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java
@@ -58,7 +58,7 @@
 
   private static final FakeDescriptor IMPLICIT_NAME_ATTRIBUTE_DESCRIPTOR =
       new FakeDescriptor(
-          AttributeType.NAME, "A unique name for this target.", true, ImmutableList.of());
+          AttributeType.NAME, "A unique name for this target.", true, ImmutableList.of(), "");
   private final List<RuleInfoWrapper> ruleInfoList;
 
   private final List<ProviderInfoWrapper> providerInfoList;
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/repository/FakeRepositoryModule.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/repository/FakeRepositoryModule.java
index 3f61a88..b6ff221 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/repository/FakeRepositoryModule.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/repository/FakeRepositoryModule.java
@@ -39,7 +39,7 @@
 public class FakeRepositoryModule implements RepositoryModuleApi {
   private static final FakeDescriptor IMPLICIT_NAME_ATTRIBUTE_DESCRIPTOR =
       new FakeDescriptor(
-          AttributeType.NAME, "A unique name for this repository.", true, ImmutableList.of());
+          AttributeType.NAME, "A unique name for this repository.", true, ImmutableList.of(), "");
 
   private final List<RuleInfoWrapper> ruleInfoList;
 
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/proto/stardoc_output.proto b/src/main/java/com/google/devtools/build/skydoc/rendering/proto/stardoc_output.proto
index 5cf36ef..1c46f23 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/proto/stardoc_output.proto
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/proto/stardoc_output.proto
@@ -97,6 +97,9 @@
   // label, a label list, or a label-keyed string dictionary, the field will be
   // left empty.
   repeated ProviderNameGroup provider_name_group = 5;
+
+  // The string representation of the default value of this attribute.
+  string default_value = 6;
 }
 
 // Representation of a set of providers that a rule attribute may be required to
diff --git a/src/test/java/com/google/devtools/build/skydoc/BUILD b/src/test/java/com/google/devtools/build/skydoc/BUILD
index 1674672..f73db4f 100644
--- a/src/test/java/com/google/devtools/build/skydoc/BUILD
+++ b/src/test/java/com/google/devtools/build/skydoc/BUILD
@@ -259,6 +259,13 @@
     input_file = "testdata/pure_markdown_template_test/input.bzl",
 )
 
+skydoc_test(
+    name = "attribute_defaults_test",
+    format = "markdown_tables",
+    golden_file = "testdata/attribute_defaults_test/golden.txt",
+    input_file = "testdata/attribute_defaults_test/input.bzl",
+)
+
 genrule(
     name = "generate_bzl_test_dep",
     srcs = ["testdata/generated_bzl_test/dep.bzl.tpl"],
diff --git a/src/test/java/com/google/devtools/build/skydoc/test_templates/markdown_tables/aspect.vm b/src/test/java/com/google/devtools/build/skydoc/test_templates/markdown_tables/aspect.vm
index cd57ab7..8bc3391 100644
--- a/src/test/java/com/google/devtools/build/skydoc/test_templates/markdown_tables/aspect.vm
+++ b/src/test/java/com/google/devtools/build/skydoc/test_templates/markdown_tables/aspect.vm
@@ -24,9 +24,9 @@
 
 #if (!$aspectInfo.getAttributeList().isEmpty())
 
-| Name  | Description | Type | Mandatory |
-| :-------------: | :-------------: | :-------------: | :-------------: |
+| Name  | Description | Type | Mandatory | Default |
+| :-------------: | :-------------: | :-------------: | :-------------: | :-------------: |
 #foreach ($attribute in $aspectInfo.getAttributeList())
-| $attribute.name | #if(!$attribute.docString.isEmpty()) ${util.markdownCellFormat($attribute.docString)} #else - #end  | ${util.attributeTypeString($attribute)} | ${util.mandatoryString($attribute)} |
+| $attribute.name | #if(!$attribute.docString.isEmpty()) ${util.markdownCellFormat($attribute.docString)} #else - #end  | ${util.attributeTypeString($attribute)} | ${util.mandatoryString($attribute)} |  $attribute.defaultValue |
 #end
 #end
diff --git a/src/test/java/com/google/devtools/build/skydoc/test_templates/markdown_tables/rule.vm b/src/test/java/com/google/devtools/build/skydoc/test_templates/markdown_tables/rule.vm
index a6f546c..567bc9f 100644
--- a/src/test/java/com/google/devtools/build/skydoc/test_templates/markdown_tables/rule.vm
+++ b/src/test/java/com/google/devtools/build/skydoc/test_templates/markdown_tables/rule.vm
@@ -12,9 +12,9 @@
 
 #if (!$ruleInfo.getAttributeList().isEmpty())
 
-| Name  | Description | Type | Mandatory |
-| :-------------: | :-------------: | :-------------: | :-------------: |
+| Name  | Description | Type | Mandatory | Default |
+| :-------------: | :-------------: | :-------------: | :-------------: | :-------------: |
 #foreach ($attribute in $ruleInfo.getAttributeList())
-| $attribute.name | #if(!$attribute.docString.isEmpty()) ${util.markdownCellFormat($attribute.docString)} #else - #end  | ${util.attributeTypeString($attribute)} | ${util.mandatoryString($attribute)} |
+| $attribute.name | #if(!$attribute.docString.isEmpty()) ${util.markdownCellFormat($attribute.docString)} #else - #end  | ${util.attributeTypeString($attribute)} | ${util.mandatoryString($attribute)} | $attribute.defaultValue |
 #end
 #end
diff --git a/src/test/java/com/google/devtools/build/skydoc/testdata/attribute_defaults_test/golden.txt b/src/test/java/com/google/devtools/build/skydoc/testdata/attribute_defaults_test/golden.txt
new file mode 100644
index 0000000..2dce74d
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/skydoc/testdata/attribute_defaults_test/golden.txt
@@ -0,0 +1,72 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_rule"></a>
+
+## my_rule
+
+<pre>
+my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-a">a</a>, <a href="#my_rule-b">b</a>, <a href="#my_rule-c">c</a>, <a href="#my_rule-d">d</a>, <a href="#my_rule-e">e</a>, <a href="#my_rule-f">f</a>, <a href="#my_rule-g">g</a>, <a href="#my_rule-h">h</a>, <a href="#my_rule-i">i</a>, <a href="#my_rule-j">j</a>, <a href="#my_rule-k">k</a>, <a href="#my_rule-l">l</a>, <a href="#my_rule-m">m</a>, <a href="#my_rule-n">n</a>, <a href="#my_rule-o">o</a>, <a href="#my_rule-p">p</a>, <a href="#my_rule-q">q</a>, <a href="#my_rule-r">r</a>, <a href="#my_rule-s">s</a>, <a href="#my_rule-t">t</a>, <a href="#my_rule-u">u</a>, <a href="#my_rule-v">v</a>, <a href="#my_rule-w">w</a>)
+</pre>
+
+This is my rule. It does stuff.
+
+**ATTRIBUTES**
+
+
+| Name  | Description | Type | Mandatory | Default |
+| :-------------: | :-------------: | :-------------: | :-------------: | :-------------: |
+| name |  A unique name for this target.   | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |  |
+| a |  Some bool   | Boolean | optional | False |
+| b |  Some int   | Integer | optional | 2 |
+| c |  Some int_list   | List of integers | optional | [0, 1] |
+| d |  Some label   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | //foo:bar |
+| e |  Some label_keyed_string_dict   | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: Label -> String</a> | optional | {"//foo:bar": "hello", "//bar:baz": "goodbye"} |
+| f |  Some label_list   | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | ["//foo:bar", "//bar:baz"] |
+| g |  Some string   | String | optional | "" |
+| h |  Some string_dict   | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {"animal": "bunny", "color": "orange"} |
+| i |  Some string_list   | List of strings | optional | ["cat", "dog"] |
+| j |  Some string_list_dict   | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> List of strings</a> | optional | {"animal": ["cat", "bunny"], "color": ["blue", "orange"]} |
+| k |  Some bool   | Boolean | required |  |
+| l |  Some int   | Integer | required |  |
+| m |  Some int_list   | List of integers | required |  |
+| n |  Some label   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required |  |
+| o |  Some label_keyed_string_dict   | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: Label -> String</a> | required |  |
+| p |  Some label_list   | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | required |  |
+| q |  Some string   | String | required |  |
+| r |  Some string_dict   | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | required |  |
+| s |  Some string_list   | List of strings | required |  |
+| t |  Some string_list_dict   | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> List of strings</a> | required |  |
+| u |  -   | String | optional | "" |
+| v |  -   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
+| w |  -   | Integer | optional | 0 |
+
+
+<a name="#my_aspect"></a>
+
+## my_aspect
+
+<pre>
+my_aspect(<a href="#my_aspect-name">name</a>, <a href="#my_aspect-y">y</a>, <a href="#my_aspect-z">z</a>)
+</pre>
+
+This is my aspect. It does stuff.
+
+**ASPECT ATTRIBUTES**
+
+
+| Name | Type |
+| :-------------: | :-------------: |
+| deps| String |
+| attr_aspect| String |
+
+
+**ATTRIBUTES**
+
+
+| Name  | Description | Type | Mandatory | Default |
+| :-------------: | :-------------: | :-------------: | :-------------: | :-------------: |
+| name |  A unique name for this target.   | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |   |
+| y |  some string   | String | optional |  "why" |
+| z |  -   | String | required |   |
+
+
diff --git a/src/test/java/com/google/devtools/build/skydoc/testdata/attribute_defaults_test/input.bzl b/src/test/java/com/google/devtools/build/skydoc/testdata/attribute_defaults_test/input.bzl
new file mode 100644
index 0000000..fe891f6
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/skydoc/testdata/attribute_defaults_test/input.bzl
@@ -0,0 +1,57 @@
+"""A golden test to verify attribute default values."""
+
+def _my_rule_impl(ctx):
+    return []
+
+def _my_aspect_impl(target, ctx):
+    return []
+
+my_aspect = aspect(
+    implementation = _my_aspect_impl,
+    doc = "This is my aspect. It does stuff.",
+    attr_aspects = ["deps", "attr_aspect"],
+    attrs = {
+        "_x": attr.label(mandatory = True),
+        "y": attr.string(default = "why", doc = "some string"),
+        "z": attr.string(mandatory = True),
+    },
+)
+
+my_rule = rule(
+    implementation = _my_rule_impl,
+    doc = "This is my rule. It does stuff.",
+    attrs = {
+        "a": attr.bool(default = False, doc = "Some bool"),
+        "b": attr.int(default = 2, doc = "Some int"),
+        "c": attr.int_list(default = [0, 1], doc = "Some int_list"),
+        "d": attr.label(default = "//foo:bar", doc = "Some label"),
+        "e": attr.label_keyed_string_dict(
+            default = {"//foo:bar": "hello", "//bar:baz": "goodbye"},
+            doc = "Some label_keyed_string_dict",
+        ),
+        "f": attr.label_list(default = ["//foo:bar", "//bar:baz"], doc = "Some label_list"),
+        "g": attr.string(default = "", doc = "Some string"),
+        "h": attr.string_dict(
+            default = {"animal": "bunny", "color": "orange"},
+            doc = "Some string_dict",
+        ),
+        "i": attr.string_list(default = ["cat", "dog"], doc = "Some string_list"),
+        "j": attr.string_list_dict(
+            default = {"animal": ["cat", "bunny"], "color": ["blue", "orange"]},
+            doc = "Some string_list_dict",
+        ),
+        "k": attr.bool(mandatory = True, doc = "Some bool"),
+        "l": attr.int(mandatory = True, doc = "Some int"),
+        "m": attr.int_list(mandatory = True, doc = "Some int_list"),
+        "n": attr.label(mandatory = True, doc = "Some label"),
+        "o": attr.label_keyed_string_dict(mandatory = True, doc = "Some label_keyed_string_dict"),
+        "p": attr.label_list(mandatory = True, doc = "Some label_list"),
+        "q": attr.string(mandatory = True, doc = "Some string"),
+        "r": attr.string_dict(mandatory = True, doc = "Some string_dict"),
+        "s": attr.string_list(mandatory = True, doc = "Some string_list"),
+        "t": attr.string_list_dict(mandatory = True, doc = "Some string_list_dict"),
+        "u": attr.string(),
+        "v": attr.label(),
+        "w": attr.int()
+    },
+)
diff --git a/src/test/java/com/google/devtools/build/skydoc/testdata/proto_format_test/golden.raw b/src/test/java/com/google/devtools/build/skydoc/testdata/proto_format_test/golden.raw
index 3c7d256..d158834 100644
--- a/src/test/java/com/google/devtools/build/skydoc/testdata/proto_format_test/golden.raw
+++ b/src/test/java/com/google/devtools/build/skydoc/testdata/proto_format_test/golden.raw
@@ -1,9 +1,10 @@
 
-}
+‰
 
 my_exampleSmall example of rule.*
-nameA unique name for this target. +
-uselessThis argument will be ignored.•
+nameA unique name for this target. 7
+uselessThis argument will be ignored.2
+"ignoreme"•
 example$Stores information about an example. 
 fooA string representing foo 
 barA string representing bar 
diff --git a/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/golden.txt b/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/golden.txt
index ecbc516..77e173e 100644
--- a/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/golden.txt
+++ b/src/test/java/com/google/devtools/build/skydoc/testdata/pure_markdown_template_test/golden.txt
@@ -13,11 +13,11 @@
 **ATTRIBUTES**
 
 
-| Name  | Description | Type | Mandatory |
-| :-------------: | :-------------: | :-------------: | :-------------: |
-| name |  A unique name for this target.   | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |
-| first |  This is the first attribute   | String | optional |
-| second |  -   | String | optional |
+| Name  | Description | Type | Mandatory | Default |
+| :-------------: | :-------------: | :-------------: | :-------------: | :-------------: |
+| name |  A unique name for this target.   | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |  |
+| first |  This is the first attribute   | String | optional | "" |
+| second |  -   | String | optional | "2" |
 
 
 <a name="#ExampleProviderInfo"></a>
@@ -81,10 +81,10 @@
 **ATTRIBUTES**
 
 
-| Name  | Description | Type | Mandatory |
-| :-------------: | :-------------: | :-------------: | :-------------: |
-| name |  A unique name for this target.   | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |
-| first |  -   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required |
-| second |  This is the second attribute.   | String | optional |
+| Name  | Description | Type | Mandatory | Default |
+| :-------------: | :-------------: | :-------------: | :-------------: | :-------------: |
+| name |  A unique name for this target.   | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |   |
+| first |  -   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required |   |
+| second |  This is the second attribute.   | String | optional |  "" |