encoding/jsonpb: add unmarshal option to ignore unknown fields

This feature seems to be used quite a bit, and the conformance tests
treat this as required, perhaps as a "required option" since the
developer guide states:

"Proto3 JSON parser should reject unknown fields by default but may
provide an option to ignore unknown fields in parsing."

Also, all invalid UTF-8 errors in skipped values are also returned as it
is similar to a parse error, except it is a non-fatal one.

Change-Id: Ia26e9a355daecdbf99af23f3061353fffa32d47d
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/174017
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/encoding/jsonpb/decode.go b/encoding/jsonpb/decode.go
index 4b0d9bb..0a08e4f 100644
--- a/encoding/jsonpb/decode.go
+++ b/encoding/jsonpb/decode.go
@@ -29,11 +29,13 @@
 type UnmarshalOptions struct {
 	pragma.NoUnkeyedLiterals
 
-	// AllowPartial accepts input for messages that will result in missing
-	// required fields. If AllowPartial is false (the default), Unmarshal will
-	// return error if there are any missing required fields.
+	// If AllowPartial is set, input for messages that will result in missing
+	// required fields will not return an error.
 	AllowPartial bool
 
+	// If DiscardUnknown is set, unknown fields are ignored.
+	DiscardUnknown bool
+
 	// Resolver is the registry used for type lookups when unmarshaling extensions
 	// and processing Any. If Resolver is not set, unmarshaling will default to
 	// using protoregistry.GlobalTypes.
@@ -217,7 +219,12 @@
 
 		if fd == nil {
 			// Field is unknown.
-			// TODO: Provide option to ignore unknown message fields.
+			if o.DiscardUnknown {
+				if err := skipJSONValue(o.decoder); !nerr.Merge(err) {
+					return err
+				}
+				continue
+			}
 			return newError("%v contains unknown field %s", msgType.FullName(), jval)
 		}