encoding/jsonpb: fix unmarshaling of NullValue field

A JSON "null" field should set the NullValue enum field because
NullValue has the custom encoding format of "null".

Change-Id: I2bfa0900de64d7e2874f7c6db04b1cbc0b61b904
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/170107
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/encoding/jsonpb/decode.go b/encoding/jsonpb/decode.go
index 8511a8d..7655054 100644
--- a/encoding/jsonpb/decode.go
+++ b/encoding/jsonpb/decode.go
@@ -225,8 +225,8 @@
 		seenNums.Set(num)
 
 		// No need to set values for JSON null unless the field type is
-		// google.protobuf.Value.
-		if o.decoder.Peek() == json.Null && !isKnownValue(fd) {
+		// google.protobuf.Value or google.protobuf.NullValue.
+		if o.decoder.Peek() == json.Null && !isKnownValue(fd) && !isNullValue(fd) {
 			o.decoder.Read()
 			continue
 		}
@@ -277,6 +277,16 @@
 	return nil, protoregistry.NotFound
 }
 
+func isKnownValue(fd pref.FieldDescriptor) bool {
+	md := fd.MessageType()
+	return md != nil && md.FullName() == "google.protobuf.Value"
+}
+
+func isNullValue(fd pref.FieldDescriptor) bool {
+	ed := fd.EnumType()
+	return ed != nil && ed.FullName() == "google.protobuf.NullValue"
+}
+
 // unmarshalSingular unmarshals to the non-repeated field specified by the given
 // FieldDescriptor.
 func (o UnmarshalOptions) unmarshalSingular(knownFields pref.KnownFields, fd pref.FieldDescriptor) error {
@@ -509,6 +519,12 @@
 			return pref.Value{}, err
 		}
 		return pref.ValueOf(pref.EnumNumber(n)), nil
+
+	case json.Null:
+		// This is only valid for google.protobuf.NullValue.
+		if isNullValue(fd) {
+			return pref.ValueOf(pref.EnumNumber(0)), nil
+		}
 	}
 
 	return pref.Value{}, unexpectedJSONError{jval}