runtime/protoiface: API adjustments

The following adjustments were made:
* The pragma.NoUnkeyedLiterals is moved to be the first field.
This is done to keep the options struct smaller. Even if the last
field is zero-length, Go GC implementation details forces the struct
to be padded at the end.
* Methods are documented as always treating AllowPartial as true.
* Added a support flag for UnmarshalOptions.DiscardUnknown.

Change-Id: I1f75d226542ab2bb0123d9cea143c7060df226d8
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/185998
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/proto/decode.go b/proto/decode.go
index 6c2b9b7..0b98366 100644
--- a/proto/decode.go
+++ b/proto/decode.go
@@ -18,6 +18,8 @@
 // Example usage:
 //   err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m)
 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 an error if there are any missing required fields.
@@ -31,8 +33,6 @@
 	Resolver interface {
 		protoregistry.ExtensionTypeResolver
 	}
-
-	pragma.NoUnkeyedLiterals
 }
 
 var _ = protoiface.UnmarshalOptions(UnmarshalOptions{})
@@ -60,7 +60,8 @@
 }
 
 func (o UnmarshalOptions) unmarshalMessage(b []byte, m protoreflect.Message) error {
-	if methods := protoMethods(m); methods != nil && methods.Unmarshal != nil {
+	if methods := protoMethods(m); methods != nil && methods.Unmarshal != nil &&
+		!(o.DiscardUnknown && methods.Flags&protoiface.SupportUnmarshalDiscardUnknown == 0) {
 		return methods.Unmarshal(b, m, protoiface.UnmarshalOptions(o))
 	}
 	return o.unmarshalMessageSlow(b, m)