bazel packages: support float values in proto.encode

PiperOrigin-RevId: 338758654
diff --git a/src/main/java/com/google/devtools/build/lib/packages/StarlarkLibrary.java b/src/main/java/com/google/devtools/build/lib/packages/StarlarkLibrary.java
index 5865edb..13386a3 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/StarlarkLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/StarlarkLibrary.java
@@ -40,6 +40,7 @@
 import net.starlark.java.eval.NoneType;
 import net.starlark.java.eval.Sequence;
 import net.starlark.java.eval.Starlark;
+import net.starlark.java.eval.StarlarkFloat;
 import net.starlark.java.eval.StarlarkInt;
 import net.starlark.java.eval.StarlarkThread;
 import net.starlark.java.eval.StarlarkValue;
@@ -90,8 +91,8 @@
         name = "encode_text",
         doc =
             "Returns the struct argument's encoding as a text-format protocol message.\n"
-                + "The data structure must be recursively composed of strings, ints, or bools,or"
-                + " structs, sequences, and dicts of these types.\n"
+                + "The data structure must be recursively composed of strings, ints, floats, or"
+                + " bools, or structs, sequences, and dicts of these types.\n"
                 + "<p>A struct is converted to a message. Fields are emitted in name order.\n"
                 + "<p>A sequence (such as a list or tuple) is converted to a repeated field.\n"
                 + "Its elements must not be sequences or dicts.\n"
@@ -209,7 +210,7 @@
       }
 
       // Emits field (name, v) as a message field, or one element of a repeated field.
-      // v must be an int, string, bool, or ClassObject.
+      // v must be an int, float, string, bool, or ClassObject.
       private void fieldElement(String name, Object v) throws EvalException {
         if (v instanceof ClassObject) {
           emitLine(name, " {");
@@ -226,7 +227,7 @@
               s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n"),
               "\"");
 
-        } else if (v instanceof StarlarkInt || v instanceof Boolean) {
+        } else if (v instanceof StarlarkInt || v instanceof StarlarkFloat || v instanceof Boolean) {
           emitLine(name, ": ", v.toString());
 
         } else {
diff --git a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java
index 63893c9..dd9639a 100644
--- a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java
@@ -983,6 +983,12 @@
     checkTextMessage("struct(name=[]).to_proto()"); // empty lines
     checkTextMessage("struct(name=['a', 'b']).to_proto()", "name: \"a\"", "name: \"b\"");
     checkTextMessage("struct(name=123).to_proto()", "name: 123");
+    checkTextMessage(
+        "struct(a=1.2e34, b=float('nan'), c=float('-inf')).to_proto()",
+        "a: 1.2e+34",
+        "b: nan",
+        "c: -inf");
+    checkTextMessage("struct(name=123).to_proto()", "name: 123");
     checkTextMessage("struct(name=[1, 2, 3]).to_proto()", "name: 1", "name: 2", "name: 3");
     checkTextMessage("struct(a=struct(b='b')).to_proto()", "a {", "  b: \"b\"", "}");
     checkTextMessage(