encoding/textpb: add AllowPartial option to MarshalOptions and UnmarshalOptions

Provide AllowPartial option to accept messages with missing required
field during marshaling and unmarshaling.

Change-Id: Ia23783870a8125633f8ddc0b686984b4c5ca15ba
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/169500
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/encoding/textpb/encode.go b/encoding/textpb/encode.go
index 93eab31..d94f771 100644
--- a/encoding/textpb/encode.go
+++ b/encoding/textpb/encode.go
@@ -18,7 +18,6 @@
 )
 
 // Marshal writes the given proto.Message in textproto format using default options.
-// TODO: may want to describe when Marshal returns error.
 func Marshal(m proto.Message) ([]byte, error) {
 	return MarshalOptions{}.Marshal(m)
 }
@@ -27,6 +26,11 @@
 type MarshalOptions struct {
 	pragma.NoUnkeyedLiterals
 
+	// AllowPartial allows messages that have missing required fields to marshal
+	// without returning an error. If AllowPartial is false (the default),
+	// Marshal will return error if there are any missing required fields.
+	AllowPartial bool
+
 	// If Indent is a non-empty string, it causes entries for a Message to be
 	// preceded by the indent and trailed by a newline. Indent can only be
 	// composed of space or tab characters.
@@ -85,7 +89,7 @@
 		num := fd.Number()
 
 		if !knownFields.Has(num) {
-			if fd.Cardinality() == pref.Required {
+			if !o.AllowPartial && fd.Cardinality() == pref.Required {
 				// Treat unset required fields as a non-fatal error.
 				nerr.AppendRequiredNotSet(string(fd.FullName()))
 			}