Skip to content

Commit 90e6e6f

Browse files
committed
fix nullable struct deserializer
1 parent e1a39c8 commit 90e6e6f

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

generator/java.stoneg.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -1068,10 +1068,14 @@ def java_serializer(self, data_type):
10681068
return self.fmt('%s.INSTANCE', serializer_class)
10691069
else:
10701070
serializers_class = JavaClass('com.dropbox.core.stone.StoneSerializers')
1071-
if is_nullable_type(data_type):
1071+
if is_nullable_type(data_type) and is_struct_type(data_type.data_type):
1072+
return self.fmt('%s.nullableStruct(%s)',
1073+
serializers_class, self.java_serializer(data_type.data_type))
1074+
elif is_nullable_type(data_type):
10721075
return self.fmt('%s.nullable(%s)',
10731076
serializers_class, self.java_serializer(data_type.data_type))
10741077
elif is_list_type(data_type):
1078+
# TODO: also support passing collapsed to list serializer
10751079
return self.fmt('%s.list(%s)',
10761080
serializers_class, self.java_serializer(data_type.data_type))
10771081
else:
@@ -3889,7 +3893,7 @@ def generate_union_serialize(self, data_type):
38893893
w.out('writeTag("%s", g);', field.name)
38903894
serializer = w.java_serializer(field.data_type)
38913895
value = 'value.%s' % j.param_name(field)
3892-
if j.is_collapsible(field.data_type):
3896+
if j.is_collapsible(field.data_type) or is_nullable_type(field.data_type) and j.is_collapsible(field.data_type.data_type):
38933897
w.out('%s.serialize(%s, g, true);', serializer, value)
38943898
else:
38953899
w.out('g.writeFieldName("%s");', field.name)
@@ -3940,7 +3944,7 @@ def generate_union_deserialize(self, data_type):
39403944
w.out('%s fieldValue = null;', j.java_class(field_dt, boxed=True, generics=True))
39413945
with w.conditional_block(is_nullable_type(field.data_type), 'if (p.getCurrentToken() != JsonToken.END_OBJECT)'):
39423946
field_serializer = w.java_serializer(field_dt)
3943-
if j.is_collapsible(field_dt):
3947+
if j.is_collapsible(field_dt) or is_nullable_type(field_dt) and j.is_collapsible(field_dt.data_type):
39443948
w.out('fieldValue = %s.deserialize(p, true);', field_serializer)
39453949
else:
39463950
w.out('expectField("%s", p);', field.name)

src/main/java/com/dropbox/core/stone/StoneSerializers.java

+50
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ public static <T> StoneSerializer<T> nullable(StoneSerializer<T> underlying) {
6262
return new NullableSerializer<T>(underlying);
6363
}
6464

65+
public static <T> StructSerializer<T> nullableStruct(StructSerializer<T> underlying) {
66+
return new NullableStructSerializer<T>(underlying);
67+
}
68+
6569
public static <T> StoneSerializer<List<T>> list(StoneSerializer<T> underlying) {
6670
return new ListSerializer<T>(underlying);
6771
}
@@ -241,6 +245,52 @@ public T deserialize(JsonParser p) throws IOException, JsonParseException {
241245
}
242246
}
243247

248+
private static final class NullableStructSerializer<T> extends StructSerializer<T> {
249+
private final StructSerializer<T> underlying;
250+
251+
public NullableStructSerializer(StructSerializer<T> underlying) {
252+
this.underlying = underlying;
253+
}
254+
255+
@Override
256+
public void serialize(T value, JsonGenerator g) throws IOException {
257+
if (value == null) {
258+
g.writeNull();
259+
} else {
260+
underlying.serialize(value, g);
261+
}
262+
}
263+
264+
@Override
265+
public void serialize(T value, JsonGenerator g, boolean collapsed) throws IOException {
266+
if (value == null) {
267+
g.writeNull();
268+
} else {
269+
underlying.serialize(value, g, collapsed);
270+
}
271+
}
272+
273+
@Override
274+
public T deserialize(JsonParser p) throws IOException {
275+
if (p.getCurrentToken() == JsonToken.VALUE_NULL) {
276+
p.nextToken();
277+
return null;
278+
} else {
279+
return underlying.deserialize(p);
280+
}
281+
}
282+
283+
@Override
284+
public T deserialize(JsonParser p, boolean collapsed) throws IOException {
285+
if (p.getCurrentToken() == JsonToken.VALUE_NULL) {
286+
p.nextToken();
287+
return null;
288+
} else {
289+
return underlying.deserialize(p, collapsed);
290+
}
291+
}
292+
}
293+
244294
private static final class ListSerializer<T> extends StoneSerializer<List<T>> {
245295
private final StoneSerializer<T> underlying;
246296

0 commit comments

Comments
 (0)