encoding/protojson: allow missing value for Any of type Empty

Some other implementations do not send the value field when encoding
an Any representing a message of the Empty Well-Known-Type.

Fixes golang/protobuf#1620

Change-Id: I89bffd5f92656ba3ac462c0b6365ed4b49e6189d
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/618395
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Stapelberg <stapelberg@google.com>
diff --git a/encoding/protojson/decode_test.go b/encoding/protojson/decode_test.go
index faf5eb5..053d269 100644
--- a/encoding/protojson/decode_test.go
+++ b/encoding/protojson/decode_test.go
@@ -2203,7 +2203,9 @@
 		inputText: `{
   "@type": "type.googleapis.com/google.protobuf.Empty"
 }`,
-		wantErr: `(line 3:1): missing "value" field`,
+		wantMessage: &anypb.Any{
+			TypeUrl: "type.googleapis.com/google.protobuf.Empty",
+		},
 	}, {
 		desc:         "Any with StringValue containing invalid UTF8",
 		inputMessage: &anypb.Any{},
diff --git a/encoding/protojson/well_known_types.go b/encoding/protojson/well_known_types.go
index 4b177c8..e9fe103 100644
--- a/encoding/protojson/well_known_types.go
+++ b/encoding/protojson/well_known_types.go
@@ -348,7 +348,11 @@
 		switch tok.Kind() {
 		case json.ObjectClose:
 			if !found {
-				return d.newError(tok.Pos(), `missing "value" field`)
+				// We tolerate an omitted `value` field with the google.protobuf.Empty Well-Known-Type,
+				// for compatibility with other proto runtimes that have interpreted the spec differently.
+				if m.Descriptor().FullName() != genid.Empty_message_fullname {
+					return d.newError(tok.Pos(), `missing "value" field`)
+				}
 			}
 			return nil