Refactor FunctionParamInfo into a proto.

PiperOrigin-RevId: 251708686
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/FunctionParamInfo.java b/src/main/java/com/google/devtools/build/skydoc/rendering/FunctionParamInfo.java
deleted file mode 100644
index 81dafe9..0000000
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/FunctionParamInfo.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2018 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.skydoc.rendering;
-
-import com.google.devtools.build.lib.syntax.Printer;
-import com.google.devtools.build.lib.syntax.Printer.BasePrinter;
-import javax.annotation.Nullable;
-
-/** Stores information about a function parameter definition. */
-public class FunctionParamInfo {
-
-  private final String name;
-  private final String docString;
-  @Nullable private final Object defaultValue;
-  private final boolean mandatory;
-
-  private FunctionParamInfo(
-      String name, String docString, @Nullable Object defaultValue, boolean mandatory) {
-    this.name = name;
-    this.docString = docString;
-    this.defaultValue = defaultValue;
-    this.mandatory = mandatory;
-  }
-
-  /** Constructor to be used for normal parameters. */
-  public static FunctionParamInfo forParam(
-      String name, String docString, @Nullable Object defaultValue) {
-    return new FunctionParamInfo(name, docString, defaultValue, defaultValue == null);
-  }
-
-  /** Constructor to be used for *args or **kwargs. */
-  public static FunctionParamInfo forSpecialParam(String name, String docString) {
-    return new FunctionParamInfo(name, docString, null, false);
-  }
-
-  /**
-   * Return the name of this parameter (for example, in 'def foo(bar):', the only parameter is
-   * named 'bar'.
-   */
-  public String getName() {
-    return name;
-  }
-
-  /**
-   * Return the documented description of this parameter (if specified in the function's docstring).
-   */
-  public String getDocString() {
-    return docString;
-  }
-
-  /**
-   * Returns true if this function has a default value and the default value can be displayed
-   * as a string.
-   */
-  public boolean hasDefaultValueString() {
-    return defaultValue != null && !getDefaultString().isEmpty();
-  }
-
-  /**
-   * Returns a string representing the default value this function parameter.
-   *
-   * @throws IllegalStateException if there is no default value of this function parameter;
-   *     invoke {@link #hasDefaultValueString()} first to check whether there is a default
-   *     parameter
-   */
-  public String getDefaultString() {
-    if (defaultValue == null) {
-      return "";
-    }
-    BasePrinter printer = Printer.getSimplifiedPrinter();
-    printer.repr(defaultValue);
-    return printer.toString();
-  }
-
-  /**
-   * Returns 'required' if this parameter is mandatory, otherwise returns 'optional'.
-   */
-  public String getMandatoryString() {
-    return mandatory ? "required" : "optional";
-  }
-}
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 ff13751..f902e01 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
@@ -17,6 +17,7 @@
 import com.google.common.base.Joiner;
 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 java.util.List;
 import java.util.stream.Collectors;
 
@@ -112,6 +113,14 @@
     return attrInfo.getMandatory() ? "required" : "optional";
   }
 
+  /**
+   * Returns "required" if providing a value for this parameter is mandatory. Otherwise, returns
+   * "optional".
+   */
+  public String mandatoryString(FunctionParamInfo paramInfo) {
+    return paramInfo.getMandatory() ? "required" : "optional";
+  }
+
   private String attributeTypeDescription(AttributeType attributeType) {
     switch (attributeType) {
       case NAME:
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/UserDefinedFunctionInfo.java b/src/main/java/com/google/devtools/build/skydoc/rendering/UserDefinedFunctionInfo.java
index afe3f3e..2e7c9df 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/UserDefinedFunctionInfo.java
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/UserDefinedFunctionInfo.java
@@ -19,9 +19,12 @@
 import com.google.common.collect.Maps;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.syntax.FunctionSignature;
+import com.google.devtools.build.lib.syntax.Printer;
+import com.google.devtools.build.lib.syntax.Printer.BasePrinter;
 import com.google.devtools.build.lib.syntax.SkylarkType;
 import com.google.devtools.build.lib.syntax.StringLiteral;
 import com.google.devtools.build.lib.syntax.UserDefinedFunction;
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.FunctionParamInfo;
 import com.google.devtools.skylark.common.DocstringUtils;
 import com.google.devtools.skylark.common.DocstringUtils.DocstringInfo;
 import com.google.devtools.skylark.common.DocstringUtils.DocstringParseError;
@@ -29,6 +32,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import javax.annotation.Nullable;
 
 /** Encapsulates information about a user-defined Starlark function. */
 public class UserDefinedFunctionInfo {
@@ -108,6 +112,35 @@
         functionDescription);
   }
 
+  /** Constructor to be used for normal parameters. */
+  public static FunctionParamInfo forParam(
+      String name, String docString, @Nullable Object defaultValue) {
+    FunctionParamInfo.Builder paramBuilder =
+        FunctionParamInfo.newBuilder().setName(name).setDocString(docString);
+    if (defaultValue == null) {
+      paramBuilder.setMandatory(true);
+    } else {
+      BasePrinter printer = Printer.getSimplifiedPrinter();
+      printer.repr(defaultValue);
+      String defaultValueString = printer.toString();
+
+      if (defaultValueString.isEmpty()) {
+        defaultValueString = "{unknown object}";
+      }
+      paramBuilder.setDefaultValue(defaultValueString).setMandatory(false);
+    }
+    return paramBuilder.build();
+  }
+
+  /** Constructor to be used for *args or **kwargs. */
+  public static FunctionParamInfo forSpecialParam(String name, String docString) {
+    return FunctionParamInfo.newBuilder()
+        .setName(name)
+        .setDocString(docString)
+        .setMandatory(false)
+        .build();
+  }
+
   private static List<FunctionParamInfo> parameterInfos(
       UserDefinedFunction userDefinedFunction,
       Map<String, String> paramNameToDocMap)  {
@@ -126,7 +159,7 @@
     for (paramIndex = 0; paramIndex < numMandatoryParams; paramIndex++) {
       String paramName = paramNames.get(paramIndex);
       String paramDoc = paramNameToDocMap.getOrDefault(paramName, "");
-      parameterInfos.add(FunctionParamInfo.forParam(paramName, paramDoc, /*default param*/ null));
+      parameterInfos.add(forParam(paramName, paramDoc, /*default param*/ null));
     }
 
     // Parameters with defaults.
@@ -138,7 +171,7 @@
         if (paramNameToDocMap.containsKey(paramName)) {
           paramDoc = paramNameToDocMap.get(paramName);
         }
-        parameterInfos.add(FunctionParamInfo.forParam(paramName, paramDoc, defaultParamValue));
+        parameterInfos.add(forParam(paramName, paramDoc, defaultParamValue));
         paramIndex++;
       }
     }
@@ -152,7 +185,7 @@
       } else if (paramNameToDocMap.containsKey("*" + paramName)) {
         paramDoc = paramNameToDocMap.get("*" + paramName);
       }
-      parameterInfos.add(FunctionParamInfo.forSpecialParam(paramName, paramDoc));
+      parameterInfos.add(forSpecialParam(paramName, paramDoc));
       paramIndex++;
     }
 
@@ -165,7 +198,7 @@
       } else if (paramNameToDocMap.containsKey("**" + paramName)) {
         paramDoc = paramNameToDocMap.get("**" + paramName);
       }
-      parameterInfos.add(FunctionParamInfo.forSpecialParam(paramName, paramDoc));
+      parameterInfos.add(forSpecialParam(paramName, paramDoc));
       paramIndex++;
     }
     return parameterInfos.build();
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 004d3b9..4b35a1e 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
@@ -64,3 +64,22 @@
   // If true, all targets of the rule must specify a value for this attribute.
   bool mandatory = 4;
 }
+
+// Representation of a Starlark function parameter definition.
+message FunctionParamInfo {
+  // The name of the parameter.
+  string name = 1;
+
+  // The documented description of the parameter (if specified in the function's
+  // docstring).
+  string doc_string = 2;
+
+  // If not an empty string, the default value of the parameter displayed
+  // as a string.
+  string default_value = 3;
+
+  // If true, the default value is unset and a value is needed for this
+  // parameter. This might be false even if defaultValue is empty in the case of
+  // special parameter such as *args and **kwargs"
+  bool mandatory = 4;
+}
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/templates/func.vm b/src/main/java/com/google/devtools/build/skydoc/rendering/templates/func.vm
index 17ac789..3046495 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/templates/func.vm
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/templates/func.vm
@@ -21,11 +21,11 @@
     <tr id="${funcInfo.name}-${param.name}">
       <td><code>${param.name}</code></td>
       <td>
-        ${param.mandatoryString}.#if($param.hasDefaultValueString()) default is <code>${param.defaultString}</code>#end
+        ${util.mandatoryString($param)}.#if(!$param.getDefaultValue().isEmpty()) default is <code>$param.getDefaultValue()</code>#end
 
 #if (!$param.docString.isEmpty())
         <p>
-          ${param.docString}
+          ${param.docString.trim()}
         </p>
 #end
       </td>
diff --git a/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/golden.txt b/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/golden.txt
index bdb8c4c..8b0ad83 100644
--- a/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/golden.txt
+++ b/src/test/java/com/google/devtools/build/skydoc/testdata/function_basic_test/golden.txt
@@ -79,7 +79,7 @@
     <tr id="check_sources-struct_param">
       <td><code>struct_param</code></td>
       <td>
-        optional.
+        optional. default is <code>{unknown object}</code>
       </td>
     </tr>
   </tbody>