aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/packages
diff options
context:
space:
mode:
authorGravatar Taras Tsugrii <ttsugrii@fb.com>2018-07-25 13:58:02 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-07-25 13:59:42 -0700
commit7fe7047e6e6aec82f78cca366f0604dd606a5e7e (patch)
tree72b158530314b509a9637ba33af1dfa124085e19 /src/main/java/com/google/devtools/build/lib/packages
parent59a0b3f7c9d69b7be3be23ee57a8c058130ac9e8 (diff)
[Skylark] Support dictionaries in structs when serializing them using struct.to_json.
Dictionaries are frequently used for generic configuration descriptions especially given that `struct` is not allowed in build files. In order to be JSON-compatible, only dictionaries with string keys are allowed. Technically Python also allows integers and booleans by automatically converting them to strings, but this is confusing and not necessarily a good thing to do. Fixes #5542 Closes #5543. PiperOrigin-RevId: 206049754
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/packages')
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/Info.java34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Info.java b/src/main/java/com/google/devtools/build/lib/packages/Info.java
index 775b8e0a80..4bc863bafd 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Info.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Info.java
@@ -30,6 +30,7 @@ import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.EvalUtils;
import com.google.devtools.build.lib.syntax.Printer;
import com.google.devtools.build.lib.syntax.Runtime;
+import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkType;
import com.google.protobuf.TextFormat;
@@ -218,8 +219,8 @@ public abstract class Info implements ClassObject, StructApi, Serializable {
return sb.toString();
}
- private void printProtoTextMessage(
- ClassObject object, StringBuilder sb, int indent, Location loc) throws EvalException {
+ private void printProtoTextMessage(ClassObject object, StringBuilder sb, int indent, Location loc)
+ throws EvalException {
// For determinism sort the fields alphabetically.
List<String> fields = new ArrayList<>(object.getFieldNames());
Collections.sort(fields);
@@ -260,8 +261,7 @@ public abstract class Info implements ClassObject, StructApi, Serializable {
}
private void printProtoTextMessage(
- String key, Object value, StringBuilder sb, int indent, Location loc)
- throws EvalException {
+ String key, Object value, StringBuilder sb, int indent, Location loc) throws EvalException {
if (value instanceof SkylarkList) {
for (Object item : ((SkylarkList) value)) {
// TODO(bazel-team): There should be some constraint on the fields of the structs
@@ -297,8 +297,7 @@ public abstract class Info implements ClassObject, StructApi, Serializable {
return sb.toString();
}
- private void printJson(
- Object value, StringBuilder sb, Location loc, String container, String key)
+ private void printJson(Object value, StringBuilder sb, Location loc, String container, String key)
throws EvalException {
if (value == Runtime.NONE) {
sb.append("null");
@@ -315,6 +314,29 @@ public abstract class Info implements ClassObject, StructApi, Serializable {
printJson(((ClassObject) value).getValue(field), sb, loc, "struct field", field);
}
sb.append("}");
+ } else if (value instanceof SkylarkDict) {
+ sb.append("{");
+ String join = "";
+ for (Map.Entry<?, ?> entry : ((SkylarkDict<?, ?>) value).entrySet()) {
+ sb.append(join);
+ join = ",";
+ if (!(entry.getKey() instanceof String)) {
+ String errorMessage =
+ "Keys must be a string but got a "
+ + EvalUtils.getDataTypeName(entry.getKey())
+ + " for "
+ + container;
+ if (key != null) {
+ errorMessage += " '" + key + "'";
+ }
+ throw new EvalException(loc, errorMessage);
+ }
+ sb.append("\"");
+ sb.append(entry.getKey());
+ sb.append("\":");
+ printJson(entry.getValue(), sb, loc, "dict value", String.valueOf(entry.getKey()));
+ }
+ sb.append("}");
} else if (value instanceof List) {
sb.append("[");
String join = "";