Refactor RuleInfo into a proto.

PiperOrigin-RevId: 252468961
diff --git a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
index f794be5..b14030b 100644
--- a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
+++ b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
@@ -106,7 +106,8 @@
 import com.google.devtools.build.skydoc.rendering.FunctionUtil;
 import com.google.devtools.build.skydoc.rendering.MarkdownRenderer;
 import com.google.devtools.build.skydoc.rendering.ProviderInfo;
-import com.google.devtools.build.skydoc.rendering.RuleInfo;
+import com.google.devtools.build.skydoc.rendering.RuleInfoWrapper;
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.UserDefinedFunctionInfo;
 import com.google.devtools.common.options.OptionsParser;
 import java.io.IOException;
@@ -346,13 +347,14 @@
       throws InterruptedException, IOException, LabelSyntaxException, EvalException,
           StarlarkEvaluationException {
 
-    List<RuleInfo> ruleInfoList = new ArrayList<>();
+    List<RuleInfoWrapper> ruleInfoList = new ArrayList<>();
     List<ProviderInfo> providerInfoList = new ArrayList<>();
     Environment env = recursiveEval(semantics, label, ruleInfoList, providerInfoList);
 
-    Map<BaseFunction, RuleInfo> ruleFunctions =
+    Map<BaseFunction, RuleInfoWrapper> ruleFunctions =
         ruleInfoList.stream()
-            .collect(Collectors.toMap(RuleInfo::getIdentifierFunction, Functions.identity()));
+            .collect(
+                Collectors.toMap(RuleInfoWrapper::getIdentifierFunction, Functions.identity()));
     Map<BaseFunction, ProviderInfo> providerInfos =
         providerInfoList.stream()
             .collect(Collectors.toMap(ProviderInfo::getIdentifier, Functions.identity()));
@@ -362,7 +364,7 @@
 
     for (Entry<String, Object> envEntry : sortedBindings.entrySet()) {
       if (ruleFunctions.containsKey(envEntry.getValue())) {
-        RuleInfo ruleInfo = ruleFunctions.get(envEntry.getValue());
+        RuleInfo ruleInfo = ruleFunctions.get(envEntry.getValue()).getRuleInfo();
         ruleInfoMap.put(envEntry.getKey(), ruleInfo);
       }
       if (providerInfos.containsKey(envEntry.getValue())) {
@@ -400,7 +402,7 @@
   private Environment recursiveEval(
       StarlarkSemantics semantics,
       Label label,
-      List<RuleInfo> ruleInfoList,
+      List<RuleInfoWrapper> ruleInfoList,
       List<ProviderInfo> providerInfoList)
       throws InterruptedException, IOException, LabelSyntaxException, StarlarkEvaluationException {
     Path path = pathOfLabel(label);
@@ -468,7 +470,7 @@
       StarlarkSemantics semantics,
       BuildFileAST buildFileAST,
       Map<String, Extension> imports,
-      List<RuleInfo> ruleInfoList,
+      List<RuleInfoWrapper> ruleInfoList,
       List<ProviderInfo> providerInfoList)
       throws InterruptedException, StarlarkEvaluationException {
 
@@ -494,7 +496,7 @@
    *     invocation information will be added
    */
   private static GlobalFrame globalFrame(
-      List<RuleInfo> ruleInfoList, List<ProviderInfo> providerInfoList) {
+      List<RuleInfoWrapper> ruleInfoList, List<ProviderInfo> providerInfoList) {
     TopLevelBootstrap topLevelBootstrap =
         new TopLevelBootstrap(
             new FakeBuildApiGlobals(),
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 96d6c4d..1a3e9fc 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
@@ -34,10 +34,11 @@
 import com.google.devtools.build.lib.syntax.SkylarkList;
 import com.google.devtools.build.lib.syntax.SkylarkType;
 import com.google.devtools.build.skydoc.rendering.ProviderInfo;
-import com.google.devtools.build.skydoc.rendering.RuleInfo;
+import com.google.devtools.build.skydoc.rendering.RuleInfoWrapper;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeInfo;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeType;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ProviderFieldInfo;
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
@@ -54,7 +55,7 @@
 
   private static final FakeDescriptor IMPLICIT_NAME_ATTRIBUTE_DESCRIPTOR =
       new FakeDescriptor(AttributeType.NAME, "A unique name for this target.", true);
-  private final List<RuleInfo> ruleInfoList;
+  private final List<RuleInfoWrapper> ruleInfoList;
   private final List<ProviderInfo> providerInfoList;
 
   /**
@@ -62,11 +63,11 @@
    *
    * @param ruleInfoList the list of {@link RuleInfo} objects to which rule() invocation information
    *     will be added
-   * @param providerInfoList the list of {@link ProviderInfo} objects to which provider()
-   *     invocation information will be added
+   * @param providerInfoList the list of {@link ProviderInfo} objects to which provider() invocation
+   *     information will be added
    */
-  public FakeSkylarkRuleFunctionsApi(List<RuleInfo> ruleInfoList,
-      List<ProviderInfo> providerInfoList) {
+  public FakeSkylarkRuleFunctionsApi(
+      List<RuleInfoWrapper> ruleInfoList, List<ProviderInfo> providerInfoList) {
     this.ruleInfoList = ruleInfoList;
     this.providerInfoList = providerInfoList;
   }
@@ -146,7 +147,10 @@
 
     RuleDefinitionIdentifier functionIdentifier = new RuleDefinitionIdentifier();
 
-    ruleInfoList.add(new RuleInfo(functionIdentifier, ast.getLocation(), doc, attrInfos));
+    RuleInfo ruleInfo = RuleInfo.newBuilder().setDocString(doc).addAllAttributes(attrInfos).build();
+
+    ruleInfoList.add(new RuleInfoWrapper(functionIdentifier, ast.getLocation(), ruleInfo));
+
     return functionIdentifier;
   }
 
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 d09d4db..c3b257b 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
@@ -25,9 +25,10 @@
 import com.google.devtools.build.lib.syntax.SkylarkList;
 import com.google.devtools.build.skydoc.fakebuildapi.FakeDescriptor;
 import com.google.devtools.build.skydoc.fakebuildapi.FakeSkylarkRuleFunctionsApi.AttributeNameComparator;
-import com.google.devtools.build.skydoc.rendering.RuleInfo;
+import com.google.devtools.build.skydoc.rendering.RuleInfoWrapper;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeInfo;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeType;
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
 import java.util.List;
 import java.util.stream.Collectors;
 import javax.annotation.Nullable;
@@ -39,9 +40,9 @@
   private static final FakeDescriptor IMPLICIT_NAME_ATTRIBUTE_DESCRIPTOR =
       new FakeDescriptor(AttributeType.NAME, "A unique name for this repository.", true);
 
-  private final List<RuleInfo> ruleInfoList;
+  private final List<RuleInfoWrapper> ruleInfoList;
 
-  public FakeRepositoryModule(List<RuleInfo> ruleInfoList) {
+  public FakeRepositoryModule(List<RuleInfoWrapper> ruleInfoList) {
     this.ruleInfoList = ruleInfoList;
   }
 
@@ -73,7 +74,9 @@
     RepositoryRuleDefinitionIdentifier functionIdentifier =
         new RepositoryRuleDefinitionIdentifier();
 
-    ruleInfoList.add(new RuleInfo(functionIdentifier, ast.getLocation(), doc, attrInfos));
+    RuleInfo ruleInfo = RuleInfo.newBuilder().setDocString(doc).addAllAttributes(attrInfos).build();
+
+    ruleInfoList.add(new RuleInfoWrapper(functionIdentifier, ast.getLocation(), ruleInfo));
     return functionIdentifier;
   }
 
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java
index 96dc91c..f6fd3ef 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.skydoc.rendering;
 
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.UserDefinedFunctionInfo;
 import java.io.IOException;
 import java.io.StringWriter;
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownUtil.java b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownUtil.java
index 3e9010f..251b78d 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownUtil.java
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownUtil.java
@@ -18,6 +18,7 @@
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeInfo;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeType;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.FunctionParamInfo;
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.UserDefinedFunctionInfo;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -35,9 +36,10 @@
    */
   @SuppressWarnings("unused") // Used by markdown template.
   public String ruleSummary(String ruleName, RuleInfo ruleInfo) {
-    List<String> attributeNames = ruleInfo.getAttributes().stream()
-        .map(attr -> attr.getName())
-        .collect(Collectors.toList());
+    List<String> attributeNames =
+        ruleInfo.getAttributesList().stream()
+            .map(attr -> attr.getName())
+            .collect(Collectors.toList());
     return summary(ruleName, attributeNames);
   }
 
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/RuleInfo.java b/src/main/java/com/google/devtools/build/skydoc/rendering/RuleInfoWrapper.java
similarity index 66%
rename from src/main/java/com/google/devtools/build/skydoc/rendering/RuleInfo.java
rename to src/main/java/com/google/devtools/build/skydoc/rendering/RuleInfoWrapper.java
index b1c795a..c371272 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/RuleInfo.java
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/RuleInfoWrapper.java
@@ -16,27 +16,19 @@
 
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.syntax.BaseFunction;
-import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeInfo;
-import java.util.Collection;
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
 
-/**
- * Stores information about a skylark rule definition.
- */
-public class RuleInfo {
+/** Stores information about a skylark rule definition. */
+public class RuleInfoWrapper {
 
   private final BaseFunction identifierFunction;
   private final Location location;
-  private final String docString;
-  private final Collection<AttributeInfo> attrInfos;
+  private final RuleInfo ruleInfo;
 
-  public RuleInfo(BaseFunction identifierFunction,
-      Location location,
-      String docString,
-      Collection<AttributeInfo> attrInfos) {
+  public RuleInfoWrapper(BaseFunction identifierFunction, Location location, RuleInfo ruleInfo) {
     this.identifierFunction = identifierFunction;
     this.location = location;
-    this.docString = docString;
-    this.attrInfos = attrInfos;
+    this.ruleInfo = ruleInfo;
   }
 
   public BaseFunction getIdentifierFunction() {
@@ -47,11 +39,7 @@
     return location;
   }
 
-  public String getDocString() {
-    return docString;
-  }
-
-  public Collection<AttributeInfo> getAttributes() {
-    return attrInfos;
+  public RuleInfo getRuleInfo() {
+    return ruleInfo;
   }
 }
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 65b9061..fa9d011 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
@@ -45,6 +45,15 @@
   OUTPUT_LIST = 13;
 }
 
+// Representation of a Starlark rule definition.
+message RuleInfo {
+  // The documentation string of the rule.
+  string doc_string = 1;
+
+  // The attributes of the rule.
+  repeated AttributeInfo attributes = 2;
+}
+
 // Representation of a Starlark rule attribute definition, comprised of an
 // attribute name, and a schema defined by a call to one of the 'attr' module
 // methods enumerated at
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/templates/rule.vm b/src/main/java/com/google/devtools/build/skydoc/rendering/templates/rule.vm
index d9ea3bf..6769aca 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/templates/rule.vm
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/templates/rule.vm
@@ -10,14 +10,14 @@
 
 #[[###]]# Attributes
 
-#if (!$ruleInfo.attributes.isEmpty())
+#if (!$ruleInfo.getAttributesList().isEmpty())
 <table class="params-table">
   <colgroup>
     <col class="col-param" />
     <col class="col-description" />
   </colgroup>
   <tbody>
-#foreach ($attribute in $ruleInfo.attributes)
+#foreach ($attribute in $ruleInfo.getAttributesList())
     <tr id="${ruleName}-${attribute.name}">
       <td><code>${attribute.name}</code></td>
       <td>