Skip to content

Commit af94003

Browse files
jsonpb: restore previous behavior for handling nulls and JSONPBUnmarshaler (#1300)
When a JSON null is encountered for a field which implements JSONPBUnmarshaler, jsonpb will now call the unmarshal method, instead of just skipping the field.
1 parent a36a1a1 commit af94003

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

jsonpb/decode.go

+18-8
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,14 @@ func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error
135135
md := m.Descriptor()
136136
fds := md.Fields()
137137

138-
if string(in) == "null" && md.FullName() != "google.protobuf.Value" {
139-
return nil
140-
}
141-
142138
if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok {
143139
return jsu.UnmarshalJSONPB(u, in)
144140
}
145141

142+
if string(in) == "null" && md.FullName() != "google.protobuf.Value" {
143+
return nil
144+
}
145+
146146
switch wellKnownType(md.FullName()) {
147147
case "Any":
148148
var jsonObject map[string]json.RawMessage
@@ -332,11 +332,12 @@ func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error
332332
raw = v
333333
}
334334

335+
field := m.NewField(fd)
335336
// Unmarshal the field value.
336-
if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd)) {
337+
if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
337338
continue
338339
}
339-
v, err := u.unmarshalValue(m.NewField(fd), raw, fd)
340+
v, err := u.unmarshalValue(field, raw, fd)
340341
if err != nil {
341342
return err
342343
}
@@ -364,11 +365,12 @@ func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error
364365
return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName())
365366
}
366367

368+
field := m.NewField(fd)
367369
// Unmarshal the field value.
368-
if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd)) {
370+
if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
369371
continue
370372
}
371-
v, err := u.unmarshalValue(m.NewField(fd), raw, fd)
373+
v, err := u.unmarshalValue(field, raw, fd)
372374
if err != nil {
373375
return err
374376
}
@@ -390,6 +392,14 @@ func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
390392
return false
391393
}
392394

395+
func isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.FieldDescriptor) bool {
396+
if fd.Message() != nil && fd.Cardinality() != protoreflect.Repeated {
397+
_, ok := proto.MessageV1(v.Interface()).(JSONPBUnmarshaler)
398+
return ok
399+
}
400+
return false
401+
}
402+
393403
func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
394404
switch {
395405
case fd.IsList():

jsonpb/json_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,7 @@ func TestUnmarshalNullWithJSONPBUnmarshaler(t *testing.T) {
10091009
t.Errorf("unmarshal error: %v", err)
10101010
}
10111011

1012-
want := ptrFieldMessage{}
1012+
want := ptrFieldMessage{StringField: &stringField{IsSet: true, StringValue: "null"}}
10131013
if !proto.Equal(&ptrFieldMsg, &want) {
10141014
t.Errorf("unmarshal result StringField: got %v, want %v", ptrFieldMsg, want)
10151015
}

0 commit comments

Comments
 (0)