Ver Fonte

all: remove non-fatal UTF-8 validation errors (and non-fatal in general)

Immediately abort (un)marshal operations when encountering invalid UTF-8
data in proto3 strings. No other proto implementation supports non-UTF-8
data in proto3 strings (and many reject it in proto2 strings as well).
Producing invalid output is an interoperability threat (other
implementations won't be able to read it).

The case where existing string data is found to contain non-UTF8 data is
better handled by changing the field to the `bytes` type, which (aside
from UTF-8 validation) is wire-compatible with `string`.

Remove the errors.NonFatal type, since there are no remaining cases
where it is needed. "Non-fatal" errors which produce results and a
non-nil error are problematic because they compose poorly; the better
approach is to take an option like AllowPartial indicating which
conditions to check for.

Change-Id: I9d189ec6ffda7b5d96d094aa1b290af2e3f23736
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/183098
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Damien Neil há 6 anos atrás
pai
commit
8c86fc5e7d

+ 36 - 48
encoding/protojson/decode.go

@@ -62,8 +62,7 @@ func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error {
 	}
 	}
 	o.decoder = json.NewDecoder(b)
 	o.decoder = json.NewDecoder(b)
 
 
-	var nerr errors.NonFatal
-	if err := o.unmarshalMessage(m.ProtoReflect(), false); !nerr.Merge(err) {
+	if err := o.unmarshalMessage(m.ProtoReflect(), false); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -76,10 +75,10 @@ func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error {
 		return unexpectedJSONError{val}
 		return unexpectedJSONError{val}
 	}
 	}
 
 
-	if !o.AllowPartial {
-		nerr.Merge(proto.IsInitialized(m))
+	if o.AllowPartial {
+		return nil
 	}
 	}
-	return nerr.E
+	return proto.IsInitialized(m)
 }
 }
 
 
 // unexpectedJSONError is an error that contains the unexpected json.Value. This
 // unexpectedJSONError is an error that contains the unexpected json.Value. This
@@ -116,30 +115,27 @@ func newError(f string, x ...interface{}) error {
 
 
 // unmarshalMessage unmarshals a message into the given protoreflect.Message.
 // unmarshalMessage unmarshals a message into the given protoreflect.Message.
 func (o UnmarshalOptions) unmarshalMessage(m pref.Message, skipTypeURL bool) error {
 func (o UnmarshalOptions) unmarshalMessage(m pref.Message, skipTypeURL bool) error {
-	var nerr errors.NonFatal
-
 	if isCustomType(m.Descriptor().FullName()) {
 	if isCustomType(m.Descriptor().FullName()) {
 		return o.unmarshalCustomType(m)
 		return o.unmarshalCustomType(m)
 	}
 	}
 
 
 	jval, err := o.decoder.Read()
 	jval, err := o.decoder.Read()
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 	if jval.Type() != json.StartObject {
 	if jval.Type() != json.StartObject {
 		return unexpectedJSONError{jval}
 		return unexpectedJSONError{jval}
 	}
 	}
 
 
-	if err := o.unmarshalFields(m, skipTypeURL); !nerr.Merge(err) {
+	if err := o.unmarshalFields(m, skipTypeURL); err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	return nerr.E
+	return nil
 }
 }
 
 
 // unmarshalFields unmarshals the fields into the given protoreflect.Message.
 // unmarshalFields unmarshals the fields into the given protoreflect.Message.
 func (o UnmarshalOptions) unmarshalFields(m pref.Message, skipTypeURL bool) error {
 func (o UnmarshalOptions) unmarshalFields(m pref.Message, skipTypeURL bool) error {
-	var nerr errors.NonFatal
 	var seenNums set.Ints
 	var seenNums set.Ints
 	var seenOneofs set.Ints
 	var seenOneofs set.Ints
 
 
@@ -150,7 +146,7 @@ Loop:
 	for {
 	for {
 		// Read field name.
 		// Read field name.
 		jval, err := o.decoder.Read()
 		jval, err := o.decoder.Read()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 		switch jval.Type() {
 		switch jval.Type() {
@@ -163,7 +159,7 @@ Loop:
 		}
 		}
 
 
 		name, err := jval.Name()
 		name, err := jval.Name()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 		// Unmarshaling a non-custom embedded message in Any will contain the
 		// Unmarshaling a non-custom embedded message in Any will contain the
@@ -195,7 +191,7 @@ Loop:
 		if fd == nil {
 		if fd == nil {
 			// Field is unknown.
 			// Field is unknown.
 			if o.DiscardUnknown {
 			if o.DiscardUnknown {
-				if err := skipJSONValue(o.decoder); !nerr.Merge(err) {
+				if err := skipJSONValue(o.decoder); err != nil {
 					return err
 					return err
 				}
 				}
 				continue
 				continue
@@ -220,12 +216,12 @@ Loop:
 		switch {
 		switch {
 		case fd.IsList():
 		case fd.IsList():
 			list := m.Mutable(fd).List()
 			list := m.Mutable(fd).List()
-			if err := o.unmarshalList(list, fd); !nerr.Merge(err) {
+			if err := o.unmarshalList(list, fd); err != nil {
 				return errors.New("%v|%q: %v", fd.FullName(), name, err)
 				return errors.New("%v|%q: %v", fd.FullName(), name, err)
 			}
 			}
 		case fd.IsMap():
 		case fd.IsMap():
 			mmap := m.Mutable(fd).Map()
 			mmap := m.Mutable(fd).Map()
-			if err := o.unmarshalMap(mmap, fd); !nerr.Merge(err) {
+			if err := o.unmarshalMap(mmap, fd); err != nil {
 				return errors.New("%v|%q: %v", fd.FullName(), name, err)
 				return errors.New("%v|%q: %v", fd.FullName(), name, err)
 			}
 			}
 		default:
 		default:
@@ -239,13 +235,13 @@ Loop:
 			}
 			}
 
 
 			// Required or optional fields.
 			// Required or optional fields.
-			if err := o.unmarshalSingular(m, fd); !nerr.Merge(err) {
+			if err := o.unmarshalSingular(m, fd); err != nil {
 				return errors.New("%v|%q: %v", fd.FullName(), name, err)
 				return errors.New("%v|%q: %v", fd.FullName(), name, err)
 			}
 			}
 		}
 		}
 	}
 	}
 
 
-	return nerr.E
+	return nil
 }
 }
 
 
 // findExtension returns protoreflect.ExtensionType from the resolver if found.
 // findExtension returns protoreflect.ExtensionType from the resolver if found.
@@ -287,12 +283,11 @@ func (o UnmarshalOptions) unmarshalSingular(m pref.Message, fd pref.FieldDescrip
 		val, err = o.unmarshalScalar(fd)
 		val, err = o.unmarshalScalar(fd)
 	}
 	}
 
 
-	var nerr errors.NonFatal
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 	m.Set(fd, val)
 	m.Set(fd, val)
-	return nerr.E
+	return nil
 }
 }
 
 
 // unmarshalScalar unmarshals to a scalar/enum protoreflect.Value specified by
 // unmarshalScalar unmarshals to a scalar/enum protoreflect.Value specified by
@@ -301,9 +296,8 @@ func (o UnmarshalOptions) unmarshalScalar(fd pref.FieldDescriptor) (pref.Value,
 	const b32 int = 32
 	const b32 int = 32
 	const b64 int = 64
 	const b64 int = 64
 
 
-	var nerr errors.NonFatal
 	jval, err := o.decoder.Read()
 	jval, err := o.decoder.Read()
-	if !nerr.Merge(err) {
+	if err != nil {
 		return pref.Value{}, err
 		return pref.Value{}, err
 	}
 	}
 
 
@@ -332,10 +326,10 @@ func (o UnmarshalOptions) unmarshalScalar(fd pref.FieldDescriptor) (pref.Value,
 
 
 	case pref.StringKind:
 	case pref.StringKind:
 		pval, err := unmarshalString(jval)
 		pval, err := unmarshalString(jval)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return pval, err
 			return pval, err
 		}
 		}
-		return pval, nerr.E
+		return pval, nil
 
 
 	case pref.BytesKind:
 	case pref.BytesKind:
 		return unmarshalBytes(jval)
 		return unmarshalBytes(jval)
@@ -367,9 +361,8 @@ func unmarshalInt(jval json.Value, bitSize int) (pref.Value, error) {
 			return pref.Value{}, errors.New("invalid number %v", jval.Raw())
 			return pref.Value{}, errors.New("invalid number %v", jval.Raw())
 		}
 		}
 		dec := json.NewDecoder([]byte(s))
 		dec := json.NewDecoder([]byte(s))
-		var nerr errors.NonFatal
 		jval, err := dec.Read()
 		jval, err := dec.Read()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return pref.Value{}, err
 			return pref.Value{}, err
 		}
 		}
 		return getInt(jval, bitSize)
 		return getInt(jval, bitSize)
@@ -400,9 +393,8 @@ func unmarshalUint(jval json.Value, bitSize int) (pref.Value, error) {
 			return pref.Value{}, errors.New("invalid number %v", jval.Raw())
 			return pref.Value{}, errors.New("invalid number %v", jval.Raw())
 		}
 		}
 		dec := json.NewDecoder([]byte(s))
 		dec := json.NewDecoder([]byte(s))
-		var nerr errors.NonFatal
 		jval, err := dec.Read()
 		jval, err := dec.Read()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return pref.Value{}, err
 			return pref.Value{}, err
 		}
 		}
 		return getUint(jval, bitSize)
 		return getUint(jval, bitSize)
@@ -450,9 +442,8 @@ func unmarshalFloat(jval json.Value, bitSize int) (pref.Value, error) {
 			return pref.Value{}, errors.New("invalid number %v", jval.Raw())
 			return pref.Value{}, errors.New("invalid number %v", jval.Raw())
 		}
 		}
 		dec := json.NewDecoder([]byte(s))
 		dec := json.NewDecoder([]byte(s))
-		var nerr errors.NonFatal
 		jval, err := dec.Read()
 		jval, err := dec.Read()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return pref.Value{}, err
 			return pref.Value{}, err
 		}
 		}
 		return getFloat(jval, bitSize)
 		return getFloat(jval, bitSize)
@@ -526,9 +517,8 @@ func unmarshalEnum(jval json.Value, fd pref.FieldDescriptor) (pref.Value, error)
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalList(list pref.List, fd pref.FieldDescriptor) error {
 func (o UnmarshalOptions) unmarshalList(list pref.List, fd pref.FieldDescriptor) error {
-	var nerr errors.NonFatal
 	jval, err := o.decoder.Read()
 	jval, err := o.decoder.Read()
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 	if jval.Type() != json.StartArray {
 	if jval.Type() != json.StartArray {
@@ -540,11 +530,11 @@ func (o UnmarshalOptions) unmarshalList(list pref.List, fd pref.FieldDescriptor)
 		for {
 		for {
 			m := list.NewMessage()
 			m := list.NewMessage()
 			err := o.unmarshalMessage(m, false)
 			err := o.unmarshalMessage(m, false)
-			if !nerr.Merge(err) {
+			if err != nil {
 				if e, ok := err.(unexpectedJSONError); ok {
 				if e, ok := err.(unexpectedJSONError); ok {
 					if e.value.Type() == json.EndArray {
 					if e.value.Type() == json.EndArray {
 						// Done with list.
 						// Done with list.
-						return nerr.E
+						return nil
 					}
 					}
 				}
 				}
 				return err
 				return err
@@ -554,11 +544,11 @@ func (o UnmarshalOptions) unmarshalList(list pref.List, fd pref.FieldDescriptor)
 	default:
 	default:
 		for {
 		for {
 			val, err := o.unmarshalScalar(fd)
 			val, err := o.unmarshalScalar(fd)
-			if !nerr.Merge(err) {
+			if err != nil {
 				if e, ok := err.(unexpectedJSONError); ok {
 				if e, ok := err.(unexpectedJSONError); ok {
 					if e.value.Type() == json.EndArray {
 					if e.value.Type() == json.EndArray {
 						// Done with list.
 						// Done with list.
-						return nerr.E
+						return nil
 					}
 					}
 				}
 				}
 				return err
 				return err
@@ -566,13 +556,12 @@ func (o UnmarshalOptions) unmarshalList(list pref.List, fd pref.FieldDescriptor)
 			list.Append(val)
 			list.Append(val)
 		}
 		}
 	}
 	}
-	return nerr.E
+	return nil
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalMap(mmap pref.Map, fd pref.FieldDescriptor) error {
 func (o UnmarshalOptions) unmarshalMap(mmap pref.Map, fd pref.FieldDescriptor) error {
-	var nerr errors.NonFatal
 	jval, err := o.decoder.Read()
 	jval, err := o.decoder.Read()
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 	if jval.Type() != json.StartObject {
 	if jval.Type() != json.StartObject {
@@ -586,12 +575,11 @@ func (o UnmarshalOptions) unmarshalMap(mmap pref.Map, fd pref.FieldDescriptor) e
 	switch fd.MapValue().Kind() {
 	switch fd.MapValue().Kind() {
 	case pref.MessageKind, pref.GroupKind:
 	case pref.MessageKind, pref.GroupKind:
 		unmarshalMapValue = func() (pref.Value, error) {
 		unmarshalMapValue = func() (pref.Value, error) {
-			var nerr errors.NonFatal
 			m := mmap.NewMessage()
 			m := mmap.NewMessage()
-			if err := o.unmarshalMessage(m, false); !nerr.Merge(err) {
+			if err := o.unmarshalMessage(m, false); err != nil {
 				return pref.Value{}, err
 				return pref.Value{}, err
 			}
 			}
-			return pref.ValueOf(m), nerr.E
+			return pref.ValueOf(m), nil
 		}
 		}
 	default:
 	default:
 		unmarshalMapValue = func() (pref.Value, error) {
 		unmarshalMapValue = func() (pref.Value, error) {
@@ -603,7 +591,7 @@ Loop:
 	for {
 	for {
 		// Read field name.
 		// Read field name.
 		jval, err := o.decoder.Read()
 		jval, err := o.decoder.Read()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 		switch jval.Type() {
 		switch jval.Type() {
@@ -616,13 +604,13 @@ Loop:
 		}
 		}
 
 
 		name, err := jval.Name()
 		name, err := jval.Name()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 
 
 		// Unmarshal field name.
 		// Unmarshal field name.
 		pkey, err := unmarshalMapKey(name, fd.MapKey())
 		pkey, err := unmarshalMapKey(name, fd.MapKey())
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 
 
@@ -633,14 +621,14 @@ Loop:
 
 
 		// Read and unmarshal field value.
 		// Read and unmarshal field value.
 		pval, err := unmarshalMapValue()
 		pval, err := unmarshalMapValue()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 
 
 		mmap.Set(pkey, pval)
 		mmap.Set(pkey, pval)
 	}
 	}
 
 
-	return nerr.E
+	return nil
 }
 }
 
 
 // unmarshalMapKey converts given string into a protoreflect.MapKey. A map key type is any
 // unmarshalMapKey converts given string into a protoreflect.MapKey. A map key type is any

+ 6 - 118
encoding/protojson/decode_test.go

@@ -5,7 +5,6 @@
 package protojson_test
 package protojson_test
 
 
 import (
 import (
-	"bytes"
 	"math"
 	"math"
 	"testing"
 	"testing"
 
 
@@ -391,10 +390,7 @@ func TestUnmarshal(t *testing.T) {
 		desc:         "string with invalid UTF-8",
 		desc:         "string with invalid UTF-8",
 		inputMessage: &pb3.Scalars{},
 		inputMessage: &pb3.Scalars{},
 		inputText:    "{\"sString\": \"\xff\"}",
 		inputText:    "{\"sString\": \"\xff\"}",
-		wantMessage: &pb3.Scalars{
-			SString: "\xff",
-		},
-		wantErr: true,
+		wantErr:      true,
 	}, {
 	}, {
 		desc:         "not string",
 		desc:         "not string",
 		inputMessage: &pb2.Scalars{},
 		inputMessage: &pb2.Scalars{},
@@ -814,18 +810,12 @@ func TestUnmarshal(t *testing.T) {
 		desc:         "repeated string contains invalid UTF8",
 		desc:         "repeated string contains invalid UTF8",
 		inputMessage: &pb2.Repeats{},
 		inputMessage: &pb2.Repeats{},
 		inputText:    `{"rptString": ["` + "abc\xff" + `"]}`,
 		inputText:    `{"rptString": ["` + "abc\xff" + `"]}`,
-		wantMessage: &pb2.Repeats{
-			RptString: []string{"abc\xff"},
-		},
-		wantErr: true,
+		wantErr:      true,
 	}, {
 	}, {
 		desc:         "repeated messages contain invalid UTF8",
 		desc:         "repeated messages contain invalid UTF8",
 		inputMessage: &pb2.Nests{},
 		inputMessage: &pb2.Nests{},
 		inputText:    `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
 		inputText:    `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
-		wantMessage: &pb2.Nests{
-			RptNested: []*pb2.Nested{{OptString: scalar.String("abc\xff")}},
-		},
-		wantErr: true,
+		wantErr:      true,
 	}, {
 	}, {
 		desc:         "repeated scalars contain invalid type",
 		desc:         "repeated scalars contain invalid type",
 		inputMessage: &pb2.Repeats{},
 		inputMessage: &pb2.Repeats{},
@@ -1020,11 +1010,6 @@ func TestUnmarshal(t *testing.T) {
 	}
 	}
   }
   }
 }`,
 }`,
-		wantMessage: &pb3.Maps{
-			StrToNested: map[string]*pb3.Nested{
-				"hello": {SString: "abc\xff"},
-			},
-		},
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:         "map key contains invalid UTF8",
 		desc:         "map key contains invalid UTF8",
@@ -1034,11 +1019,6 @@ func TestUnmarshal(t *testing.T) {
     "` + "abc\xff" + `": {}
     "` + "abc\xff" + `": {}
   }
   }
 }`,
 }`,
-		wantMessage: &pb3.Maps{
-			StrToNested: map[string]*pb3.Nested{
-				"abc\xff": {},
-			},
-		},
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:         "required fields not set",
 		desc:         "required fields not set",
@@ -1509,16 +1489,12 @@ func TestUnmarshal(t *testing.T) {
 		desc:         "StringValue with invalid UTF8 error",
 		desc:         "StringValue with invalid UTF8 error",
 		inputMessage: &wrapperspb.StringValue{},
 		inputMessage: &wrapperspb.StringValue{},
 		inputText:    "\"abc\xff\"",
 		inputText:    "\"abc\xff\"",
-		wantMessage:  &wrapperspb.StringValue{Value: "abc\xff"},
 		wantErr:      true,
 		wantErr:      true,
 	}, {
 	}, {
 		desc:         "StringValue field with invalid UTF8 error",
 		desc:         "StringValue field with invalid UTF8 error",
 		inputMessage: &pb2.KnownTypes{},
 		inputMessage: &pb2.KnownTypes{},
 		inputText:    "{\n  \"optString\": \"abc\xff\"\n}",
 		inputText:    "{\n  \"optString\": \"abc\xff\"\n}",
-		wantMessage: &pb2.KnownTypes{
-			OptString: &wrapperspb.StringValue{Value: "abc\xff"},
-		},
-		wantErr: true,
+		wantErr:      true,
 	}, {
 	}, {
 		desc:         "NullValue field with JSON null",
 		desc:         "NullValue field with JSON null",
 		inputMessage: &pb2.KnownTypes{},
 		inputMessage: &pb2.KnownTypes{},
@@ -1589,7 +1565,6 @@ func TestUnmarshal(t *testing.T) {
 		desc:         "Value string with invalid UTF8",
 		desc:         "Value string with invalid UTF8",
 		inputMessage: &structpb.Value{},
 		inputMessage: &structpb.Value{},
 		inputText:    "\"\xff\"",
 		inputText:    "\"\xff\"",
-		wantMessage:  &structpb.Value{Kind: &structpb.Value_StringValue{"\xff"}},
 		wantErr:      true,
 		wantErr:      true,
 	}, {
 	}, {
 		desc:         "Value field string",
 		desc:         "Value field string",
@@ -1606,9 +1581,6 @@ func TestUnmarshal(t *testing.T) {
 		inputText: `{
 		inputText: `{
   "optValue": "` + "\xff" + `"
   "optValue": "` + "\xff" + `"
 }`,
 }`,
-		wantMessage: &pb2.KnownTypes{
-			OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"\xff"}},
-		},
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:         "Value empty struct",
 		desc:         "Value empty struct",
@@ -1660,16 +1632,7 @@ func TestUnmarshal(t *testing.T) {
 		desc:         "Value struct with invalid UTF8 string",
 		desc:         "Value struct with invalid UTF8 string",
 		inputMessage: &structpb.Value{},
 		inputMessage: &structpb.Value{},
 		inputText:    "{\"string\": \"abc\xff\"}",
 		inputText:    "{\"string\": \"abc\xff\"}",
-		wantMessage: &structpb.Value{
-			Kind: &structpb.Value_StructValue{
-				&structpb.Struct{
-					Fields: map[string]*structpb.Value{
-						"string": {Kind: &structpb.Value_StringValue{"abc\xff"}},
-					},
-				},
-			},
-		},
-		wantErr: true,
+		wantErr:      true,
 	}, {
 	}, {
 		desc:         "Value field struct",
 		desc:         "Value field struct",
 		inputMessage: &pb2.KnownTypes{},
 		inputMessage: &pb2.KnownTypes{},
@@ -1743,33 +1706,13 @@ func TestUnmarshal(t *testing.T) {
 		desc:         "Value list with invalid UTF8 string",
 		desc:         "Value list with invalid UTF8 string",
 		inputMessage: &structpb.Value{},
 		inputMessage: &structpb.Value{},
 		inputText:    "[\"abc\xff\"]",
 		inputText:    "[\"abc\xff\"]",
-		wantMessage: &structpb.Value{
-			Kind: &structpb.Value_ListValue{
-				&structpb.ListValue{
-					Values: []*structpb.Value{
-						{Kind: &structpb.Value_StringValue{"abc\xff"}},
-					},
-				},
-			},
-		},
-		wantErr: true,
+		wantErr:      true,
 	}, {
 	}, {
 		desc:         "Value field list with invalid UTF8 string",
 		desc:         "Value field list with invalid UTF8 string",
 		inputMessage: &pb2.KnownTypes{},
 		inputMessage: &pb2.KnownTypes{},
 		inputText: `{
 		inputText: `{
   "optValue": [ "` + "abc\xff" + `"]
   "optValue": [ "` + "abc\xff" + `"]
 }`,
 }`,
-		wantMessage: &pb2.KnownTypes{
-			OptValue: &structpb.Value{
-				Kind: &structpb.Value_ListValue{
-					&structpb.ListValue{
-						Values: []*structpb.Value{
-							{Kind: &structpb.Value_StringValue{"abc\xff"}},
-						},
-					},
-				},
-			},
-		},
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:         "Duration empty string",
 		desc:         "Duration empty string",
@@ -2073,19 +2016,6 @@ func TestUnmarshal(t *testing.T) {
   "optString": "` + "abc\xff" + `",
   "optString": "` + "abc\xff" + `",
   "@type": "foo/pb2.Nested"
   "@type": "foo/pb2.Nested"
 }`,
 }`,
-		wantMessage: func() proto.Message {
-			m := &pb2.Nested{
-				OptString: scalar.String("abc\xff"),
-			}
-			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
-			if err != nil {
-				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
-			}
-			return &anypb.Any{
-				TypeUrl: "foo/pb2.Nested",
-				Value:   b,
-			}
-		}(),
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "Any with BoolValue",
 		desc: "Any with BoolValue",
@@ -2141,17 +2071,6 @@ func TestUnmarshal(t *testing.T) {
   "@type": "google.protobuf.StringValue",
   "@type": "google.protobuf.StringValue",
   "value": "` + "abc\xff" + `"
   "value": "` + "abc\xff" + `"
 }`,
 }`,
-		wantMessage: func() proto.Message {
-			m := &wrapperspb.StringValue{Value: "abcd"}
-			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
-			if err != nil {
-				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
-			}
-			return &anypb.Any{
-				TypeUrl: "google.protobuf.StringValue",
-				Value:   bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
-			}
-		}(),
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "Any with Int64Value",
 		desc: "Any with Int64Value",
@@ -2227,17 +2146,6 @@ func TestUnmarshal(t *testing.T) {
   "@type": "google.protobuf.Value",
   "@type": "google.protobuf.Value",
   "value": "` + "abc\xff" + `"
   "value": "` + "abc\xff" + `"
 }`,
 }`,
-		wantMessage: func() proto.Message {
-			m := &structpb.Value{Kind: &structpb.Value_StringValue{"abcd"}}
-			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
-			if err != nil {
-				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
-			}
-			return &anypb.Any{
-				TypeUrl: "google.protobuf.Value",
-				Value:   bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
-			}
-		}(),
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "Any with Value of NullValue",
 		desc: "Any with Value of NullValue",
@@ -2380,26 +2288,6 @@ func TestUnmarshal(t *testing.T) {
 	"value": "` + "abc\xff" + `"
 	"value": "` + "abc\xff" + `"
   }
   }
 }`,
 }`,
-		wantMessage: func() proto.Message {
-			m1 := &wrapperspb.StringValue{Value: "abcd"}
-			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m1)
-			if err != nil {
-				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
-			}
-			m2 := &anypb.Any{
-				TypeUrl: "google.protobuf.StringValue",
-				Value:   b,
-			}
-			m3 := &pb2.KnownTypes{OptAny: m2}
-			b, err = proto.MarshalOptions{Deterministic: true}.Marshal(m3)
-			if err != nil {
-				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
-			}
-			return &anypb.Any{
-				TypeUrl: "pb2.KnownTypes",
-				Value:   bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
-			}
-		}(),
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "well known types as field values",
 		desc: "well known types as field values",

+ 23 - 33
encoding/protojson/encode.go

@@ -10,7 +10,6 @@ import (
 	"sort"
 	"sort"
 
 
 	"google.golang.org/protobuf/internal/encoding/json"
 	"google.golang.org/protobuf/internal/encoding/json"
-	"google.golang.org/protobuf/internal/errors"
 	"google.golang.org/protobuf/internal/pragma"
 	"google.golang.org/protobuf/internal/pragma"
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/proto"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
@@ -58,38 +57,33 @@ func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
 		o.Resolver = protoregistry.GlobalTypes
 		o.Resolver = protoregistry.GlobalTypes
 	}
 	}
 
 
-	var nerr errors.NonFatal
 	err = o.marshalMessage(m.ProtoReflect())
 	err = o.marshalMessage(m.ProtoReflect())
-	if !nerr.Merge(err) {
+	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	if !o.AllowPartial {
-		nerr.Merge(proto.IsInitialized(m))
+	if o.AllowPartial {
+		return o.encoder.Bytes(), nil
 	}
 	}
-	return o.encoder.Bytes(), nerr.E
+	return o.encoder.Bytes(), proto.IsInitialized(m)
 }
 }
 
 
 // marshalMessage marshals the given protoreflect.Message.
 // marshalMessage marshals the given protoreflect.Message.
 func (o MarshalOptions) marshalMessage(m pref.Message) error {
 func (o MarshalOptions) marshalMessage(m pref.Message) error {
-	var nerr errors.NonFatal
-
 	if isCustomType(m.Descriptor().FullName()) {
 	if isCustomType(m.Descriptor().FullName()) {
 		return o.marshalCustomType(m)
 		return o.marshalCustomType(m)
 	}
 	}
 
 
 	o.encoder.StartObject()
 	o.encoder.StartObject()
 	defer o.encoder.EndObject()
 	defer o.encoder.EndObject()
-	if err := o.marshalFields(m); !nerr.Merge(err) {
+	if err := o.marshalFields(m); err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	return nerr.E
+	return nil
 }
 }
 
 
 // marshalFields marshals the fields in the given protoreflect.Message.
 // marshalFields marshals the fields in the given protoreflect.Message.
 func (o MarshalOptions) marshalFields(m pref.Message) error {
 func (o MarshalOptions) marshalFields(m pref.Message) error {
-	var nerr errors.NonFatal
-
 	// Marshal out known fields.
 	// Marshal out known fields.
 	fieldDescs := m.Descriptor().Fields()
 	fieldDescs := m.Descriptor().Fields()
 	for i := 0; i < fieldDescs.Len(); i++ {
 	for i := 0; i < fieldDescs.Len(); i++ {
@@ -100,19 +94,19 @@ func (o MarshalOptions) marshalFields(m pref.Message) error {
 
 
 		name := fd.JSONName()
 		name := fd.JSONName()
 		val := m.Get(fd)
 		val := m.Get(fd)
-		if err := o.encoder.WriteName(name); !nerr.Merge(err) {
+		if err := o.encoder.WriteName(name); err != nil {
 			return err
 			return err
 		}
 		}
-		if err := o.marshalValue(val, fd); !nerr.Merge(err) {
+		if err := o.marshalValue(val, fd); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
 
 
 	// Marshal out extensions.
 	// Marshal out extensions.
-	if err := o.marshalExtensions(m); !nerr.Merge(err) {
+	if err := o.marshalExtensions(m); err != nil {
 		return err
 		return err
 	}
 	}
-	return nerr.E
+	return nil
 }
 }
 
 
 // marshalValue marshals the given protoreflect.Value.
 // marshalValue marshals the given protoreflect.Value.
@@ -130,13 +124,12 @@ func (o MarshalOptions) marshalValue(val pref.Value, fd pref.FieldDescriptor) er
 // marshalSingular marshals the given non-repeated field value. This includes
 // marshalSingular marshals the given non-repeated field value. This includes
 // all scalar types, enums, messages, and groups.
 // all scalar types, enums, messages, and groups.
 func (o MarshalOptions) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error {
 func (o MarshalOptions) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error {
-	var nerr errors.NonFatal
 	switch kind := fd.Kind(); kind {
 	switch kind := fd.Kind(); kind {
 	case pref.BoolKind:
 	case pref.BoolKind:
 		o.encoder.WriteBool(val.Bool())
 		o.encoder.WriteBool(val.Bool())
 
 
 	case pref.StringKind:
 	case pref.StringKind:
-		if err := o.encoder.WriteString(val.String()); !nerr.Merge(err) {
+		if err := o.encoder.WriteString(val.String()); err != nil {
 			return err
 			return err
 		}
 		}
 
 
@@ -161,7 +154,7 @@ func (o MarshalOptions) marshalSingular(val pref.Value, fd pref.FieldDescriptor)
 
 
 	case pref.BytesKind:
 	case pref.BytesKind:
 		err := o.encoder.WriteString(base64.StdEncoding.EncodeToString(val.Bytes()))
 		err := o.encoder.WriteString(base64.StdEncoding.EncodeToString(val.Bytes()))
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 
 
@@ -170,7 +163,7 @@ func (o MarshalOptions) marshalSingular(val pref.Value, fd pref.FieldDescriptor)
 			o.encoder.WriteNull()
 			o.encoder.WriteNull()
 		} else if desc := fd.Enum().Values().ByNumber(val.Enum()); desc != nil {
 		} else if desc := fd.Enum().Values().ByNumber(val.Enum()); desc != nil {
 			err := o.encoder.WriteString(string(desc.Name()))
 			err := o.encoder.WriteString(string(desc.Name()))
-			if !nerr.Merge(err) {
+			if err != nil {
 				return err
 				return err
 			}
 			}
 		} else {
 		} else {
@@ -179,14 +172,14 @@ func (o MarshalOptions) marshalSingular(val pref.Value, fd pref.FieldDescriptor)
 		}
 		}
 
 
 	case pref.MessageKind, pref.GroupKind:
 	case pref.MessageKind, pref.GroupKind:
-		if err := o.marshalMessage(val.Message()); !nerr.Merge(err) {
+		if err := o.marshalMessage(val.Message()); err != nil {
 			return err
 			return err
 		}
 		}
 
 
 	default:
 	default:
 		panic(fmt.Sprintf("%v has unknown kind: %v", fd.FullName(), kind))
 		panic(fmt.Sprintf("%v has unknown kind: %v", fd.FullName(), kind))
 	}
 	}
-	return nerr.E
+	return nil
 }
 }
 
 
 // marshalList marshals the given protoreflect.List.
 // marshalList marshals the given protoreflect.List.
@@ -194,14 +187,13 @@ func (o MarshalOptions) marshalList(list pref.List, fd pref.FieldDescriptor) err
 	o.encoder.StartArray()
 	o.encoder.StartArray()
 	defer o.encoder.EndArray()
 	defer o.encoder.EndArray()
 
 
-	var nerr errors.NonFatal
 	for i := 0; i < list.Len(); i++ {
 	for i := 0; i < list.Len(); i++ {
 		item := list.Get(i)
 		item := list.Get(i)
-		if err := o.marshalSingular(item, fd); !nerr.Merge(err) {
+		if err := o.marshalSingular(item, fd); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
-	return nerr.E
+	return nil
 }
 }
 
 
 type mapEntry struct {
 type mapEntry struct {
@@ -223,16 +215,15 @@ func (o MarshalOptions) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) error
 	sortMap(fd.MapKey().Kind(), entries)
 	sortMap(fd.MapKey().Kind(), entries)
 
 
 	// Write out sorted list.
 	// Write out sorted list.
-	var nerr errors.NonFatal
 	for _, entry := range entries {
 	for _, entry := range entries {
-		if err := o.encoder.WriteName(entry.key.String()); !nerr.Merge(err) {
+		if err := o.encoder.WriteName(entry.key.String()); err != nil {
 			return err
 			return err
 		}
 		}
-		if err := o.marshalSingular(entry.value, fd.MapValue()); !nerr.Merge(err) {
+		if err := o.marshalSingular(entry.value, fd.MapValue()); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
-	return nerr.E
+	return nil
 }
 }
 
 
 // sortMap orders list based on value of key field for deterministic ordering.
 // sortMap orders list based on value of key field for deterministic ordering.
@@ -288,19 +279,18 @@ func (o MarshalOptions) marshalExtensions(m pref.Message) error {
 	})
 	})
 
 
 	// Write out sorted list.
 	// Write out sorted list.
-	var nerr errors.NonFatal
 	for _, entry := range entries {
 	for _, entry := range entries {
 		// JSON field name is the proto field name enclosed in [], similar to
 		// JSON field name is the proto field name enclosed in [], similar to
 		// textproto. This is consistent with Go v1 lib. C++ lib v3.7.0 does not
 		// textproto. This is consistent with Go v1 lib. C++ lib v3.7.0 does not
 		// marshal out extension fields.
 		// marshal out extension fields.
-		if err := o.encoder.WriteName("[" + entry.key + "]"); !nerr.Merge(err) {
+		if err := o.encoder.WriteName("[" + entry.key + "]"); err != nil {
 			return err
 			return err
 		}
 		}
-		if err := o.marshalValue(entry.value, entry.desc); !nerr.Merge(err) {
+		if err := o.marshalValue(entry.value, entry.desc); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
-	return nerr.E
+	return nil
 }
 }
 
 
 // isMessageSetExtension reports whether extension extends a message set.
 // isMessageSetExtension reports whether extension extends a message set.

+ 0 - 18
encoding/protojson/encode_test.go

@@ -159,7 +159,6 @@ func TestMarshal(t *testing.T) {
 		input: &pb3.Scalars{
 		input: &pb3.Scalars{
 			SString: "abc\xff",
 			SString: "abc\xff",
 		},
 		},
-		want:    "{\n  \"sString\": \"abc\xff\"\n}",
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "float nan",
 		desc: "float nan",
@@ -1149,14 +1148,12 @@ func TestMarshal(t *testing.T) {
 	}, {
 	}, {
 		desc:    "StringValue with invalid UTF8 error",
 		desc:    "StringValue with invalid UTF8 error",
 		input:   &wrapperspb.StringValue{Value: "abc\xff"},
 		input:   &wrapperspb.StringValue{Value: "abc\xff"},
-		want:    "\"abc\xff\"",
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "StringValue field with invalid UTF8 error",
 		desc: "StringValue field with invalid UTF8 error",
 		input: &pb2.KnownTypes{
 		input: &pb2.KnownTypes{
 			OptString: &wrapperspb.StringValue{Value: "abc\xff"},
 			OptString: &wrapperspb.StringValue{Value: "abc\xff"},
 		},
 		},
-		want:    "{\n  \"optString\": \"abc\xff\"\n}",
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:  "BytesValue",
 		desc:  "BytesValue",
@@ -1201,7 +1198,6 @@ func TestMarshal(t *testing.T) {
 	}, {
 	}, {
 		desc:    "Value contains StringValue with invalid UTF8",
 		desc:    "Value contains StringValue with invalid UTF8",
 		input:   &structpb.Value{Kind: &structpb.Value_StringValue{"\xff"}},
 		input:   &structpb.Value{Kind: &structpb.Value_StringValue{"\xff"}},
-		want:    "\"\xff\"",
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "Value contains Struct",
 		desc: "Value contains Struct",
@@ -1312,7 +1308,6 @@ func TestMarshal(t *testing.T) {
 				"string": {Kind: &structpb.Value_StringValue{"\xff"}},
 				"string": {Kind: &structpb.Value_StringValue{"\xff"}},
 			},
 			},
 		},
 		},
-		want:    "{\n  \"string\": \"\xff\"\n}",
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:  "ListValue with nil values",
 		desc:  "ListValue with nil values",
@@ -1375,7 +1370,6 @@ func TestMarshal(t *testing.T) {
 				{Kind: &structpb.Value_StringValue{"\xff"}},
 				{Kind: &structpb.Value_StringValue{"\xff"}},
 			},
 			},
 		},
 		},
-		want:    "[\n  \"\xff\"\n]",
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:  "Duration empty",
 		desc:  "Duration empty",
@@ -1631,10 +1625,6 @@ func TestMarshal(t *testing.T) {
 				Value:   b,
 				Value:   b,
 			}
 			}
 		}(),
 		}(),
-		want: `{
-  "@type": "foo/pb2.Nested",
-  "optString": "` + "abc\xff" + `"
-}`,
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "Any with invalid value",
 		desc: "Any with invalid value",
@@ -1702,10 +1692,6 @@ func TestMarshal(t *testing.T) {
 				Value:   bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
 				Value:   bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
 			}
 			}
 		}(),
 		}(),
-		want: `{
-  "@type": "google.protobuf.StringValue",
-  "value": "` + "abc\xff" + `"
-}`,
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "Any with Int64Value",
 		desc: "Any with Int64Value",
@@ -1780,10 +1766,6 @@ func TestMarshal(t *testing.T) {
 				Value:   bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
 				Value:   bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
 			}
 			}
 		}(),
 		}(),
-		want: `{
-  "@type": "type.googleapis.com/google.protobuf.Value",
-  "value": "` + "abc\xff" + `"
-}`,
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "Any with Value of NullValue",
 		desc: "Any with Value of NullValue",

+ 40 - 51
encoding/protojson/well_known_types.go

@@ -166,14 +166,13 @@ func (o MarshalOptions) marshalAny(m pref.Message) error {
 	// Marshal out @type field.
 	// Marshal out @type field.
 	typeURL := typeVal.String()
 	typeURL := typeVal.String()
 	o.encoder.WriteName("@type")
 	o.encoder.WriteName("@type")
-	var nerr errors.NonFatal
-	if err := o.encoder.WriteString(typeURL); !nerr.Merge(err) {
+	if err := o.encoder.WriteString(typeURL); err != nil {
 		return err
 		return err
 	}
 	}
 
 
 	// Resolve the type in order to unmarshal value field.
 	// Resolve the type in order to unmarshal value field.
 	emt, err := o.Resolver.FindMessageByURL(typeURL)
 	emt, err := o.Resolver.FindMessageByURL(typeURL)
-	if !nerr.Merge(err) {
+	if err != nil {
 		return errors.New("%s: unable to resolve %q: %v", m.Descriptor().FullName(), typeURL, err)
 		return errors.New("%s: unable to resolve %q: %v", m.Descriptor().FullName(), typeURL, err)
 	}
 	}
 
 
@@ -182,7 +181,7 @@ func (o MarshalOptions) marshalAny(m pref.Message) error {
 		AllowPartial: true, // never check required fields inside an Any
 		AllowPartial: true, // never check required fields inside an Any
 		Resolver:     o.Resolver,
 		Resolver:     o.Resolver,
 	}.Unmarshal(valueVal.Bytes(), em.Interface())
 	}.Unmarshal(valueVal.Bytes(), em.Interface())
-	if !nerr.Merge(err) {
+	if err != nil {
 		return errors.New("%s: unable to unmarshal %q: %v", m.Descriptor().FullName(), typeURL, err)
 		return errors.New("%s: unable to unmarshal %q: %v", m.Descriptor().FullName(), typeURL, err)
 	}
 	}
 
 
@@ -195,11 +194,11 @@ func (o MarshalOptions) marshalAny(m pref.Message) error {
 	}
 	}
 
 
 	// Else, marshal out the embedded message's fields in this Any object.
 	// Else, marshal out the embedded message's fields in this Any object.
-	if err := o.marshalFields(em); !nerr.Merge(err) {
+	if err := o.marshalFields(em); err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	return nerr.E
+	return nil
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalAny(m pref.Message) error {
 func (o UnmarshalOptions) unmarshalAny(m pref.Message) error {
@@ -224,8 +223,7 @@ func (o UnmarshalOptions) unmarshalAny(m pref.Message) error {
 		// Treat all fields as unknowns, similar to an empty object.
 		// Treat all fields as unknowns, similar to an empty object.
 		return skipJSONValue(o.decoder)
 		return skipJSONValue(o.decoder)
 	}
 	}
-	var nerr errors.NonFatal
-	if !nerr.Merge(err) {
+	if err != nil {
 		return errors.New("google.protobuf.Any: %v", err)
 		return errors.New("google.protobuf.Any: %v", err)
 	}
 	}
 
 
@@ -239,12 +237,12 @@ func (o UnmarshalOptions) unmarshalAny(m pref.Message) error {
 	if isCustomType(emt.Descriptor().FullName()) {
 	if isCustomType(emt.Descriptor().FullName()) {
 		// If embedded message is a custom type, unmarshal the JSON "value" field
 		// If embedded message is a custom type, unmarshal the JSON "value" field
 		// into it.
 		// into it.
-		if err := o.unmarshalAnyValue(em); !nerr.Merge(err) {
+		if err := o.unmarshalAnyValue(em); err != nil {
 			return errors.New("google.protobuf.Any: %v", err)
 			return errors.New("google.protobuf.Any: %v", err)
 		}
 		}
 	} else {
 	} else {
 		// Else unmarshal the current JSON object into it.
 		// Else unmarshal the current JSON object into it.
-		if err := o.unmarshalMessage(em, true); !nerr.Merge(err) {
+		if err := o.unmarshalMessage(em, true); err != nil {
 			return errors.New("google.protobuf.Any: %v", err)
 			return errors.New("google.protobuf.Any: %v", err)
 		}
 		}
 	}
 	}
@@ -254,7 +252,7 @@ func (o UnmarshalOptions) unmarshalAny(m pref.Message) error {
 		AllowPartial:  true, // never check required fields inside an Any
 		AllowPartial:  true, // never check required fields inside an Any
 		Deterministic: true,
 		Deterministic: true,
 	}.Marshal(em.Interface())
 	}.Marshal(em.Interface())
-	if !nerr.Merge(err) {
+	if err != nil {
 		return errors.New("google.protobuf.Any: %v", err)
 		return errors.New("google.protobuf.Any: %v", err)
 	}
 	}
 
 
@@ -264,7 +262,7 @@ func (o UnmarshalOptions) unmarshalAny(m pref.Message) error {
 
 
 	m.Set(fdType, pref.ValueOf(typeURL))
 	m.Set(fdType, pref.ValueOf(typeURL))
 	m.Set(fdValue, pref.ValueOf(b))
 	m.Set(fdValue, pref.ValueOf(b))
-	return nerr.E
+	return nil
 }
 }
 
 
 var errEmptyObject = errors.New(`empty object`)
 var errEmptyObject = errors.New(`empty object`)
@@ -276,7 +274,6 @@ var errMissingType = errors.New(`missing "@type" field`)
 // does not contain the field or other decoding problems.
 // does not contain the field or other decoding problems.
 func findTypeURL(dec *json.Decoder) (string, error) {
 func findTypeURL(dec *json.Decoder) (string, error) {
 	var typeURL string
 	var typeURL string
-	var nerr errors.NonFatal
 	numFields := 0
 	numFields := 0
 	// Skip start object.
 	// Skip start object.
 	dec.Read()
 	dec.Read()
@@ -284,7 +281,7 @@ func findTypeURL(dec *json.Decoder) (string, error) {
 Loop:
 Loop:
 	for {
 	for {
 		jval, err := dec.Read()
 		jval, err := dec.Read()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return "", err
 			return "", err
 		}
 		}
 
 
@@ -302,12 +299,12 @@ Loop:
 		case json.Name:
 		case json.Name:
 			numFields++
 			numFields++
 			name, err := jval.Name()
 			name, err := jval.Name()
-			if !nerr.Merge(err) {
+			if err != nil {
 				return "", err
 				return "", err
 			}
 			}
 			if name != "@type" {
 			if name != "@type" {
 				// Skip value.
 				// Skip value.
-				if err := skipJSONValue(dec); !nerr.Merge(err) {
+				if err := skipJSONValue(dec); err != nil {
 					return "", err
 					return "", err
 				}
 				}
 				continue
 				continue
@@ -319,7 +316,7 @@ Loop:
 			}
 			}
 			// Read field value.
 			// Read field value.
 			jval, err := dec.Read()
 			jval, err := dec.Read()
-			if !nerr.Merge(err) {
+			if err != nil {
 				return "", err
 				return "", err
 			}
 			}
 			if jval.Type() != json.String {
 			if jval.Type() != json.String {
@@ -332,7 +329,7 @@ Loop:
 		}
 		}
 	}
 	}
 
 
-	return typeURL, nerr.E
+	return typeURL, nil
 }
 }
 
 
 // skipJSONValue makes the given decoder parse a JSON value (null, boolean,
 // skipJSONValue makes the given decoder parse a JSON value (null, boolean,
@@ -340,9 +337,8 @@ Loop:
 // JSON value. It relies on Decoder.Read returning an error if the types are
 // JSON value. It relies on Decoder.Read returning an error if the types are
 // not in valid sequence.
 // not in valid sequence.
 func skipJSONValue(dec *json.Decoder) error {
 func skipJSONValue(dec *json.Decoder) error {
-	var nerr errors.NonFatal
 	jval, err := dec.Read()
 	jval, err := dec.Read()
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 	// Only need to continue reading for objects and arrays.
 	// Only need to continue reading for objects and arrays.
@@ -350,7 +346,7 @@ func skipJSONValue(dec *json.Decoder) error {
 	case json.StartObject:
 	case json.StartObject:
 		for {
 		for {
 			jval, err := dec.Read()
 			jval, err := dec.Read()
-			if !nerr.Merge(err) {
+			if err != nil {
 				return err
 				return err
 			}
 			}
 			switch jval.Type() {
 			switch jval.Type() {
@@ -358,7 +354,7 @@ func skipJSONValue(dec *json.Decoder) error {
 				return nil
 				return nil
 			case json.Name:
 			case json.Name:
 				// Skip object field value.
 				// Skip object field value.
-				if err := skipJSONValue(dec); !nerr.Merge(err) {
+				if err := skipJSONValue(dec); err != nil {
 					return err
 					return err
 				}
 				}
 			}
 			}
@@ -375,26 +371,25 @@ func skipJSONValue(dec *json.Decoder) error {
 				return err
 				return err
 			default:
 			default:
 				// Skip array item.
 				// Skip array item.
-				if err := skipJSONValue(dec); !nerr.Merge(err) {
+				if err := skipJSONValue(dec); err != nil {
 					return err
 					return err
 				}
 				}
 			}
 			}
 		}
 		}
 	}
 	}
-	return nerr.E
+	return nil
 }
 }
 
 
 // unmarshalAnyValue unmarshals the given custom-type message from the JSON
 // unmarshalAnyValue unmarshals the given custom-type message from the JSON
 // object's "value" field.
 // object's "value" field.
 func (o UnmarshalOptions) unmarshalAnyValue(m pref.Message) error {
 func (o UnmarshalOptions) unmarshalAnyValue(m pref.Message) error {
-	var nerr errors.NonFatal
 	// Skip StartObject, and start reading the fields.
 	// Skip StartObject, and start reading the fields.
 	o.decoder.Read()
 	o.decoder.Read()
 
 
 	var found bool // Used for detecting duplicate "value".
 	var found bool // Used for detecting duplicate "value".
 	for {
 	for {
 		jval, err := o.decoder.Read()
 		jval, err := o.decoder.Read()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 		switch jval.Type() {
 		switch jval.Type() {
@@ -402,17 +397,17 @@ func (o UnmarshalOptions) unmarshalAnyValue(m pref.Message) error {
 			if !found {
 			if !found {
 				return errors.New(`missing "value" field`)
 				return errors.New(`missing "value" field`)
 			}
 			}
-			return nerr.E
+			return nil
 
 
 		case json.Name:
 		case json.Name:
 			name, err := jval.Name()
 			name, err := jval.Name()
-			if !nerr.Merge(err) {
+			if err != nil {
 				return err
 				return err
 			}
 			}
 			switch name {
 			switch name {
 			default:
 			default:
 				if o.DiscardUnknown {
 				if o.DiscardUnknown {
-					if err := skipJSONValue(o.decoder); !nerr.Merge(err) {
+					if err := skipJSONValue(o.decoder); err != nil {
 						return err
 						return err
 					}
 					}
 					continue
 					continue
@@ -428,7 +423,7 @@ func (o UnmarshalOptions) unmarshalAnyValue(m pref.Message) error {
 					return errors.New(`duplicate "value" field`)
 					return errors.New(`duplicate "value" field`)
 				}
 				}
 				// Unmarshal the field value into the given message.
 				// Unmarshal the field value into the given message.
-				if err := o.unmarshalCustomType(m); !nerr.Merge(err) {
+				if err := o.unmarshalCustomType(m); err != nil {
 					return err
 					return err
 				}
 				}
 				found = true
 				found = true
@@ -451,12 +446,11 @@ func (o MarshalOptions) marshalWrapperType(m pref.Message) error {
 func (o UnmarshalOptions) unmarshalWrapperType(m pref.Message) error {
 func (o UnmarshalOptions) unmarshalWrapperType(m pref.Message) error {
 	fd := m.Descriptor().Fields().ByNumber(wrapperFieldNumber)
 	fd := m.Descriptor().Fields().ByNumber(wrapperFieldNumber)
 	val, err := o.unmarshalScalar(fd)
 	val, err := o.unmarshalScalar(fd)
-	var nerr errors.NonFatal
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 	m.Set(fd, val)
 	m.Set(fd, val)
-	return nerr.E
+	return nil
 }
 }
 
 
 // The JSON representation for Empty is an empty JSON object.
 // The JSON representation for Empty is an empty JSON object.
@@ -468,7 +462,6 @@ func (o MarshalOptions) marshalEmpty(pref.Message) error {
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalEmpty(pref.Message) error {
 func (o UnmarshalOptions) unmarshalEmpty(pref.Message) error {
-	var nerr errors.NonFatal
 	jval, err := o.decoder.Read()
 	jval, err := o.decoder.Read()
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -479,16 +472,16 @@ func (o UnmarshalOptions) unmarshalEmpty(pref.Message) error {
 
 
 	for {
 	for {
 		jval, err := o.decoder.Read()
 		jval, err := o.decoder.Read()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 		switch jval.Type() {
 		switch jval.Type() {
 		case json.EndObject:
 		case json.EndObject:
-			return nerr.E
+			return nil
 
 
 		case json.Name:
 		case json.Name:
 			if o.DiscardUnknown {
 			if o.DiscardUnknown {
-				if err := skipJSONValue(o.decoder); !nerr.Merge(err) {
+				if err := skipJSONValue(o.decoder); err != nil {
 					return err
 					return err
 				}
 				}
 				continue
 				continue
@@ -543,7 +536,6 @@ func (o MarshalOptions) marshalKnownValue(m pref.Message) error {
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalKnownValue(m pref.Message) error {
 func (o UnmarshalOptions) unmarshalKnownValue(m pref.Message) error {
-	var nerr errors.NonFatal
 	switch o.decoder.Peek() {
 	switch o.decoder.Peek() {
 	case json.Null:
 	case json.Null:
 		o.decoder.Read()
 		o.decoder.Read()
@@ -582,11 +574,11 @@ func (o UnmarshalOptions) unmarshalKnownValue(m pref.Message) error {
 		// always assigned to the string_value field, which means that certain
 		// always assigned to the string_value field, which means that certain
 		// encoding cannot be parsed back to the same field.
 		// encoding cannot be parsed back to the same field.
 		jval, err := o.decoder.Read()
 		jval, err := o.decoder.Read()
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 		val, err := unmarshalString(jval)
 		val, err := unmarshalString(jval)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_StringValue)
 		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_StringValue)
@@ -595,7 +587,7 @@ func (o UnmarshalOptions) unmarshalKnownValue(m pref.Message) error {
 	case json.StartObject:
 	case json.StartObject:
 		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_StructValue)
 		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_StructValue)
 		m2 := m.NewMessage(fd)
 		m2 := m.NewMessage(fd)
-		if err := o.unmarshalStruct(m2); !nerr.Merge(err) {
+		if err := o.unmarshalStruct(m2); err != nil {
 			return err
 			return err
 		}
 		}
 		m.Set(fd, pref.ValueOf(m2))
 		m.Set(fd, pref.ValueOf(m2))
@@ -603,7 +595,7 @@ func (o UnmarshalOptions) unmarshalKnownValue(m pref.Message) error {
 	case json.StartArray:
 	case json.StartArray:
 		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_ListValue)
 		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_ListValue)
 		m2 := m.NewMessage(fd)
 		m2 := m.NewMessage(fd)
-		if err := o.unmarshalListValue(m2); !nerr.Merge(err) {
+		if err := o.unmarshalListValue(m2); err != nil {
 			return err
 			return err
 		}
 		}
 		m.Set(fd, pref.ValueOf(m2))
 		m.Set(fd, pref.ValueOf(m2))
@@ -615,7 +607,7 @@ func (o UnmarshalOptions) unmarshalKnownValue(m pref.Message) error {
 		}
 		}
 		return unexpectedJSONError{jval}
 		return unexpectedJSONError{jval}
 	}
 	}
-	return nerr.E
+	return nil
 }
 }
 
 
 // The JSON representation for a Duration is a JSON string that ends in the
 // The JSON representation for a Duration is a JSON string that ends in the
@@ -671,9 +663,8 @@ func (o MarshalOptions) marshalDuration(m pref.Message) error {
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalDuration(m pref.Message) error {
 func (o UnmarshalOptions) unmarshalDuration(m pref.Message) error {
-	var nerr errors.NonFatal
 	jval, err := o.decoder.Read()
 	jval, err := o.decoder.Read()
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 	if jval.Type() != json.String {
 	if jval.Type() != json.String {
@@ -697,7 +688,7 @@ func (o UnmarshalOptions) unmarshalDuration(m pref.Message) error {
 
 
 	m.Set(fdSeconds, pref.ValueOf(secs))
 	m.Set(fdSeconds, pref.ValueOf(secs))
 	m.Set(fdNanos, pref.ValueOf(nanos))
 	m.Set(fdNanos, pref.ValueOf(nanos))
-	return nerr.E
+	return nil
 }
 }
 
 
 // parseDuration parses the given input string for seconds and nanoseconds value
 // parseDuration parses the given input string for seconds and nanoseconds value
@@ -855,9 +846,8 @@ func (o MarshalOptions) marshalTimestamp(m pref.Message) error {
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalTimestamp(m pref.Message) error {
 func (o UnmarshalOptions) unmarshalTimestamp(m pref.Message) error {
-	var nerr errors.NonFatal
 	jval, err := o.decoder.Read()
 	jval, err := o.decoder.Read()
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 	if jval.Type() != json.String {
 	if jval.Type() != json.String {
@@ -882,7 +872,7 @@ func (o UnmarshalOptions) unmarshalTimestamp(m pref.Message) error {
 
 
 	m.Set(fdSeconds, pref.ValueOf(secs))
 	m.Set(fdSeconds, pref.ValueOf(secs))
 	m.Set(fdNanos, pref.ValueOf(int32(t.Nanosecond())))
 	m.Set(fdNanos, pref.ValueOf(int32(t.Nanosecond())))
-	return nerr.E
+	return nil
 }
 }
 
 
 // The JSON representation for a FieldMask is a JSON string where paths are
 // The JSON representation for a FieldMask is a JSON string where paths are
@@ -910,9 +900,8 @@ func (o MarshalOptions) marshalFieldMask(m pref.Message) error {
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalFieldMask(m pref.Message) error {
 func (o UnmarshalOptions) unmarshalFieldMask(m pref.Message) error {
-	var nerr errors.NonFatal
 	jval, err := o.decoder.Read()
 	jval, err := o.decoder.Read()
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 	if jval.Type() != json.String {
 	if jval.Type() != json.String {

+ 30 - 47
encoding/prototext/decode.go

@@ -45,8 +45,6 @@ type UnmarshalOptions struct {
 // Unmarshal reads the given []byte and populates the given proto.Message using options in
 // Unmarshal reads the given []byte and populates the given proto.Message using options in
 // UnmarshalOptions object.
 // UnmarshalOptions object.
 func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error {
 func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error {
-	var nerr errors.NonFatal
-
 	// Clear all fields before populating it.
 	// Clear all fields before populating it.
 	// TODO: Determine if this needs to be consistent with protojson and binary unmarshal where
 	// TODO: Determine if this needs to be consistent with protojson and binary unmarshal where
 	// behavior is to merge values into existing message. If decision is to not clear the fields
 	// behavior is to merge values into existing message. If decision is to not clear the fields
@@ -55,7 +53,7 @@ func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error {
 
 
 	// Parse into text.Value of message type.
 	// Parse into text.Value of message type.
 	val, err := text.Unmarshal(b)
 	val, err := text.Unmarshal(b)
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -63,21 +61,18 @@ func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error {
 		o.Resolver = protoregistry.GlobalTypes
 		o.Resolver = protoregistry.GlobalTypes
 	}
 	}
 	err = o.unmarshalMessage(val.Message(), m.ProtoReflect())
 	err = o.unmarshalMessage(val.Message(), m.ProtoReflect())
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	if !o.AllowPartial {
-		nerr.Merge(proto.IsInitialized(m))
+	if o.AllowPartial {
+		return nil
 	}
 	}
-
-	return nerr.E
+	return proto.IsInitialized(m)
 }
 }
 
 
 // unmarshalMessage unmarshals a [][2]text.Value message into the given protoreflect.Message.
 // unmarshalMessage unmarshals a [][2]text.Value message into the given protoreflect.Message.
 func (o UnmarshalOptions) unmarshalMessage(tmsg [][2]text.Value, m pref.Message) error {
 func (o UnmarshalOptions) unmarshalMessage(tmsg [][2]text.Value, m pref.Message) error {
-	var nerr errors.NonFatal
-
 	messageDesc := m.Descriptor()
 	messageDesc := m.Descriptor()
 
 
 	// Handle expanded Any message.
 	// Handle expanded Any message.
@@ -141,7 +136,7 @@ func (o UnmarshalOptions) unmarshalMessage(tmsg [][2]text.Value, m pref.Message)
 			}
 			}
 
 
 			list := m.Mutable(fd).List()
 			list := m.Mutable(fd).List()
-			if err := o.unmarshalList(items, fd, list); !nerr.Merge(err) {
+			if err := o.unmarshalList(items, fd, list); err != nil {
 				return err
 				return err
 			}
 			}
 		case fd.IsMap():
 		case fd.IsMap():
@@ -154,7 +149,7 @@ func (o UnmarshalOptions) unmarshalMessage(tmsg [][2]text.Value, m pref.Message)
 			}
 			}
 
 
 			mmap := m.Mutable(fd).Map()
 			mmap := m.Mutable(fd).Map()
-			if err := o.unmarshalMap(items, fd, mmap); !nerr.Merge(err) {
+			if err := o.unmarshalMap(items, fd, mmap); err != nil {
 				return err
 				return err
 			}
 			}
 		default:
 		default:
@@ -172,14 +167,14 @@ func (o UnmarshalOptions) unmarshalMessage(tmsg [][2]text.Value, m pref.Message)
 			if seenNums.Has(num) {
 			if seenNums.Has(num) {
 				return errors.New("non-repeated field %v is repeated", fd.FullName())
 				return errors.New("non-repeated field %v is repeated", fd.FullName())
 			}
 			}
-			if err := o.unmarshalSingular(tval, fd, m); !nerr.Merge(err) {
+			if err := o.unmarshalSingular(tval, fd, m); err != nil {
 				return err
 				return err
 			}
 			}
 			seenNums.Set(num)
 			seenNums.Set(num)
 		}
 		}
 	}
 	}
 
 
-	return nerr.E
+	return nil
 }
 }
 
 
 // findExtension returns protoreflect.ExtensionType from the Resolver if found.
 // findExtension returns protoreflect.ExtensionType from the Resolver if found.
@@ -199,7 +194,6 @@ func (o UnmarshalOptions) findExtension(xtName pref.FullName) (pref.ExtensionTyp
 
 
 // unmarshalSingular unmarshals given text.Value into the non-repeated field.
 // unmarshalSingular unmarshals given text.Value into the non-repeated field.
 func (o UnmarshalOptions) unmarshalSingular(input text.Value, fd pref.FieldDescriptor, m pref.Message) error {
 func (o UnmarshalOptions) unmarshalSingular(input text.Value, fd pref.FieldDescriptor, m pref.Message) error {
-	var nerr errors.NonFatal
 	var val pref.Value
 	var val pref.Value
 	switch fd.Kind() {
 	switch fd.Kind() {
 	case pref.MessageKind, pref.GroupKind:
 	case pref.MessageKind, pref.GroupKind:
@@ -207,20 +201,20 @@ func (o UnmarshalOptions) unmarshalSingular(input text.Value, fd pref.FieldDescr
 			return errors.New("%v contains invalid message/group value: %v", fd.FullName(), input)
 			return errors.New("%v contains invalid message/group value: %v", fd.FullName(), input)
 		}
 		}
 		m2 := m.NewMessage(fd)
 		m2 := m.NewMessage(fd)
-		if err := o.unmarshalMessage(input.Message(), m2); !nerr.Merge(err) {
+		if err := o.unmarshalMessage(input.Message(), m2); err != nil {
 			return err
 			return err
 		}
 		}
 		val = pref.ValueOf(m2)
 		val = pref.ValueOf(m2)
 	default:
 	default:
 		var err error
 		var err error
 		val, err = unmarshalScalar(input, fd)
 		val, err = unmarshalScalar(input, fd)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
 	m.Set(fd, val)
 	m.Set(fd, val)
 
 
-	return nerr.E
+	return nil
 }
 }
 
 
 // unmarshalScalar converts the given text.Value to a scalar/enum protoreflect.Value specified in
 // unmarshalScalar converts the given text.Value to a scalar/enum protoreflect.Value specified in
@@ -264,9 +258,7 @@ func unmarshalScalar(input text.Value, fd pref.FieldDescriptor) (pref.Value, err
 			if utf8.ValidString(s) {
 			if utf8.ValidString(s) {
 				return pref.ValueOf(s), nil
 				return pref.ValueOf(s), nil
 			}
 			}
-			var nerr errors.NonFatal
-			nerr.AppendInvalidUTF8(string(fd.FullName()))
-			return pref.ValueOf(s), nerr.E
+			return pref.Value{}, errors.InvalidUTF8(string(fd.FullName()))
 		}
 		}
 	case pref.BytesKind:
 	case pref.BytesKind:
 		if input.Type() == text.String {
 		if input.Type() == text.String {
@@ -292,8 +284,6 @@ func unmarshalScalar(input text.Value, fd pref.FieldDescriptor) (pref.Value, err
 
 
 // unmarshalList unmarshals given []text.Value into given protoreflect.List.
 // unmarshalList unmarshals given []text.Value into given protoreflect.List.
 func (o UnmarshalOptions) unmarshalList(inputList []text.Value, fd pref.FieldDescriptor, list pref.List) error {
 func (o UnmarshalOptions) unmarshalList(inputList []text.Value, fd pref.FieldDescriptor, list pref.List) error {
-	var nerr errors.NonFatal
-
 	switch fd.Kind() {
 	switch fd.Kind() {
 	case pref.MessageKind, pref.GroupKind:
 	case pref.MessageKind, pref.GroupKind:
 		for _, input := range inputList {
 		for _, input := range inputList {
@@ -301,7 +291,7 @@ func (o UnmarshalOptions) unmarshalList(inputList []text.Value, fd pref.FieldDes
 				return errors.New("%v contains invalid message/group value: %v", fd.FullName(), input)
 				return errors.New("%v contains invalid message/group value: %v", fd.FullName(), input)
 			}
 			}
 			m := list.NewMessage()
 			m := list.NewMessage()
-			if err := o.unmarshalMessage(input.Message(), m); !nerr.Merge(err) {
+			if err := o.unmarshalMessage(input.Message(), m); err != nil {
 				return err
 				return err
 			}
 			}
 			list.Append(pref.ValueOf(m))
 			list.Append(pref.ValueOf(m))
@@ -309,20 +299,18 @@ func (o UnmarshalOptions) unmarshalList(inputList []text.Value, fd pref.FieldDes
 	default:
 	default:
 		for _, input := range inputList {
 		for _, input := range inputList {
 			val, err := unmarshalScalar(input, fd)
 			val, err := unmarshalScalar(input, fd)
-			if !nerr.Merge(err) {
+			if err != nil {
 				return err
 				return err
 			}
 			}
 			list.Append(val)
 			list.Append(val)
 		}
 		}
 	}
 	}
 
 
-	return nerr.E
+	return nil
 }
 }
 
 
 // unmarshalMap unmarshals given []text.Value into given protoreflect.Map.
 // unmarshalMap unmarshals given []text.Value into given protoreflect.Map.
 func (o UnmarshalOptions) unmarshalMap(input []text.Value, fd pref.FieldDescriptor, mmap pref.Map) error {
 func (o UnmarshalOptions) unmarshalMap(input []text.Value, fd pref.FieldDescriptor, mmap pref.Map) error {
-	var nerr errors.NonFatal
-
 	// Determine ahead whether map entry is a scalar type or a message type in order to call the
 	// Determine ahead whether map entry is a scalar type or a message type in order to call the
 	// appropriate unmarshalMapValue func inside the for loop below.
 	// appropriate unmarshalMapValue func inside the for loop below.
 	unmarshalMapValue := unmarshalMapScalarValue
 	unmarshalMapValue := unmarshalMapScalarValue
@@ -336,20 +324,20 @@ func (o UnmarshalOptions) unmarshalMap(input []text.Value, fd pref.FieldDescript
 			return errors.New("%v contains invalid map entry: %v", fd.FullName(), entry)
 			return errors.New("%v contains invalid map entry: %v", fd.FullName(), entry)
 		}
 		}
 		tkey, tval, err := parseMapEntry(entry.Message(), fd.FullName())
 		tkey, tval, err := parseMapEntry(entry.Message(), fd.FullName())
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 		pkey, err := unmarshalMapKey(tkey, fd.MapKey())
 		pkey, err := unmarshalMapKey(tkey, fd.MapKey())
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 		err = unmarshalMapValue(tval, pkey, fd.MapValue(), mmap)
 		err = unmarshalMapValue(tval, pkey, fd.MapValue(), mmap)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
 
 
-	return nerr.E
+	return nil
 }
 }
 
 
 // parseMapEntry parses [][2]text.Value for field names key and value, and return corresponding
 // parseMapEntry parses [][2]text.Value for field names key and value, and return corresponding
@@ -391,46 +379,43 @@ func unmarshalMapKey(input text.Value, fd pref.FieldDescriptor) (pref.MapKey, er
 		return fd.Default().MapKey(), nil
 		return fd.Default().MapKey(), nil
 	}
 	}
 
 
-	var nerr errors.NonFatal
 	val, err := unmarshalScalar(input, fd)
 	val, err := unmarshalScalar(input, fd)
-	if !nerr.Merge(err) {
+	if err != nil {
 		return pref.MapKey{}, errors.New("%v contains invalid key: %v", fd.FullName(), input)
 		return pref.MapKey{}, errors.New("%v contains invalid key: %v", fd.FullName(), input)
 	}
 	}
-	return val.MapKey(), nerr.E
+	return val.MapKey(), nil
 }
 }
 
 
 // unmarshalMapMessageValue unmarshals given message-type text.Value into a protoreflect.Map for
 // unmarshalMapMessageValue unmarshals given message-type text.Value into a protoreflect.Map for
 // the given MapKey.
 // the given MapKey.
 func (o UnmarshalOptions) unmarshalMapMessageValue(input text.Value, pkey pref.MapKey, _ pref.FieldDescriptor, mmap pref.Map) error {
 func (o UnmarshalOptions) unmarshalMapMessageValue(input text.Value, pkey pref.MapKey, _ pref.FieldDescriptor, mmap pref.Map) error {
-	var nerr errors.NonFatal
 	var value [][2]text.Value
 	var value [][2]text.Value
 	if input.Type() != 0 {
 	if input.Type() != 0 {
 		value = input.Message()
 		value = input.Message()
 	}
 	}
 	m := mmap.NewMessage()
 	m := mmap.NewMessage()
-	if err := o.unmarshalMessage(value, m); !nerr.Merge(err) {
+	if err := o.unmarshalMessage(value, m); err != nil {
 		return err
 		return err
 	}
 	}
 	mmap.Set(pkey, pref.ValueOf(m))
 	mmap.Set(pkey, pref.ValueOf(m))
-	return nerr.E
+	return nil
 }
 }
 
 
 // unmarshalMapScalarValue unmarshals given scalar-type text.Value into a protoreflect.Map
 // unmarshalMapScalarValue unmarshals given scalar-type text.Value into a protoreflect.Map
 // for the given MapKey.
 // for the given MapKey.
 func unmarshalMapScalarValue(input text.Value, pkey pref.MapKey, fd pref.FieldDescriptor, mmap pref.Map) error {
 func unmarshalMapScalarValue(input text.Value, pkey pref.MapKey, fd pref.FieldDescriptor, mmap pref.Map) error {
-	var nerr errors.NonFatal
 	var val pref.Value
 	var val pref.Value
 	if input.Type() == 0 {
 	if input.Type() == 0 {
 		val = fd.Default()
 		val = fd.Default()
 	} else {
 	} else {
 		var err error
 		var err error
 		val, err = unmarshalScalar(input, fd)
 		val, err = unmarshalScalar(input, fd)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
 	mmap.Set(pkey, val)
 	mmap.Set(pkey, val)
-	return nerr.E
+	return nil
 }
 }
 
 
 // isExpandedAny returns true if given [][2]text.Value may be an expanded Any that contains only one
 // isExpandedAny returns true if given [][2]text.Value may be an expanded Any that contains only one
@@ -447,19 +432,17 @@ func isExpandedAny(tmsg [][2]text.Value) bool {
 // unmarshalAny unmarshals an expanded Any textproto. This method assumes that the given
 // unmarshalAny unmarshals an expanded Any textproto. This method assumes that the given
 // tfield has key type of text.String and value type of text.Message.
 // tfield has key type of text.String and value type of text.Message.
 func (o UnmarshalOptions) unmarshalAny(tfield [2]text.Value, m pref.Message) error {
 func (o UnmarshalOptions) unmarshalAny(tfield [2]text.Value, m pref.Message) error {
-	var nerr errors.NonFatal
-
 	typeURL := tfield[0].String()
 	typeURL := tfield[0].String()
 	value := tfield[1].Message()
 	value := tfield[1].Message()
 
 
 	mt, err := o.Resolver.FindMessageByURL(typeURL)
 	mt, err := o.Resolver.FindMessageByURL(typeURL)
-	if !nerr.Merge(err) {
+	if err != nil {
 		return errors.New("unable to resolve message [%v]: %v", typeURL, err)
 		return errors.New("unable to resolve message [%v]: %v", typeURL, err)
 	}
 	}
 	// Create new message for the embedded message type and unmarshal the
 	// Create new message for the embedded message type and unmarshal the
 	// value into it.
 	// value into it.
 	m2 := mt.New()
 	m2 := mt.New()
-	if err := o.unmarshalMessage(value, m2); !nerr.Merge(err) {
+	if err := o.unmarshalMessage(value, m2); err != nil {
 		return err
 		return err
 	}
 	}
 	// Serialize the embedded message and assign the resulting bytes to the value field.
 	// Serialize the embedded message and assign the resulting bytes to the value field.
@@ -467,7 +450,7 @@ func (o UnmarshalOptions) unmarshalAny(tfield [2]text.Value, m pref.Message) err
 		AllowPartial:  true, // never check required fields inside an Any
 		AllowPartial:  true, // never check required fields inside an Any
 		Deterministic: true,
 		Deterministic: true,
 	}.Marshal(m2.Interface())
 	}.Marshal(m2.Interface())
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -478,5 +461,5 @@ func (o UnmarshalOptions) unmarshalAny(tfield [2]text.Value, m pref.Message) err
 	m.Set(fdType, pref.ValueOf(typeURL))
 	m.Set(fdType, pref.ValueOf(typeURL))
 	m.Set(fdValue, pref.ValueOf(b))
 	m.Set(fdValue, pref.ValueOf(b))
 
 
-	return nerr.E
+	return nil
 }
 }

+ 3 - 44
encoding/prototext/decode_test.go

@@ -10,7 +10,6 @@ import (
 
 
 	protoV1 "github.com/golang/protobuf/proto"
 	protoV1 "github.com/golang/protobuf/proto"
 	"google.golang.org/protobuf/encoding/prototext"
 	"google.golang.org/protobuf/encoding/prototext"
-	"google.golang.org/protobuf/internal/errors"
 	pimpl "google.golang.org/protobuf/internal/impl"
 	pimpl "google.golang.org/protobuf/internal/impl"
 	"google.golang.org/protobuf/internal/scalar"
 	"google.golang.org/protobuf/internal/scalar"
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/proto"
@@ -157,10 +156,7 @@ s_string: "谷歌"
 		desc:         "string with invalid UTF-8",
 		desc:         "string with invalid UTF-8",
 		inputMessage: &pb3.Scalars{},
 		inputMessage: &pb3.Scalars{},
 		inputText:    `s_string: "abc\xff"`,
 		inputText:    `s_string: "abc\xff"`,
-		wantMessage: &pb3.Scalars{
-			SString: "abc\xff",
-		},
-		wantErr: true,
+		wantErr:      true,
 	}, {
 	}, {
 		desc:         "proto2 message contains unknown field",
 		desc:         "proto2 message contains unknown field",
 		inputMessage: &pb2.Scalars{},
 		inputMessage: &pb2.Scalars{},
@@ -459,11 +455,6 @@ s_nested: {
   s_string: "abc\xff"
   s_string: "abc\xff"
 }
 }
 `,
 `,
-		wantMessage: &pb3.Nests{
-			SNested: &pb3.Nested{
-				SString: "abc\xff",
-			},
-		},
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:         "oneof set to empty string",
 		desc:         "oneof set to empty string",
@@ -556,10 +547,7 @@ rpt_string: "b"
 		desc:         "repeated contains invalid UTF-8",
 		desc:         "repeated contains invalid UTF-8",
 		inputMessage: &pb2.Repeats{},
 		inputMessage: &pb2.Repeats{},
 		inputText:    `rpt_string: "abc\xff"`,
 		inputText:    `rpt_string: "abc\xff"`,
-		wantMessage: &pb2.Repeats{
-			RptString: []string{"abc\xff"},
-		},
-		wantErr: true,
+		wantErr:      true,
 	}, {
 	}, {
 		desc:         "repeated enums",
 		desc:         "repeated enums",
 		inputMessage: &pb2.Enums{},
 		inputMessage: &pb2.Enums{},
@@ -878,11 +866,6 @@ int32_to_str: {}
   value: "abc\xff"
   value: "abc\xff"
 }
 }
 `,
 `,
-		wantMessage: &pb3.Maps{
-			Int32ToStr: map[int32]string{
-				101: "abc\xff",
-			},
-		},
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:         "map field key contains invalid UTF-8",
 		desc:         "map field key contains invalid UTF-8",
@@ -892,11 +875,6 @@ int32_to_str: {}
   value: {}
   value: {}
 }
 }
 `,
 `,
-		wantMessage: &pb3.Maps{
-			StrToNested: map[string]*pb3.Nested{
-				"abc\xff": {},
-			},
-		},
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:         "map contains unknown field",
 		desc:         "map contains unknown field",
@@ -1196,12 +1174,7 @@ opt_int32: 42
 		desc:         "extension field contains invalid UTF-8",
 		desc:         "extension field contains invalid UTF-8",
 		inputMessage: &pb2.Extensions{},
 		inputMessage: &pb2.Extensions{},
 		inputText:    `[pb2.opt_ext_string]: "abc\xff"`,
 		inputText:    `[pb2.opt_ext_string]: "abc\xff"`,
-		wantMessage: func() proto.Message {
-			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_OptExtString, "abc\xff")
-			return m
-		}(),
-		wantErr: true,
+		wantErr:      true,
 	}, {
 	}, {
 		desc:         "extensions of repeated fields",
 		desc:         "extensions of repeated fields",
 		inputMessage: &pb2.Extensions{},
 		inputMessage: &pb2.Extensions{},
@@ -1466,20 +1439,6 @@ value: "some bytes"
   s_string: "abc\xff"
   s_string: "abc\xff"
 }
 }
 `,
 `,
-		wantMessage: func() proto.Message {
-			m := &pb3.Nested{
-				SString: "abc\xff",
-			}
-			var nerr errors.NonFatal
-			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
-			if !nerr.Merge(err) {
-				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
-			}
-			return &anypb.Any{
-				TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
-				Value:   b,
-			}
-		}(),
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:         "Any expanded with unregistered type",
 		desc:         "Any expanded with unregistered type",

+ 30 - 41
encoding/prototext/encode.go

@@ -53,38 +53,35 @@ func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
 		o.Resolver = protoregistry.GlobalTypes
 		o.Resolver = protoregistry.GlobalTypes
 	}
 	}
 
 
-	var nerr errors.NonFatal
 	v, err := o.marshalMessage(m.ProtoReflect())
 	v, err := o.marshalMessage(m.ProtoReflect())
-	if !nerr.Merge(err) {
+	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
 	delims := [2]byte{'{', '}'}
 	delims := [2]byte{'{', '}'}
 	const outputASCII = false
 	const outputASCII = false
 	b, err := text.Marshal(v, o.Indent, delims, outputASCII)
 	b, err := text.Marshal(v, o.Indent, delims, outputASCII)
-	if !nerr.Merge(err) {
+	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	if !o.AllowPartial {
-		nerr.Merge(proto.IsInitialized(m))
+	if o.AllowPartial {
+		return b, nil
 	}
 	}
-	return b, nerr.E
+	return b, proto.IsInitialized(m)
 }
 }
 
 
 // marshalMessage converts a protoreflect.Message to a text.Value.
 // marshalMessage converts a protoreflect.Message to a text.Value.
 func (o MarshalOptions) marshalMessage(m pref.Message) (text.Value, error) {
 func (o MarshalOptions) marshalMessage(m pref.Message) (text.Value, error) {
-	var nerr errors.NonFatal
 	var msgFields [][2]text.Value
 	var msgFields [][2]text.Value
 	messageDesc := m.Descriptor()
 	messageDesc := m.Descriptor()
 
 
 	// Handle Any expansion.
 	// Handle Any expansion.
 	if messageDesc.FullName() == "google.protobuf.Any" {
 	if messageDesc.FullName() == "google.protobuf.Any" {
-		msg, err := o.marshalAny(m)
-		if err == nil || nerr.Merge(err) {
-			// Return as is for nil or non-fatal error.
-			return msg, nerr.E
+		if msg, err := o.marshalAny(m); err == nil {
+			// Return as is if no error.
+			return msg, nil
 		}
 		}
-		// For other errors, continue on to marshal Any as a regular message.
+		// Otherwise continue on to marshal Any as a regular message.
 	}
 	}
 
 
 	// Handle known fields.
 	// Handle known fields.
@@ -104,7 +101,7 @@ func (o MarshalOptions) marshalMessage(m pref.Message) (text.Value, error) {
 		pval := m.Get(fd)
 		pval := m.Get(fd)
 		var err error
 		var err error
 		msgFields, err = o.appendField(msgFields, name, pval, fd)
 		msgFields, err = o.appendField(msgFields, name, pval, fd)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return text.Value{}, err
 			return text.Value{}, err
 		}
 		}
 	}
 	}
@@ -112,7 +109,7 @@ func (o MarshalOptions) marshalMessage(m pref.Message) (text.Value, error) {
 	// Handle extensions.
 	// Handle extensions.
 	var err error
 	var err error
 	msgFields, err = o.appendExtensions(msgFields, m)
 	msgFields, err = o.appendExtensions(msgFields, m)
-	if !nerr.Merge(err) {
+	if err != nil {
 		return text.Value{}, err
 		return text.Value{}, err
 	}
 	}
 
 
@@ -120,17 +117,15 @@ func (o MarshalOptions) marshalMessage(m pref.Message) (text.Value, error) {
 	// TODO: Provide option to exclude or include unknown fields.
 	// TODO: Provide option to exclude or include unknown fields.
 	msgFields = appendUnknown(msgFields, m.GetUnknown())
 	msgFields = appendUnknown(msgFields, m.GetUnknown())
 
 
-	return text.ValueOf(msgFields), nerr.E
+	return text.ValueOf(msgFields), nil
 }
 }
 
 
 // appendField marshals a protoreflect.Value and appends it to the given [][2]text.Value.
 // appendField marshals a protoreflect.Value and appends it to the given [][2]text.Value.
 func (o MarshalOptions) appendField(msgFields [][2]text.Value, name text.Value, pval pref.Value, fd pref.FieldDescriptor) ([][2]text.Value, error) {
 func (o MarshalOptions) appendField(msgFields [][2]text.Value, name text.Value, pval pref.Value, fd pref.FieldDescriptor) ([][2]text.Value, error) {
-	var nerr errors.NonFatal
-
 	switch {
 	switch {
 	case fd.IsList():
 	case fd.IsList():
 		items, err := o.marshalList(pval.List(), fd)
 		items, err := o.marshalList(pval.List(), fd)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return msgFields, err
 			return msgFields, err
 		}
 		}
 
 
@@ -139,7 +134,7 @@ func (o MarshalOptions) appendField(msgFields [][2]text.Value, name text.Value,
 		}
 		}
 	case fd.IsMap():
 	case fd.IsMap():
 		items, err := o.marshalMap(pval.Map(), fd)
 		items, err := o.marshalMap(pval.Map(), fd)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return msgFields, err
 			return msgFields, err
 		}
 		}
 
 
@@ -148,13 +143,13 @@ func (o MarshalOptions) appendField(msgFields [][2]text.Value, name text.Value,
 		}
 		}
 	default:
 	default:
 		tval, err := o.marshalSingular(pval, fd)
 		tval, err := o.marshalSingular(pval, fd)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return msgFields, err
 			return msgFields, err
 		}
 		}
 		msgFields = append(msgFields, [2]text.Value{name, tval})
 		msgFields = append(msgFields, [2]text.Value{name, tval})
 	}
 	}
 
 
-	return msgFields, nerr.E
+	return msgFields, nil
 }
 }
 
 
 // marshalSingular converts a non-repeated field value to text.Value.
 // marshalSingular converts a non-repeated field value to text.Value.
@@ -173,12 +168,10 @@ func (o MarshalOptions) marshalSingular(val pref.Value, fd pref.FieldDescriptor)
 
 
 	case pref.StringKind:
 	case pref.StringKind:
 		s := val.String()
 		s := val.String()
-		if utf8.ValidString(s) {
-			return text.ValueOf(s), nil
+		if !utf8.ValidString(s) {
+			return text.Value{}, errors.InvalidUTF8(string(fd.FullName()))
 		}
 		}
-		var nerr errors.NonFatal
-		nerr.AppendInvalidUTF8(string(fd.FullName()))
-		return text.ValueOf(s), nerr.E
+		return text.ValueOf(s), nil
 
 
 	case pref.EnumKind:
 	case pref.EnumKind:
 		num := val.Enum()
 		num := val.Enum()
@@ -197,21 +190,20 @@ func (o MarshalOptions) marshalSingular(val pref.Value, fd pref.FieldDescriptor)
 
 
 // marshalList converts a protoreflect.List to []text.Value.
 // marshalList converts a protoreflect.List to []text.Value.
 func (o MarshalOptions) marshalList(list pref.List, fd pref.FieldDescriptor) ([]text.Value, error) {
 func (o MarshalOptions) marshalList(list pref.List, fd pref.FieldDescriptor) ([]text.Value, error) {
-	var nerr errors.NonFatal
 	size := list.Len()
 	size := list.Len()
 	values := make([]text.Value, 0, size)
 	values := make([]text.Value, 0, size)
 
 
 	for i := 0; i < size; i++ {
 	for i := 0; i < size; i++ {
 		item := list.Get(i)
 		item := list.Get(i)
 		val, err := o.marshalSingular(item, fd)
 		val, err := o.marshalSingular(item, fd)
-		if !nerr.Merge(err) {
+		if err != nil {
 			// Return already marshaled values.
 			// Return already marshaled values.
 			return values, err
 			return values, err
 		}
 		}
 		values = append(values, val)
 		values = append(values, val)
 	}
 	}
 
 
-	return values, nerr.E
+	return values, nil
 }
 }
 
 
 var (
 var (
@@ -221,7 +213,6 @@ var (
 
 
 // marshalMap converts a protoreflect.Map to []text.Value.
 // marshalMap converts a protoreflect.Map to []text.Value.
 func (o MarshalOptions) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) ([]text.Value, error) {
 func (o MarshalOptions) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) ([]text.Value, error) {
-	var nerr errors.NonFatal
 	// values is a list of messages.
 	// values is a list of messages.
 	values := make([]text.Value, 0, mmap.Len())
 	values := make([]text.Value, 0, mmap.Len())
 
 
@@ -229,12 +220,12 @@ func (o MarshalOptions) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) ([]te
 	mapsort.Range(mmap, fd.MapKey().Kind(), func(key pref.MapKey, val pref.Value) bool {
 	mapsort.Range(mmap, fd.MapKey().Kind(), func(key pref.MapKey, val pref.Value) bool {
 		var keyTxtVal text.Value
 		var keyTxtVal text.Value
 		keyTxtVal, err = o.marshalSingular(key.Value(), fd.MapKey())
 		keyTxtVal, err = o.marshalSingular(key.Value(), fd.MapKey())
-		if !nerr.Merge(err) {
+		if err != nil {
 			return false
 			return false
 		}
 		}
 		var valTxtVal text.Value
 		var valTxtVal text.Value
 		valTxtVal, err = o.marshalSingular(val, fd.MapValue())
 		valTxtVal, err = o.marshalSingular(val, fd.MapValue())
-		if !nerr.Merge(err) {
+		if err != nil {
 			return false
 			return false
 		}
 		}
 		// Map entry (message) contains 2 fields, first field for key and second field for value.
 		// Map entry (message) contains 2 fields, first field for key and second field for value.
@@ -250,12 +241,11 @@ func (o MarshalOptions) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) ([]te
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	return values, nerr.E
+	return values, nil
 }
 }
 
 
 // appendExtensions marshals extension fields and appends them to the given [][2]text.Value.
 // appendExtensions marshals extension fields and appends them to the given [][2]text.Value.
 func (o MarshalOptions) appendExtensions(msgFields [][2]text.Value, m pref.Message) ([][2]text.Value, error) {
 func (o MarshalOptions) appendExtensions(msgFields [][2]text.Value, m pref.Message) ([][2]text.Value, error) {
-	var nerr errors.NonFatal
 	var err error
 	var err error
 	var entries [][2]text.Value
 	var entries [][2]text.Value
 	m.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
 	m.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
@@ -273,7 +263,7 @@ func (o MarshalOptions) appendExtensions(msgFields [][2]text.Value, m pref.Messa
 		// Use string type to produce [name] format.
 		// Use string type to produce [name] format.
 		tname := text.ValueOf(string(name))
 		tname := text.ValueOf(string(name))
 		entries, err = o.appendField(entries, tname, v, xt)
 		entries, err = o.appendField(entries, tname, v, xt)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return false
 			return false
 		}
 		}
 		err = nil
 		err = nil
@@ -287,7 +277,7 @@ func (o MarshalOptions) appendExtensions(msgFields [][2]text.Value, m pref.Messa
 	sort.SliceStable(entries, func(i, j int) bool {
 	sort.SliceStable(entries, func(i, j int) bool {
 		return entries[i][0].String() < entries[j][0].String()
 		return entries[i][0].String() < entries[j][0].String()
 	})
 	})
-	return append(msgFields, entries...), nerr.E
+	return append(msgFields, entries...), nil
 }
 }
 
 
 // isMessageSetExtension reports whether extension extends a message set.
 // isMessageSetExtension reports whether extension extends a message set.
@@ -348,9 +338,8 @@ func (o MarshalOptions) marshalAny(m pref.Message) (text.Value, error) {
 	typeURL := m.Get(fdType).String()
 	typeURL := m.Get(fdType).String()
 	value := m.Get(fdValue)
 	value := m.Get(fdValue)
 
 
-	var nerr errors.NonFatal
 	emt, err := o.Resolver.FindMessageByURL(typeURL)
 	emt, err := o.Resolver.FindMessageByURL(typeURL)
-	if !nerr.Merge(err) {
+	if err != nil {
 		return text.Value{}, err
 		return text.Value{}, err
 	}
 	}
 	em := emt.New().Interface()
 	em := emt.New().Interface()
@@ -358,12 +347,12 @@ func (o MarshalOptions) marshalAny(m pref.Message) (text.Value, error) {
 		AllowPartial: true,
 		AllowPartial: true,
 		Resolver:     o.Resolver,
 		Resolver:     o.Resolver,
 	}.Unmarshal(value.Bytes(), em)
 	}.Unmarshal(value.Bytes(), em)
-	if !nerr.Merge(err) {
+	if err != nil {
 		return text.Value{}, err
 		return text.Value{}, err
 	}
 	}
 
 
 	msg, err := o.marshalMessage(em.ProtoReflect())
 	msg, err := o.marshalMessage(em.ProtoReflect())
-	if !nerr.Merge(err) {
+	if err != nil {
 		return text.Value{}, err
 		return text.Value{}, err
 	}
 	}
 	// Expanded Any field value contains only a single field with the type_url field value as the
 	// Expanded Any field value contains only a single field with the type_url field value as the
@@ -374,5 +363,5 @@ func (o MarshalOptions) marshalAny(m pref.Message) (text.Value, error) {
 			msg,
 			msg,
 		},
 		},
 	}
 	}
-	return text.ValueOf(msgFields), nerr.E
+	return text.ValueOf(msgFields), nil
 }
 }

+ 0 - 44
encoding/prototext/encode_test.go

@@ -5,7 +5,6 @@
 package prototext_test
 package prototext_test
 
 
 import (
 import (
-	"bytes"
 	"encoding/hex"
 	"encoding/hex"
 	"math"
 	"math"
 	"testing"
 	"testing"
@@ -162,8 +161,6 @@ opt_string: "谷歌"
 		input: &pb3.Scalars{
 		input: &pb3.Scalars{
 			SString: "abc\xff",
 			SString: "abc\xff",
 		},
 		},
-		want: `s_string: "abc\xff"
-`,
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "float nan",
 		desc: "float nan",
@@ -366,10 +363,6 @@ OptGroup: {}
 				SString: "abc\xff",
 				SString: "abc\xff",
 			},
 			},
 		},
 		},
-		want: `s_nested: {
-  s_string: "abc\xff"
-}
-`,
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc:  "oneof not set",
 		desc:  "oneof not set",
@@ -485,8 +478,6 @@ rpt_bytes: "世界"
 		input: &pb2.Repeats{
 		input: &pb2.Repeats{
 			RptString: []string{"abc\xff"},
 			RptString: []string{"abc\xff"},
 		},
 		},
-		want: `rpt_string: "abc\xff"
-`,
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "repeated enums",
 		desc: "repeated enums",
@@ -693,11 +684,6 @@ str_to_oneofs: {
 				101: "abc\xff",
 				101: "abc\xff",
 			},
 			},
 		},
 		},
-		want: `int32_to_str: {
-  key: 101
-  value: "abc\xff"
-}
-`,
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "map field key contains invalid UTF-8",
 		desc: "map field key contains invalid UTF-8",
@@ -706,11 +692,6 @@ str_to_oneofs: {
 				"abc\xff": {},
 				"abc\xff": {},
 			},
 			},
 		},
 		},
-		want: `str_to_nested: {
-  key: "abc\xff"
-  value: {}
-}
-`,
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "map field contains nil value",
 		desc: "map field contains nil value",
@@ -967,8 +948,6 @@ opt_int32: 42
 			setExtension(m, pb2.E_OptExtString, "abc\xff")
 			setExtension(m, pb2.E_OptExtString, "abc\xff")
 			return m
 			return m
 		}(),
 		}(),
-		want: `[pb2.opt_ext_string]: "abc\xff"
-`,
 		wantErr: true,
 		wantErr: true,
 	}, {
 	}, {
 		desc: "extension partial returns error",
 		desc: "extension partial returns error",
@@ -1220,29 +1199,6 @@ value: "\n\x13embedded inside Any\x12\x0b\n\tinception"
   opt_string: "embedded inside Any"
   opt_string: "embedded inside Any"
 }
 }
 `,
 `,
-	}, {
-		desc: "Any with invalid UTF-8",
-		mo: prototext.MarshalOptions{
-			Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb3.Nested{})),
-		},
-		input: func() proto.Message {
-			m := &pb3.Nested{
-				SString: "abcd",
-			}
-			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
-			if err != nil {
-				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
-			}
-			return &anypb.Any{
-				TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
-				Value:   bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1),
-			}
-		}(),
-		want: `[pb3.Nested]: {
-  s_string: "abc\xff"
-}
-`,
-		wantErr: true,
 	}, {
 	}, {
 		desc: "Any with invalid value",
 		desc: "Any with invalid value",
 		mo: prototext.MarshalOptions{
 		mo: prototext.MarshalOptions{

+ 8 - 12
internal/cmd/generate-types/proto.go

@@ -261,9 +261,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp wire.Type, fd protorefl
 		}
 		}
 		{{if (eq .Name "String") -}}
 		{{if (eq .Name "String") -}}
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.Valid(v) {
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.Valid(v) {
-			var nerr errors.NonFatal
-			nerr.AppendInvalidUTF8(string(fd.FullName()))
-			return protoreflect.ValueOf(string(v)), n, nerr.E
+			return protoreflect.Value{}, 0, errors.InvalidUTF8(string(fd.FullName()))
 		}
 		}
 		{{end -}}
 		{{end -}}
 		return protoreflect.ValueOf({{.ToValue}}), n, nil
 		return protoreflect.ValueOf({{.ToValue}}), n, nil
@@ -274,7 +272,6 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp wire.Type, fd protorefl
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protoreflect.List, fd protoreflect.FieldDescriptor) (n int, err error) {
 func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protoreflect.List, fd protoreflect.FieldDescriptor) (n int, err error) {
-	var nerr errors.NonFatal
 	switch fd.Kind() {
 	switch fd.Kind() {
 	{{- range .}}
 	{{- range .}}
 	case {{.Expr}}:
 	case {{.Expr}}:
@@ -308,19 +305,19 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 		}
 		}
 		{{if (eq .Name "String") -}}
 		{{if (eq .Name "String") -}}
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.Valid(v) {
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.Valid(v) {
-			nerr.AppendInvalidUTF8(string(fd.FullName()))
+			return 0, errors.InvalidUTF8(string(fd.FullName()))
 		}
 		}
 		{{end -}}
 		{{end -}}
 		{{if or (eq .Name "Message") (eq .Name "Group") -}}
 		{{if or (eq .Name "Message") (eq .Name "Group") -}}
 		m := list.NewMessage()
 		m := list.NewMessage()
-		if err := o.unmarshalMessage(v, m); !nerr.Merge(err) {
+		if err := o.unmarshalMessage(v, m); err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
 		list.Append(protoreflect.ValueOf(m))
 		list.Append(protoreflect.ValueOf(m))
 		{{- else -}}
 		{{- else -}}
 		list.Append(protoreflect.ValueOf({{.ToValue}}))
 		list.Append(protoreflect.ValueOf({{.ToValue}}))
 		{{- end}}
 		{{- end}}
-		return n, nerr.E
+		return n, nil
 	{{- end}}
 	{{- end}}
 	default:
 	default:
 		return 0, errUnknown
 		return 0, errUnknown
@@ -340,13 +337,12 @@ var wireTypes = map[protoreflect.Kind]wire.Type{
 }
 }
 
 
 func (o MarshalOptions) marshalSingular(b []byte, fd protoreflect.FieldDescriptor, v protoreflect.Value) ([]byte, error) {
 func (o MarshalOptions) marshalSingular(b []byte, fd protoreflect.FieldDescriptor, v protoreflect.Value) ([]byte, error) {
-	var nerr errors.NonFatal
 	switch fd.Kind() {
 	switch fd.Kind() {
 	{{- range .}}
 	{{- range .}}
 	case {{.Expr}}:
 	case {{.Expr}}:
 		{{- if (eq .Name "String") }}
 		{{- if (eq .Name "String") }}
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.ValidString(v.String()) {
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.ValidString(v.String()) {
-			nerr.AppendInvalidUTF8(string(fd.FullName()))
+			return b, errors.InvalidUTF8(string(fd.FullName()))
 		}
 		}
 		{{end -}}
 		{{end -}}
 		{{- if (eq .Name "Message") -}}
 		{{- if (eq .Name "Message") -}}
@@ -354,14 +350,14 @@ func (o MarshalOptions) marshalSingular(b []byte, fd protoreflect.FieldDescripto
 		var err error
 		var err error
 		b, pos = appendSpeculativeLength(b)
 		b, pos = appendSpeculativeLength(b)
 		b, err = o.marshalMessage(b, v.Message())
 		b, err = o.marshalMessage(b, v.Message())
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 		b = finishSpeculativeLength(b, pos)
 		b = finishSpeculativeLength(b, pos)
 		{{- else if (eq .Name "Group") -}}
 		{{- else if (eq .Name "Group") -}}
 		var err error
 		var err error
 		b, err = o.marshalMessage(b, v.Message())
 		b, err = o.marshalMessage(b, v.Message())
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 		b = wire.AppendVarint(b, wire.EncodeTag(fd.Number(), wire.EndGroupType))
 		b = wire.AppendVarint(b, wire.EncodeTag(fd.Number(), wire.EndGroupType))
@@ -372,7 +368,7 @@ func (o MarshalOptions) marshalSingular(b []byte, fd protoreflect.FieldDescripto
 	default:
 	default:
 		return b, errors.New("invalid kind %v", fd.Kind())
 		return b, errors.New("invalid kind %v", fd.Kind())
 	}
 	}
-	return b, nerr.E
+	return b, nil
 }
 }
 `))
 `))
 
 

+ 4 - 6
internal/encoding/json/decode.go

@@ -69,9 +69,8 @@ func (d *Decoder) Read() (Value, error) {
 		return d.value, d.err
 		return d.value, d.err
 	}
 	}
 
 
-	var nerr errors.NonFatal
 	value, err := d.parseNext()
 	value, err := d.parseNext()
-	if !nerr.Merge(err) {
+	if err != nil {
 		return Value{}, err
 		return Value{}, err
 	}
 	}
 	n := value.size
 	n := value.size
@@ -145,7 +144,7 @@ func (d *Decoder) Read() (Value, error) {
 	if d.value.typ == comma {
 	if d.value.typ == comma {
 		return d.Read()
 		return d.Read()
 	}
 	}
-	return value, nerr.E
+	return value, nil
 }
 }
 
 
 // Any sequence that looks like a non-delimiter (for error reporting).
 // Any sequence that looks like a non-delimiter (for error reporting).
@@ -193,12 +192,11 @@ func (d *Decoder) parseNext() (value Value, err error) {
 		return d.newValue(Number, in, n), nil
 		return d.newValue(Number, in, n), nil
 
 
 	case '"':
 	case '"':
-		var nerr errors.NonFatal
 		s, n, err := d.parseString(in)
 		s, n, err := d.parseString(in)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return Value{}, err
 			return Value{}, err
 		}
 		}
-		return d.newStringValue(in, n, s), nerr.E
+		return d.newStringValue(in, n, s), nil
 
 
 	case '{':
 	case '{':
 		return d.newValue(StartObject, in, 1), nil
 		return d.newValue(StartObject, in, 1), nil

+ 1 - 4
internal/encoding/json/decode_test.go

@@ -121,10 +121,7 @@ func TestDecoder(t *testing.T) {
 		{
 		{
 			// Invalid UTF-8 error is returned in ReadString instead of Read.
 			// Invalid UTF-8 error is returned in ReadString instead of Read.
 			input: "\"\xff\"",
 			input: "\"\xff\"",
-			want: []R{
-				{T: json.String, E: `invalid UTF-8 detected`, V: string("\xff")},
-				{T: json.EOF},
-			},
+			want:  []R{{E: `syntax error (line 1:1): invalid UTF-8 in string`}},
 		},
 		},
 		{
 		{
 			input: `"` + string(utf8.RuneError) + `"`,
 			input: `"` + string(utf8.RuneError) + `"`,

+ 0 - 13
internal/encoding/json/encode_test.go

@@ -349,19 +349,6 @@ func TestEncoder(t *testing.T) {
 		]
 		]
 	]
 	]
 }`,
 }`,
-		},
-		{
-			desc: "string contains rune error",
-			write: func(e *json.Encoder) {
-				// WriteString returns non-fatal error for invalid UTF sequence, but
-				// should still output the written value. See TestWriteStringError
-				// below that checks for this.
-				e.StartObject()
-				e.WriteName("invalid rune")
-				e.WriteString("abc\xff")
-				e.EndObject()
-			},
-			wantOut: "{\"invalid rune\":\"abc\xff\"}",
 		}}
 		}}
 
 
 	for _, tc := range tests {
 	for _, tc := range tests {

+ 4 - 8
internal/encoding/json/string.go

@@ -16,15 +16,13 @@ import (
 )
 )
 
 
 func appendString(out []byte, in string) ([]byte, error) {
 func appendString(out []byte, in string) ([]byte, error) {
-	var nerr errors.NonFatal
 	out = append(out, '"')
 	out = append(out, '"')
 	i := indexNeedEscapeInString(in)
 	i := indexNeedEscapeInString(in)
 	in, out = in[i:], append(out, in[:i]...)
 	in, out = in[i:], append(out, in[:i]...)
 	for len(in) > 0 {
 	for len(in) > 0 {
 		switch r, n := utf8.DecodeRuneInString(in); {
 		switch r, n := utf8.DecodeRuneInString(in); {
 		case r == utf8.RuneError && n == 1:
 		case r == utf8.RuneError && n == 1:
-			nerr.AppendInvalidUTF8("")
-			in, out = in[1:], append(out, in[0]) // preserve invalid byte
+			return out, errors.InvalidUTF8("")
 		case r < ' ' || r == '"' || r == '\\':
 		case r < ' ' || r == '"' || r == '\\':
 			out = append(out, '\\')
 			out = append(out, '\\')
 			switch r {
 			switch r {
@@ -52,11 +50,10 @@ func appendString(out []byte, in string) ([]byte, error) {
 		}
 		}
 	}
 	}
 	out = append(out, '"')
 	out = append(out, '"')
-	return out, nerr.E
+	return out, nil
 }
 }
 
 
 func (d *Decoder) parseString(in []byte) (string, int, error) {
 func (d *Decoder) parseString(in []byte) (string, int, error) {
-	var nerr errors.NonFatal
 	in0 := in
 	in0 := in
 	if len(in) == 0 {
 	if len(in) == 0 {
 		return "", 0, io.ErrUnexpectedEOF
 		return "", 0, io.ErrUnexpectedEOF
@@ -70,14 +67,13 @@ func (d *Decoder) parseString(in []byte) (string, int, error) {
 	for len(in) > 0 {
 	for len(in) > 0 {
 		switch r, n := utf8.DecodeRune(in); {
 		switch r, n := utf8.DecodeRune(in); {
 		case r == utf8.RuneError && n == 1:
 		case r == utf8.RuneError && n == 1:
-			nerr.AppendInvalidUTF8("")
-			in, out = in[1:], append(out, in[0]) // preserve invalid byte
+			return "", 0, d.newSyntaxError("invalid UTF-8 in string")
 		case r < ' ':
 		case r < ' ':
 			return "", 0, d.newSyntaxError("invalid character %q in string", r)
 			return "", 0, d.newSyntaxError("invalid character %q in string", r)
 		case r == '"':
 		case r == '"':
 			in = in[1:]
 			in = in[1:]
 			n := len(in0) - len(in)
 			n := len(in0) - len(in)
-			return string(out), n, nerr.E
+			return string(out), n, nil
 		case r == '\\':
 		case r == '\\':
 			if len(in) < 2 {
 			if len(in) < 2 {
 				return "", 0, io.ErrUnexpectedEOF
 				return "", 0, io.ErrUnexpectedEOF

+ 7 - 8
internal/encoding/text/decode.go

@@ -26,7 +26,7 @@ func Unmarshal(b []byte) (Value, error) {
 	p := decoder{in: b}
 	p := decoder{in: b}
 	p.consume(0) // trim leading spaces or comments
 	p.consume(0) // trim leading spaces or comments
 	v, err := p.unmarshalMessage(false)
 	v, err := p.unmarshalMessage(false)
-	if !p.nerr.Merge(err) {
+	if err != nil {
 		if e, ok := err.(syntaxError); ok {
 		if e, ok := err.(syntaxError); ok {
 			b = b[:len(b)-len(p.in)] // consumed input
 			b = b[:len(b)-len(p.in)] // consumed input
 			line := bytes.Count(b, []byte("\n")) + 1
 			line := bytes.Count(b, []byte("\n")) + 1
@@ -41,12 +41,11 @@ func Unmarshal(b []byte) (Value, error) {
 	if len(p.in) > 0 {
 	if len(p.in) > 0 {
 		return Value{}, errors.New("%d bytes of unconsumed input", len(p.in))
 		return Value{}, errors.New("%d bytes of unconsumed input", len(p.in))
 	}
 	}
-	return v, p.nerr.E
+	return v, nil
 }
 }
 
 
 type decoder struct {
 type decoder struct {
-	nerr errors.NonFatal
-	in   []byte
+	in []byte
 }
 }
 
 
 func (p *decoder) unmarshalList() (Value, error) {
 func (p *decoder) unmarshalList() (Value, error) {
@@ -58,7 +57,7 @@ func (p *decoder) unmarshalList() (Value, error) {
 	if len(p.in) > 0 && p.in[0] != ']' {
 	if len(p.in) > 0 && p.in[0] != ']' {
 		for len(p.in) > 0 {
 		for len(p.in) > 0 {
 			v, err := p.unmarshalValue()
 			v, err := p.unmarshalValue()
-			if !p.nerr.Merge(err) {
+			if err != nil {
 				return Value{}, err
 				return Value{}, err
 			}
 			}
 			elems = append(elems, v)
 			elems = append(elems, v)
@@ -91,14 +90,14 @@ func (p *decoder) unmarshalMessage(checkDelims bool) (Value, error) {
 			break
 			break
 		}
 		}
 		k, err := p.unmarshalKey()
 		k, err := p.unmarshalKey()
-		if !p.nerr.Merge(err) {
+		if err != nil {
 			return Value{}, err
 			return Value{}, err
 		}
 		}
 		if !p.tryConsumeChar(':') && len(p.in) > 0 && p.in[0] != '{' && p.in[0] != '<' {
 		if !p.tryConsumeChar(':') && len(p.in) > 0 && p.in[0] != '{' && p.in[0] != '<' {
 			return Value{}, newSyntaxError("expected ':' after message key")
 			return Value{}, newSyntaxError("expected ':' after message key")
 		}
 		}
 		v, err := p.unmarshalValue()
 		v, err := p.unmarshalValue()
-		if !p.nerr.Merge(err) {
+		if err != nil {
 			return Value{}, err
 			return Value{}, err
 		}
 		}
 		if p.tryConsumeChar(';') || p.tryConsumeChar(',') {
 		if p.tryConsumeChar(';') || p.tryConsumeChar(',') {
@@ -132,7 +131,7 @@ func (p *decoder) unmarshalKey() (v Value, err error) {
 			// This is specific to Go and contrary to the C++ implementation,
 			// This is specific to Go and contrary to the C++ implementation,
 			// which does not support strings for the Any type URL.
 			// which does not support strings for the Any type URL.
 			v, err = p.unmarshalString()
 			v, err = p.unmarshalString()
-			if !p.nerr.Merge(err) {
+			if err != nil {
 				return Value{}, err
 				return Value{}, err
 			}
 			}
 		} else if n := matchWithDelim(urlRegexp, p.in); n > 0 {
 		} else if n := matchWithDelim(urlRegexp, p.in); n > 0 {

+ 7 - 8
internal/encoding/text/encode.go

@@ -45,18 +45,17 @@ func Marshal(v Value, indent string, delims [2]byte, outputASCII bool) ([]byte,
 	p.outputASCII = outputASCII
 	p.outputASCII = outputASCII
 
 
 	err := p.marshalMessage(v, false)
 	err := p.marshalMessage(v, false)
-	if !p.nerr.Merge(err) {
+	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 	if len(indent) > 0 {
 	if len(indent) > 0 {
-		return append(bytes.TrimRight(p.out, "\n"), '\n'), p.nerr.E
+		return append(bytes.TrimRight(p.out, "\n"), '\n'), nil
 	}
 	}
-	return p.out, p.nerr.E
+	return p.out, nil
 }
 }
 
 
 type encoder struct {
 type encoder struct {
-	nerr errors.NonFatal
-	out  []byte
+	out []byte
 
 
 	indent      string
 	indent      string
 	indents     []byte
 	indents     []byte
@@ -77,7 +76,7 @@ func (p *encoder) marshalList(v Value) error {
 	}
 	}
 	for i, elem := range elems {
 	for i, elem := range elems {
 		p.out = append(p.out, p.indents...)
 		p.out = append(p.out, p.indents...)
-		if err := p.marshalValue(elem); !p.nerr.Merge(err) {
+		if err := p.marshalValue(elem); err != nil {
 			return err
 			return err
 		}
 		}
 		if i < len(elems)-1 {
 		if i < len(elems)-1 {
@@ -107,7 +106,7 @@ func (p *encoder) marshalMessage(v Value, emitDelims bool) error {
 	}
 	}
 	for i, item := range items {
 	for i, item := range items {
 		p.out = append(p.out, p.indents...)
 		p.out = append(p.out, p.indents...)
-		if err := p.marshalKey(item[0]); !p.nerr.Merge(err) {
+		if err := p.marshalKey(item[0]); err != nil {
 			return err
 			return err
 		}
 		}
 		p.out = append(p.out, ':')
 		p.out = append(p.out, ':')
@@ -120,7 +119,7 @@ func (p *encoder) marshalMessage(v Value, emitDelims bool) error {
 			p.out = append(p.out, ' ')
 			p.out = append(p.out, ' ')
 		}
 		}
 
 
-		if err := p.marshalValue(item[1]); !p.nerr.Merge(err) {
+		if err := p.marshalValue(item[1]); err != nil {
 			return err
 			return err
 		}
 		}
 		if i < len(items)-1 && len(p.indent) == 0 {
 		if i < len(items)-1 && len(p.indent) == 0 {

+ 3 - 5
internal/encoding/text/string.go

@@ -86,7 +86,6 @@ func (p *decoder) unmarshalString() (Value, error) {
 	return v, err
 	return v, err
 }
 }
 func consumeString(in []byte) (Value, int, error) {
 func consumeString(in []byte) (Value, int, error) {
-	var nerr errors.NonFatal
 	in0 := in
 	in0 := in
 	if len(in) == 0 {
 	if len(in) == 0 {
 		return Value{}, 0, io.ErrUnexpectedEOF
 		return Value{}, 0, io.ErrUnexpectedEOF
@@ -101,15 +100,14 @@ func consumeString(in []byte) (Value, int, error) {
 	for len(in) > 0 {
 	for len(in) > 0 {
 		switch r, n := utf8.DecodeRune(in); {
 		switch r, n := utf8.DecodeRune(in); {
 		case r == utf8.RuneError && n == 1:
 		case r == utf8.RuneError && n == 1:
-			nerr.AppendInvalidUTF8("")
-			in, out = in[1:], append(out, in[0]) // preserve invalid byte
+			return Value{}, 0, newSyntaxError("invalid UTF-8 detected")
 		case r == 0 || r == '\n':
 		case r == 0 || r == '\n':
 			return Value{}, 0, newSyntaxError("invalid character %q in string", r)
 			return Value{}, 0, newSyntaxError("invalid character %q in string", r)
 		case r == rune(quote):
 		case r == rune(quote):
 			in = in[1:]
 			in = in[1:]
 			n := len(in0) - len(in)
 			n := len(in0) - len(in)
 			v := rawValueOf(string(out), in0[:n:n])
 			v := rawValueOf(string(out), in0[:n:n])
-			return v, n, nerr.E
+			return v, n, nil
 		case r == '\\':
 		case r == '\\':
 			if len(in) < 2 {
 			if len(in) < 2 {
 				return Value{}, 0, io.ErrUnexpectedEOF
 				return Value{}, 0, io.ErrUnexpectedEOF
@@ -208,7 +206,7 @@ func (p *decoder) unmarshalStrings() (Value, error) {
 	var ss []string
 	var ss []string
 	for len(p.in) > 0 && (p.in[0] == '"' || p.in[0] == '\'') {
 	for len(p.in) > 0 && (p.in[0] == '"' || p.in[0] == '\'') {
 		v, err := p.unmarshalString()
 		v, err := p.unmarshalString()
-		if !p.nerr.Merge(err) {
+		if err != nil {
 			return Value{}, err
 			return Value{}, err
 		}
 		}
 		ss = append(ss, v.String())
 		ss = append(ss, v.String())

+ 8 - 20
internal/encoding/text/text_test.go

@@ -354,32 +354,20 @@ func Test(t *testing.T) {
 		wantOut:      `str:"\x01\x02\x03\x04\x05\x06\x07\x08\t\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_` + "`abcdefghijklmnopqrstuvwxyz{|}~\x7f\"",
 		wantOut:      `str:"\x01\x02\x03\x04\x05\x06\x07\x08\t\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_` + "`abcdefghijklmnopqrstuvwxyz{|}~\x7f\"",
 		wantOutASCII: `str:"\x01\x02\x03\x04\x05\x06\x07\x08\t\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_` + "`abcdefghijklmnopqrstuvwxyz{|}~\x7f\"",
 		wantOutASCII: `str:"\x01\x02\x03\x04\x05\x06\x07\x08\t\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_` + "`abcdefghijklmnopqrstuvwxyz{|}~\x7f\"",
 	}, {
 	}, {
-		in:           "str: '\xde\xad\xbe\xef'",
-		wantVal:      V(Msg{{ID("str"), V("\xde\xad\xbe\xef")}}),
-		wantOut:      "str:\"\u07ad\\xbe\\xef\"",
-		wantOutASCII: `str:"\u07ad\xbe\xef"`,
-		wantErr:      "invalid UTF-8 detected",
+		in:      "str: '\xde\xad\xbe\xef'",
+		wantErr: "invalid UTF-8 detected",
 	}, {
 	}, {
 		// Valid UTF-8 wire encoding, but sub-optimal encoding.
 		// Valid UTF-8 wire encoding, but sub-optimal encoding.
-		in:           "str: '\xc0\x80'",
-		wantVal:      V(Msg{{ID("str"), V("\xc0\x80")}}),
-		wantOut:      `str:"\xc0\x80"`,
-		wantOutASCII: `str:"\xc0\x80"`,
-		wantErr:      "invalid UTF-8 detected",
+		in:      "str: '\xc0\x80'",
+		wantErr: "invalid UTF-8 detected",
 	}, {
 	}, {
 		// Valid UTF-8 wire encoding, but invalid rune (surrogate pair).
 		// Valid UTF-8 wire encoding, but invalid rune (surrogate pair).
-		in:           "str: '\xed\xa0\x80'",
-		wantVal:      V(Msg{{ID("str"), V("\xed\xa0\x80")}}),
-		wantOut:      `str:"\xed\xa0\x80"`,
-		wantOutASCII: `str:"\xed\xa0\x80"`,
-		wantErr:      "invalid UTF-8 detected",
+		in:      "str: '\xed\xa0\x80'",
+		wantErr: "invalid UTF-8 detected",
 	}, {
 	}, {
 		// Valid UTF-8 wire encoding, but invalid rune (above max rune).
 		// Valid UTF-8 wire encoding, but invalid rune (above max rune).
-		in:           "str: '\xf7\xbf\xbf\xbf'",
-		wantVal:      V(Msg{{ID("str"), V("\xf7\xbf\xbf\xbf")}}),
-		wantOut:      `str:"\xf7\xbf\xbf\xbf"`,
-		wantOutASCII: `str:"\xf7\xbf\xbf\xbf"`,
-		wantErr:      "invalid UTF-8 detected",
+		in:      "str: '\xf7\xbf\xbf\xbf'",
+		wantErr: "invalid UTF-8 detected",
 	}, {
 	}, {
 		// Valid UTF-8 wire encoding of the RuneError rune.
 		// Valid UTF-8 wire encoding of the RuneError rune.
 		in:           "str: '\xef\xbf\xbd'",
 		in:           "str: '\xef\xbf\xbd'",

+ 1 - 1
internal/encoding/text/value.go

@@ -327,7 +327,7 @@ func (v Value) Raw() []byte {
 		return v.raw
 		return v.raw
 	}
 	}
 	p := encoder{}
 	p := encoder{}
-	if err := p.marshalValue(v); !p.nerr.Merge(err) {
+	if err := p.marshalValue(v); err != nil {
 		return []byte("<invalid>")
 		return []byte("<invalid>")
 	}
 	}
 	return p.out
 	return p.out

+ 8 - 103
internal/errors/errors.go

@@ -7,111 +7,8 @@ package errors
 
 
 import (
 import (
 	"fmt"
 	"fmt"
-	"sort"
-	"strings"
 )
 )
 
 
-// TODO: This package currently only provides functionality for constructing
-// non-fatal errors. However, it does not currently provide functionality
-// to test for a specific kind of non-fatal error, which is necessary
-// for the end user.
-//
-// When that functionality is added, we need to think carefully about whether
-// a user only cares that some kind of non-fatal error was present or whether
-// all of the errors are of the same kind of non-fatal error.
-
-// NonFatalErrors is a list of non-fatal errors where each error
-// must either be a RequiredNotSet error or InvalidUTF8 error.
-// The list must not be empty.
-type NonFatalErrors []error
-
-func (es NonFatalErrors) Error() string {
-	ms := map[string]struct{}{}
-	for _, e := range es {
-		ms[e.Error()] = struct{}{}
-	}
-	var ss []string
-	for s := range ms {
-		ss = append(ss, s)
-	}
-	sort.Strings(ss)
-	return "proto: " + strings.Join(ss, "; ")
-}
-
-// NonFatal contains non-fatal errors, which are errors that permit execution
-// to continue, but should return with a non-nil error. As such, NonFatal is
-// a data structure useful for swallowing non-fatal errors, but being able to
-// reproduce them at the end of the function.
-// An error is non-fatal if it is collection of non-fatal errors, or is
-// an individual error where IsRequiredNotSet or IsInvalidUTF8 reports true.
-//
-// Typical usage pattern:
-//	var nerr errors.NonFatal
-//	...
-//	if err := MyFunction(); !nerr.Merge(err) {
-//		return nil, err // immediately return if err is fatal
-//	}
-//	...
-//	return out, nerr.E
-type NonFatal struct{ E error }
-
-// Merge merges err into nf and reports whether it was successful.
-// Otherwise it returns false for any fatal non-nil errors.
-func (nf *NonFatal) Merge(err error) (ok bool) {
-	if err == nil {
-		return true // not an error
-	}
-	if es, ok := err.(NonFatalErrors); ok {
-		nf.append(es...)
-		return true // merged a list of non-fatal errors
-	}
-	if e, ok := err.(interface{ RequiredNotSet() bool }); ok && e.RequiredNotSet() {
-		nf.append(err)
-		return true // non-fatal RequiredNotSet error
-	}
-	if e, ok := err.(interface{ InvalidUTF8() bool }); ok && e.InvalidUTF8() {
-		nf.append(err)
-		return true // non-fatal InvalidUTF8 error
-	}
-	return false // fatal error
-}
-
-// AppendRequiredNotSet appends a RequiredNotSet error.
-func (nf *NonFatal) AppendRequiredNotSet(field string) {
-	nf.append(requiredNotSetError(field))
-}
-
-// AppendInvalidUTF8 appends an InvalidUTF8 error.
-func (nf *NonFatal) AppendInvalidUTF8(field string) {
-	nf.append(invalidUTF8Error(field))
-}
-
-func (nf *NonFatal) append(errs ...error) {
-	es, _ := nf.E.(NonFatalErrors)
-	es = append(es, errs...)
-	nf.E = es
-}
-
-type requiredNotSetError string
-
-func (e requiredNotSetError) Error() string {
-	if e == "" {
-		return "required field not set"
-	}
-	return string("required field " + e + " not set")
-}
-func (requiredNotSetError) RequiredNotSet() bool { return true }
-
-type invalidUTF8Error string
-
-func (e invalidUTF8Error) Error() string {
-	if e == "" {
-		return "invalid UTF-8 detected"
-	}
-	return string("field " + e + " contains invalid UTF-8")
-}
-func (invalidUTF8Error) InvalidUTF8() bool { return true }
-
 // New formats a string according to the format specifier and arguments and
 // New formats a string according to the format specifier and arguments and
 // returns an error that has a "proto" prefix.
 // returns an error that has a "proto" prefix.
 func New(f string, x ...interface{}) error {
 func New(f string, x ...interface{}) error {
@@ -126,3 +23,11 @@ func New(f string, x ...interface{}) error {
 type prefixError struct{ s string }
 type prefixError struct{ s string }
 
 
 func (e *prefixError) Error() string { return "proto: " + e.s }
 func (e *prefixError) Error() string { return "proto: " + e.s }
+
+func InvalidUTF8(name string) error {
+	return New("field %v contains invalid UTF-8", name)
+}
+
+func RequiredNotSet(name string) error {
+	return New("required field %v not set", name)
+}

+ 0 - 84
internal/errors/errors_test.go

@@ -5,94 +5,10 @@
 package errors
 package errors
 
 
 import (
 import (
-	"errors"
-	"reflect"
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 )
 )
 
 
-func TestNonFatal(t *testing.T) {
-	type (
-		method = interface{} // merge | appendRequiredNotSet | appendInvalidUTF8
-		merge  struct {
-			inErr  error
-			wantOk bool
-		}
-		appendRequiredNotSet struct{ inField string }
-		appendInvalidUTF8    struct{ inField string }
-	)
-
-	tests := []struct {
-		label   string
-		methods []method
-		wantErr error
-	}{{
-		label: "IgnoreNil",
-		methods: []method{
-			merge{inErr: nil, wantOk: true},
-		},
-	}, {
-		label: "IgnoreFatal",
-		methods: []method{
-			merge{inErr: errors.New("fatal error")},
-		},
-	}, {
-		label: "MergeNonFatal",
-		methods: []method{
-			appendRequiredNotSet{"foo"},
-			merge{inErr: customRequiredNotSetError{}, wantOk: true},
-			appendInvalidUTF8{"bar"},
-			merge{inErr: customInvalidUTF8Error{}, wantOk: true},
-			merge{inErr: NonFatalErrors{
-				requiredNotSetError("fizz"),
-				invalidUTF8Error("buzz"),
-			}, wantOk: true},
-			merge{inErr: errors.New("fatal error")}, // not stored
-		},
-		wantErr: NonFatalErrors{
-			requiredNotSetError("foo"),
-			customRequiredNotSetError{},
-			invalidUTF8Error("bar"),
-			customInvalidUTF8Error{},
-			requiredNotSetError("fizz"),
-			invalidUTF8Error("buzz"),
-		},
-	}}
-
-	for _, tt := range tests {
-		t.Run(tt.label, func(t *testing.T) {
-			var nerr NonFatal
-			for _, m := range tt.methods {
-				switch m := m.(type) {
-				case merge:
-					if gotOk := nerr.Merge(m.inErr); gotOk != m.wantOk {
-						t.Errorf("Merge() = %v, want %v", gotOk, m.wantOk)
-					}
-				case appendRequiredNotSet:
-					nerr.AppendRequiredNotSet(m.inField)
-				case appendInvalidUTF8:
-					nerr.AppendInvalidUTF8(m.inField)
-				default:
-					t.Fatalf("invalid method: %T", m)
-				}
-			}
-			if !reflect.DeepEqual(nerr.E, tt.wantErr) {
-				t.Errorf("NonFatal.E = %v, want %v", nerr.E, tt.wantErr)
-			}
-		})
-	}
-}
-
-type customInvalidUTF8Error struct{}
-
-func (customInvalidUTF8Error) Error() string     { return "invalid UTF-8 detected" }
-func (customInvalidUTF8Error) InvalidUTF8() bool { return true }
-
-type customRequiredNotSetError struct{}
-
-func (customRequiredNotSetError) Error() string        { return "required field not set" }
-func (customRequiredNotSetError) RequiredNotSet() bool { return true }
-
 func TestNewPrefix(t *testing.T) {
 func TestNewPrefix(t *testing.T) {
 	e1 := New("abc")
 	e1 := New("abc")
 	got := e1.Error()
 	got := e1.Error()

+ 5 - 8
internal/impl/encode.go

@@ -8,7 +8,6 @@ import (
 	"sort"
 	"sort"
 	"sync/atomic"
 	"sync/atomic"
 
 
-	"google.golang.org/protobuf/internal/errors"
 	proto "google.golang.org/protobuf/proto"
 	proto "google.golang.org/protobuf/proto"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	piface "google.golang.org/protobuf/runtime/protoiface"
 	piface "google.golang.org/protobuf/runtime/protoiface"
@@ -100,13 +99,12 @@ func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOpt
 		return b, nil
 		return b, nil
 	}
 	}
 	var err error
 	var err error
-	var nerr errors.NonFatal
 	// The old marshaler encodes extensions at beginning.
 	// The old marshaler encodes extensions at beginning.
 	if mi.extensionOffset.IsValid() {
 	if mi.extensionOffset.IsValid() {
 		e := p.Apply(mi.extensionOffset).Extensions()
 		e := p.Apply(mi.extensionOffset).Extensions()
 		// TODO: Special handling for MessageSet?
 		// TODO: Special handling for MessageSet?
 		b, err = mi.appendExtensions(b, e, opts)
 		b, err = mi.appendExtensions(b, e, opts)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 	}
 	}
@@ -119,7 +117,7 @@ func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOpt
 			continue
 			continue
 		}
 		}
 		b, err = f.funcs.marshal(b, fptr, f.wiretag, opts)
 		b, err = f.funcs.marshal(b, fptr, f.wiretag, opts)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 	}
 	}
@@ -127,7 +125,7 @@ func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOpt
 		u := *p.Apply(mi.unknownOffset).Bytes()
 		u := *p.Apply(mi.unknownOffset).Bytes()
 		b = append(b, u...)
 		b = append(b, u...)
 	}
 	}
-	return b, nerr.E
+	return b, nil
 }
 }
 
 
 func (mi *MessageInfo) sizeExtensions(ext *map[int32]ExtensionField, opts marshalOptions) (n int) {
 func (mi *MessageInfo) sizeExtensions(ext *map[int32]ExtensionField, opts marshalOptions) (n int) {
@@ -169,15 +167,14 @@ func (mi *MessageInfo) appendExtensions(b []byte, ext *map[int32]ExtensionField,
 		}
 		}
 		sort.Ints(keys)
 		sort.Ints(keys)
 		var err error
 		var err error
-		var nerr errors.NonFatal
 		for _, k := range keys {
 		for _, k := range keys {
 			x := (*ext)[int32(k)]
 			x := (*ext)[int32(k)]
 			xi := mi.extensionFieldInfo(x.GetType())
 			xi := mi.extensionFieldInfo(x.GetType())
 			b, err = xi.funcs.marshal(b, x.GetValue(), xi.wiretag, opts)
 			b, err = xi.funcs.marshal(b, x.GetValue(), xi.wiretag, opts)
-			if !nerr.Merge(err) {
+			if err != nil {
 				return b, err
 				return b, err
 			}
 			}
 		}
 		}
-		return b, nerr.E
+		return b, nil
 	}
 	}
 }
 }

+ 8 - 13
internal/impl/encode_field.go

@@ -10,7 +10,6 @@ import (
 	"unicode/utf8"
 	"unicode/utf8"
 
 
 	"google.golang.org/protobuf/internal/encoding/wire"
 	"google.golang.org/protobuf/internal/encoding/wire"
-	"google.golang.org/protobuf/internal/errors"
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/proto"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 )
 )
@@ -221,18 +220,17 @@ func sizeMessageSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalO
 
 
 func appendMessageSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
 func appendMessageSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
 	s := p.PointerSlice()
 	s := p.PointerSlice()
-	var nerr errors.NonFatal
 	var err error
 	var err error
 	for _, v := range s {
 	for _, v := range s {
 		b = wire.AppendVarint(b, wiretag)
 		b = wire.AppendVarint(b, wiretag)
 		siz := mi.sizePointer(v, opts)
 		siz := mi.sizePointer(v, opts)
 		b = wire.AppendVarint(b, uint64(siz))
 		b = wire.AppendVarint(b, uint64(siz))
 		b, err = mi.marshalAppendPointer(b, v, opts)
 		b, err = mi.marshalAppendPointer(b, v, opts)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 	}
 	}
-	return b, nerr.E
+	return b, nil
 }
 }
 
 
 func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
 func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
@@ -247,7 +245,6 @@ func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOpti
 
 
 func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
 func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
 	s := p.PointerSlice()
 	s := p.PointerSlice()
-	var nerr errors.NonFatal
 	var err error
 	var err error
 	for _, v := range s {
 	for _, v := range s {
 		m := Export{}.MessageOf(v.AsValueOf(goType.Elem()).Interface()).Interface()
 		m := Export{}.MessageOf(v.AsValueOf(goType.Elem()).Interface()).Interface()
@@ -255,11 +252,11 @@ func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type
 		siz := proto.Size(m)
 		siz := proto.Size(m)
 		b = wire.AppendVarint(b, uint64(siz))
 		b = wire.AppendVarint(b, uint64(siz))
 		b, err = opts.Options().MarshalAppend(b, m)
 		b, err = opts.Options().MarshalAppend(b, m)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 	}
 	}
-	return b, nerr.E
+	return b, nil
 }
 }
 
 
 // Slices of messages
 // Slices of messages
@@ -312,18 +309,17 @@ func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalO
 
 
 func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
 func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
 	s := p.PointerSlice()
 	s := p.PointerSlice()
-	var nerr errors.NonFatal
 	var err error
 	var err error
 	for _, v := range s {
 	for _, v := range s {
 		m := Export{}.MessageOf(v.AsValueOf(messageType.Elem()).Interface()).Interface()
 		m := Export{}.MessageOf(v.AsValueOf(messageType.Elem()).Interface()).Interface()
 		b = wire.AppendVarint(b, wiretag) // start group
 		b = wire.AppendVarint(b, wiretag) // start group
 		b, err = opts.Options().MarshalAppend(b, m)
 		b, err = opts.Options().MarshalAppend(b, m)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 		b = wire.AppendVarint(b, wiretag+1) // end group
 		b = wire.AppendVarint(b, wiretag+1) // end group
 	}
 	}
-	return b, nerr.E
+	return b, nil
 }
 }
 
 
 func sizeGroupSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
 func sizeGroupSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
@@ -337,17 +333,16 @@ func sizeGroupSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOpt
 
 
 func appendGroupSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
 func appendGroupSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
 	s := p.PointerSlice()
 	s := p.PointerSlice()
-	var nerr errors.NonFatal
 	var err error
 	var err error
 	for _, v := range s {
 	for _, v := range s {
 		b = wire.AppendVarint(b, wiretag) // start group
 		b = wire.AppendVarint(b, wiretag) // start group
 		b, err = mi.marshalAppendPointer(b, v, opts)
 		b, err = mi.marshalAppendPointer(b, v, opts)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 		b = wire.AppendVarint(b, wiretag+1) // end group
 		b = wire.AppendVarint(b, wiretag+1) // end group
 	}
 	}
-	return b, nerr.E
+	return b, nil
 }
 }
 
 
 func sizeGroupSliceIface(ival interface{}, tagsize int, opts marshalOptions) int {
 func sizeGroupSliceIface(ival interface{}, tagsize int, opts marshalOptions) int {

+ 7 - 10
internal/impl/encode_map.go

@@ -10,7 +10,6 @@ import (
 	"sort"
 	"sort"
 
 
 	"google.golang.org/protobuf/internal/encoding/wire"
 	"google.golang.org/protobuf/internal/encoding/wire"
-	"google.golang.org/protobuf/internal/errors"
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/proto"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 )
 )
@@ -59,7 +58,6 @@ func sizeMap(p pointer, tagsize int, goType reflect.Type, keyFuncs, valFuncs ifa
 
 
 func appendMap(b []byte, p pointer, wiretag, keyWiretag, valWiretag uint64, goType reflect.Type, keyFuncs, valFuncs ifaceCoderFuncs, opts marshalOptions) ([]byte, error) {
 func appendMap(b []byte, p pointer, wiretag, keyWiretag, valWiretag uint64, goType reflect.Type, keyFuncs, valFuncs ifaceCoderFuncs, opts marshalOptions) ([]byte, error) {
 	m := p.AsValueOf(goType).Elem()
 	m := p.AsValueOf(goType).Elem()
-	var nerr errors.NonFatal
 	var err error
 	var err error
 
 
 	if m.Len() == 0 {
 	if m.Len() == 0 {
@@ -71,21 +69,21 @@ func appendMap(b []byte, p pointer, wiretag, keyWiretag, valWiretag uint64, goTy
 		sort.Sort(mapKeys(keys))
 		sort.Sort(mapKeys(keys))
 		for _, k := range keys {
 		for _, k := range keys {
 			b, err = appendMapElement(b, k, m.MapIndex(k), wiretag, keyWiretag, valWiretag, keyFuncs, valFuncs, opts)
 			b, err = appendMapElement(b, k, m.MapIndex(k), wiretag, keyWiretag, valWiretag, keyFuncs, valFuncs, opts)
-			if !nerr.Merge(err) {
+			if err != nil {
 				return b, err
 				return b, err
 			}
 			}
 		}
 		}
-		return b, nerr.E
+		return b, nil
 	}
 	}
 
 
 	iter := mapRange(m)
 	iter := mapRange(m)
 	for iter.Next() {
 	for iter.Next() {
 		b, err = appendMapElement(b, iter.Key(), iter.Value(), wiretag, keyWiretag, valWiretag, keyFuncs, valFuncs, opts)
 		b, err = appendMapElement(b, iter.Key(), iter.Value(), wiretag, keyWiretag, valWiretag, keyFuncs, valFuncs, opts)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 	}
 	}
-	return b, nerr.E
+	return b, nil
 }
 }
 
 
 func appendMapElement(b []byte, key, value reflect.Value, wiretag, keyWiretag, valWiretag uint64, keyFuncs, valFuncs ifaceCoderFuncs, opts marshalOptions) ([]byte, error) {
 func appendMapElement(b []byte, key, value reflect.Value, wiretag, keyWiretag, valWiretag uint64, keyFuncs, valFuncs ifaceCoderFuncs, opts marshalOptions) ([]byte, error) {
@@ -94,16 +92,15 @@ func appendMapElement(b []byte, key, value reflect.Value, wiretag, keyWiretag, v
 	b = wire.AppendVarint(b, wiretag)
 	b = wire.AppendVarint(b, wiretag)
 	size := keyFuncs.size(ki, mapKeyTagSize, opts) + valFuncs.size(vi, mapValTagSize, opts)
 	size := keyFuncs.size(ki, mapKeyTagSize, opts) + valFuncs.size(vi, mapValTagSize, opts)
 	b = wire.AppendVarint(b, uint64(size))
 	b = wire.AppendVarint(b, uint64(size))
-	var nerr errors.NonFatal
 	b, err := keyFuncs.marshal(b, ki, keyWiretag, opts)
 	b, err := keyFuncs.marshal(b, ki, keyWiretag, opts)
-	if !nerr.Merge(err) {
+	if err != nil {
 		return b, err
 		return b, err
 	}
 	}
 	b, err = valFuncs.marshal(b, vi, valWiretag, opts)
 	b, err = valFuncs.marshal(b, vi, valWiretag, opts)
-	if !nerr.Merge(err) {
+	if err != nil {
 		return b, err
 		return b, err
 	}
 	}
-	return b, nerr.E
+	return b, nil
 }
 }
 
 
 // mapKeys returns a sort.Interface to be used for sorting the map keys.
 // mapKeys returns a sort.Interface to be used for sorting the map keys.

+ 13 - 19
proto/decode.go

@@ -53,14 +53,13 @@ func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error {
 	if err == errInternalNoFast {
 	if err == errInternalNoFast {
 		err = o.unmarshalMessage(b, m.ProtoReflect())
 		err = o.unmarshalMessage(b, m.ProtoReflect())
 	}
 	}
-	var nerr errors.NonFatal
-	if !nerr.Merge(err) {
+	if err != nil {
 		return err
 		return err
 	}
 	}
-	if !o.AllowPartial {
-		nerr.Merge(IsInitialized(m))
+	if o.AllowPartial {
+		return nil
 	}
 	}
-	return nerr.E
+	return IsInitialized(m)
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalMessageFast(b []byte, m Message) error {
 func (o UnmarshalOptions) unmarshalMessageFast(b []byte, m Message) error {
@@ -74,7 +73,6 @@ func (o UnmarshalOptions) unmarshalMessageFast(b []byte, m Message) error {
 func (o UnmarshalOptions) unmarshalMessage(b []byte, m protoreflect.Message) error {
 func (o UnmarshalOptions) unmarshalMessage(b []byte, m protoreflect.Message) error {
 	messageDesc := m.Descriptor()
 	messageDesc := m.Descriptor()
 	fieldDescs := messageDesc.Fields()
 	fieldDescs := messageDesc.Fields()
-	var nerr errors.NonFatal
 	for len(b) > 0 {
 	for len(b) > 0 {
 		// Parse the tag (field number and wire type).
 		// Parse the tag (field number and wire type).
 		num, wtyp, tagLen := wire.ConsumeTag(b)
 		num, wtyp, tagLen := wire.ConsumeTag(b)
@@ -109,18 +107,17 @@ func (o UnmarshalOptions) unmarshalMessage(b []byte, m protoreflect.Message) err
 				return wire.ParseError(valLen)
 				return wire.ParseError(valLen)
 			}
 			}
 			m.SetUnknown(append(m.GetUnknown(), b[:tagLen+valLen]...))
 			m.SetUnknown(append(m.GetUnknown(), b[:tagLen+valLen]...))
-		} else if !nerr.Merge(err) {
+		} else if err != nil {
 			return err
 			return err
 		}
 		}
 		b = b[tagLen+valLen:]
 		b = b[tagLen+valLen:]
 	}
 	}
-	return nerr.E
+	return nil
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalSingular(b []byte, wtyp wire.Type, m protoreflect.Message, fd protoreflect.FieldDescriptor) (n int, err error) {
 func (o UnmarshalOptions) unmarshalSingular(b []byte, wtyp wire.Type, m protoreflect.Message, fd protoreflect.FieldDescriptor) (n int, err error) {
-	var nerr errors.NonFatal
 	v, n, err := o.unmarshalScalar(b, wtyp, fd)
 	v, n, err := o.unmarshalScalar(b, wtyp, fd)
-	if !nerr.Merge(err) {
+	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
 	switch fd.Kind() {
 	switch fd.Kind() {
@@ -138,14 +135,14 @@ func (o UnmarshalOptions) unmarshalSingular(b []byte, wtyp wire.Type, m protoref
 			m.Set(fd, protoreflect.ValueOf(m2))
 			m.Set(fd, protoreflect.ValueOf(m2))
 		}
 		}
 		// Pass up errors (fatal and otherwise).
 		// Pass up errors (fatal and otherwise).
-		if err := o.unmarshalMessage(v.Bytes(), m2); !nerr.Merge(err) {
+		if err := o.unmarshalMessage(v.Bytes(), m2); err != nil {
 			return n, err
 			return n, err
 		}
 		}
 	default:
 	default:
 		// Non-message scalars replace the previous value.
 		// Non-message scalars replace the previous value.
 		m.Set(fd, v)
 		m.Set(fd, v)
 	}
 	}
-	return n, nerr.E
+	return n, nil
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp wire.Type, mapv protoreflect.Map, fd protoreflect.FieldDescriptor) (n int, err error) {
 func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp wire.Type, mapv protoreflect.Map, fd protoreflect.FieldDescriptor) (n int, err error) {
@@ -170,7 +167,6 @@ func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp wire.Type, mapv protorefle
 	}
 	}
 	// Map entries are represented as a two-element message with fields
 	// Map entries are represented as a two-element message with fields
 	// containing the key and value.
 	// containing the key and value.
-	var nerr errors.NonFatal
 	for len(b) > 0 {
 	for len(b) > 0 {
 		num, wtyp, n := wire.ConsumeTag(b)
 		num, wtyp, n := wire.ConsumeTag(b)
 		if n < 0 {
 		if n < 0 {
@@ -181,21 +177,19 @@ func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp wire.Type, mapv protorefle
 		switch num {
 		switch num {
 		case 1:
 		case 1:
 			key, n, err = o.unmarshalScalar(b, wtyp, keyField)
 			key, n, err = o.unmarshalScalar(b, wtyp, keyField)
-			if !nerr.Merge(err) {
+			if err != nil {
 				break
 				break
 			}
 			}
-			err = nil
 			haveKey = true
 			haveKey = true
 		case 2:
 		case 2:
 			var v protoreflect.Value
 			var v protoreflect.Value
 			v, n, err = o.unmarshalScalar(b, wtyp, valField)
 			v, n, err = o.unmarshalScalar(b, wtyp, valField)
-			if !nerr.Merge(err) {
+			if err != nil {
 				break
 				break
 			}
 			}
-			err = nil
 			switch valField.Kind() {
 			switch valField.Kind() {
 			case protoreflect.GroupKind, protoreflect.MessageKind:
 			case protoreflect.GroupKind, protoreflect.MessageKind:
-				if err := o.unmarshalMessage(v.Bytes(), val.Message()); !nerr.Merge(err) {
+				if err := o.unmarshalMessage(v.Bytes(), val.Message()); err != nil {
 					return 0, err
 					return 0, err
 				}
 				}
 			default:
 			default:
@@ -225,7 +219,7 @@ func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp wire.Type, mapv protorefle
 		}
 		}
 	}
 	}
 	mapv.Set(key.MapKey(), val)
 	mapv.Set(key.MapKey(), val)
-	return n, nerr.E
+	return n, nil
 }
 }
 
 
 // errUnknown is used internally to indicate fields which should be added
 // errUnknown is used internally to indicate fields which should be added

+ 22 - 25
proto/decode_gen.go

@@ -155,9 +155,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp wire.Type, fd protorefl
 			return val, 0, wire.ParseError(n)
 			return val, 0, wire.ParseError(n)
 		}
 		}
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.Valid(v) {
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.Valid(v) {
-			var nerr errors.NonFatal
-			nerr.AppendInvalidUTF8(string(fd.FullName()))
-			return protoreflect.ValueOf(string(v)), n, nerr.E
+			return protoreflect.Value{}, 0, errors.InvalidUTF8(string(fd.FullName()))
 		}
 		}
 		return protoreflect.ValueOf(string(v)), n, nil
 		return protoreflect.ValueOf(string(v)), n, nil
 	case protoreflect.BytesKind:
 	case protoreflect.BytesKind:
@@ -193,7 +191,6 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp wire.Type, fd protorefl
 }
 }
 
 
 func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protoreflect.List, fd protoreflect.FieldDescriptor) (n int, err error) {
 func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protoreflect.List, fd protoreflect.FieldDescriptor) (n int, err error) {
-	var nerr errors.NonFatal
 	switch fd.Kind() {
 	switch fd.Kind() {
 	case protoreflect.BoolKind:
 	case protoreflect.BoolKind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
@@ -219,7 +216,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(wire.DecodeBool(v)))
 		list.Append(protoreflect.ValueOf(wire.DecodeBool(v)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.EnumKind:
 	case protoreflect.EnumKind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -244,7 +241,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(protoreflect.EnumNumber(v)))
 		list.Append(protoreflect.ValueOf(protoreflect.EnumNumber(v)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.Int32Kind:
 	case protoreflect.Int32Kind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -269,7 +266,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(int32(v)))
 		list.Append(protoreflect.ValueOf(int32(v)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.Sint32Kind:
 	case protoreflect.Sint32Kind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -294,7 +291,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(int32(wire.DecodeZigZag(v & math.MaxUint32))))
 		list.Append(protoreflect.ValueOf(int32(wire.DecodeZigZag(v & math.MaxUint32))))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.Uint32Kind:
 	case protoreflect.Uint32Kind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -319,7 +316,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(uint32(v)))
 		list.Append(protoreflect.ValueOf(uint32(v)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.Int64Kind:
 	case protoreflect.Int64Kind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -344,7 +341,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(int64(v)))
 		list.Append(protoreflect.ValueOf(int64(v)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.Sint64Kind:
 	case protoreflect.Sint64Kind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -369,7 +366,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(wire.DecodeZigZag(v)))
 		list.Append(protoreflect.ValueOf(wire.DecodeZigZag(v)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.Uint64Kind:
 	case protoreflect.Uint64Kind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -394,7 +391,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(v))
 		list.Append(protoreflect.ValueOf(v))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.Sfixed32Kind:
 	case protoreflect.Sfixed32Kind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -419,7 +416,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(int32(v)))
 		list.Append(protoreflect.ValueOf(int32(v)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.Fixed32Kind:
 	case protoreflect.Fixed32Kind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -444,7 +441,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(uint32(v)))
 		list.Append(protoreflect.ValueOf(uint32(v)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.FloatKind:
 	case protoreflect.FloatKind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -469,7 +466,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(math.Float32frombits(uint32(v))))
 		list.Append(protoreflect.ValueOf(math.Float32frombits(uint32(v))))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.Sfixed64Kind:
 	case protoreflect.Sfixed64Kind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -494,7 +491,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(int64(v)))
 		list.Append(protoreflect.ValueOf(int64(v)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.Fixed64Kind:
 	case protoreflect.Fixed64Kind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -519,7 +516,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(v))
 		list.Append(protoreflect.ValueOf(v))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.DoubleKind:
 	case protoreflect.DoubleKind:
 		if wtyp == wire.BytesType {
 		if wtyp == wire.BytesType {
 			buf, n := wire.ConsumeBytes(b)
 			buf, n := wire.ConsumeBytes(b)
@@ -544,7 +541,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(math.Float64frombits(v)))
 		list.Append(protoreflect.ValueOf(math.Float64frombits(v)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.StringKind:
 	case protoreflect.StringKind:
 		if wtyp != wire.BytesType {
 		if wtyp != wire.BytesType {
 			return 0, errUnknown
 			return 0, errUnknown
@@ -554,10 +551,10 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.Valid(v) {
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.Valid(v) {
-			nerr.AppendInvalidUTF8(string(fd.FullName()))
+			return 0, errors.InvalidUTF8(string(fd.FullName()))
 		}
 		}
 		list.Append(protoreflect.ValueOf(string(v)))
 		list.Append(protoreflect.ValueOf(string(v)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.BytesKind:
 	case protoreflect.BytesKind:
 		if wtyp != wire.BytesType {
 		if wtyp != wire.BytesType {
 			return 0, errUnknown
 			return 0, errUnknown
@@ -567,7 +564,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		list.Append(protoreflect.ValueOf(append(([]byte)(nil), v...)))
 		list.Append(protoreflect.ValueOf(append(([]byte)(nil), v...)))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.MessageKind:
 	case protoreflect.MessageKind:
 		if wtyp != wire.BytesType {
 		if wtyp != wire.BytesType {
 			return 0, errUnknown
 			return 0, errUnknown
@@ -577,11 +574,11 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		m := list.NewMessage()
 		m := list.NewMessage()
-		if err := o.unmarshalMessage(v, m); !nerr.Merge(err) {
+		if err := o.unmarshalMessage(v, m); err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
 		list.Append(protoreflect.ValueOf(m))
 		list.Append(protoreflect.ValueOf(m))
-		return n, nerr.E
+		return n, nil
 	case protoreflect.GroupKind:
 	case protoreflect.GroupKind:
 		if wtyp != wire.StartGroupType {
 		if wtyp != wire.StartGroupType {
 			return 0, errUnknown
 			return 0, errUnknown
@@ -591,11 +588,11 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp wire.Type, list protorefl
 			return 0, wire.ParseError(n)
 			return 0, wire.ParseError(n)
 		}
 		}
 		m := list.NewMessage()
 		m := list.NewMessage()
-		if err := o.unmarshalMessage(v, m); !nerr.Merge(err) {
+		if err := o.unmarshalMessage(v, m); err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
 		list.Append(protoreflect.ValueOf(m))
 		list.Append(protoreflect.ValueOf(m))
-		return n, nerr.E
+		return n, nil
 	default:
 	default:
 		return 0, errUnknown
 		return 0, errUnknown
 	}
 	}

+ 1 - 19
proto/decode_test.go

@@ -12,7 +12,6 @@ import (
 	protoV1 "github.com/golang/protobuf/proto"
 	protoV1 "github.com/golang/protobuf/proto"
 	"google.golang.org/protobuf/encoding/prototext"
 	"google.golang.org/protobuf/encoding/prototext"
 	"google.golang.org/protobuf/internal/encoding/pack"
 	"google.golang.org/protobuf/internal/encoding/pack"
-	"google.golang.org/protobuf/internal/errors"
 	"google.golang.org/protobuf/internal/scalar"
 	"google.golang.org/protobuf/internal/scalar"
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/proto"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
@@ -89,12 +88,9 @@ func TestDecodeInvalidUTF8(t *testing.T) {
 			t.Run(fmt.Sprintf("%s (%T)", test.desc, want), func(t *testing.T) {
 			t.Run(fmt.Sprintf("%s (%T)", test.desc, want), func(t *testing.T) {
 				got := reflect.New(reflect.TypeOf(want).Elem()).Interface().(proto.Message)
 				got := reflect.New(reflect.TypeOf(want).Elem()).Interface().(proto.Message)
 				err := proto.Unmarshal(test.wire, got)
 				err := proto.Unmarshal(test.wire, got)
-				if !isErrInvalidUTF8(err) {
+				if err == nil {
 					t.Errorf("Unmarshal did not return expected error for invalid UTF8: %v\nMessage:\n%v", err, marshalText(want))
 					t.Errorf("Unmarshal did not return expected error for invalid UTF8: %v\nMessage:\n%v", err, marshalText(want))
 				}
 				}
-				if !protoV1.Equal(got.(protoV1.Message), want.(protoV1.Message)) {
-					t.Errorf("Unmarshal returned unexpected result; got:\n%v\nwant:\n%v", marshalText(got), marshalText(want))
-				}
 			})
 			})
 		}
 		}
 	}
 	}
@@ -1362,17 +1358,3 @@ func marshalText(m proto.Message) string {
 	b, _ := prototext.Marshal(m)
 	b, _ := prototext.Marshal(m)
 	return string(b)
 	return string(b)
 }
 }
-
-func isErrInvalidUTF8(err error) bool {
-	nerr, ok := err.(errors.NonFatalErrors)
-	if !ok || len(nerr) == 0 {
-		return false
-	}
-	for _, err := range nerr {
-		if e, ok := err.(interface{ InvalidUTF8() bool }); ok && e.InvalidUTF8() {
-			continue
-		}
-		return false
-	}
-	return true
-}

+ 14 - 29
proto/encode.go

@@ -8,7 +8,6 @@ import (
 	"sort"
 	"sort"
 
 
 	"google.golang.org/protobuf/internal/encoding/wire"
 	"google.golang.org/protobuf/internal/encoding/wire"
-	"google.golang.org/protobuf/internal/errors"
 	"google.golang.org/protobuf/internal/mapsort"
 	"google.golang.org/protobuf/internal/mapsort"
 	"google.golang.org/protobuf/internal/pragma"
 	"google.golang.org/protobuf/internal/pragma"
 	"google.golang.org/protobuf/reflect/protoreflect"
 	"google.golang.org/protobuf/reflect/protoreflect"
@@ -92,14 +91,13 @@ func (o MarshalOptions) MarshalAppend(b []byte, m Message) ([]byte, error) {
 	if err == errInternalNoFast {
 	if err == errInternalNoFast {
 		out, err = o.marshalMessage(b, m.ProtoReflect())
 		out, err = o.marshalMessage(b, m.ProtoReflect())
 	}
 	}
-	var nerr errors.NonFatal
-	if !nerr.Merge(err) {
-		return out, err
+	if err != nil {
+		return nil, err
 	}
 	}
-	if !allowPartial {
-		nerr.Merge(IsInitialized(m))
+	if allowPartial {
+		return out, nil
 	}
 	}
-	return out, nerr.E
+	return out, IsInitialized(m)
 }
 }
 
 
 func (o MarshalOptions) marshalMessageFast(b []byte, m Message) ([]byte, error) {
 func (o MarshalOptions) marshalMessageFast(b []byte, m Message) ([]byte, error) {
@@ -129,20 +127,15 @@ func (o MarshalOptions) marshalMessage(b []byte, m protoreflect.Message) ([]byte
 	//
 	//
 	// When using deterministic serialization, we sort the known fields by field number.
 	// When using deterministic serialization, we sort the known fields by field number.
 	var err error
 	var err error
-	var nerr errors.NonFatal
 	o.rangeFields(m, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
 	o.rangeFields(m, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
 		b, err = o.marshalField(b, fd, v)
 		b, err = o.marshalField(b, fd, v)
-		if nerr.Merge(err) {
-			err = nil
-			return true
-		}
-		return false
+		return err == nil
 	})
 	})
 	if err != nil {
 	if err != nil {
 		return b, err
 		return b, err
 	}
 	}
 	b = append(b, m.GetUnknown()...)
 	b = append(b, m.GetUnknown()...)
-	return b, nerr.E
+	return b, nil
 }
 }
 
 
 // rangeFields visits fields in field number order when deterministic
 // rangeFields visits fields in field number order when deterministic
@@ -183,35 +176,32 @@ func (o MarshalOptions) marshalList(b []byte, fd protoreflect.FieldDescriptor, l
 	if fd.IsPacked() && list.Len() > 0 {
 	if fd.IsPacked() && list.Len() > 0 {
 		b = wire.AppendTag(b, fd.Number(), wire.BytesType)
 		b = wire.AppendTag(b, fd.Number(), wire.BytesType)
 		b, pos := appendSpeculativeLength(b)
 		b, pos := appendSpeculativeLength(b)
-		var nerr errors.NonFatal
 		for i, llen := 0, list.Len(); i < llen; i++ {
 		for i, llen := 0, list.Len(); i < llen; i++ {
 			var err error
 			var err error
 			b, err = o.marshalSingular(b, fd, list.Get(i))
 			b, err = o.marshalSingular(b, fd, list.Get(i))
-			if !nerr.Merge(err) {
+			if err != nil {
 				return b, err
 				return b, err
 			}
 			}
 		}
 		}
 		b = finishSpeculativeLength(b, pos)
 		b = finishSpeculativeLength(b, pos)
-		return b, nerr.E
+		return b, nil
 	}
 	}
 
 
 	kind := fd.Kind()
 	kind := fd.Kind()
-	var nerr errors.NonFatal
 	for i, llen := 0, list.Len(); i < llen; i++ {
 	for i, llen := 0, list.Len(); i < llen; i++ {
 		var err error
 		var err error
 		b = wire.AppendTag(b, fd.Number(), wireTypes[kind])
 		b = wire.AppendTag(b, fd.Number(), wireTypes[kind])
 		b, err = o.marshalSingular(b, fd, list.Get(i))
 		b, err = o.marshalSingular(b, fd, list.Get(i))
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 	}
 	}
-	return b, nerr.E
+	return b, nil
 }
 }
 
 
 func (o MarshalOptions) marshalMap(b []byte, fd protoreflect.FieldDescriptor, mapv protoreflect.Map) ([]byte, error) {
 func (o MarshalOptions) marshalMap(b []byte, fd protoreflect.FieldDescriptor, mapv protoreflect.Map) ([]byte, error) {
 	keyf := fd.MapKey()
 	keyf := fd.MapKey()
 	valf := fd.MapValue()
 	valf := fd.MapValue()
-	var nerr errors.NonFatal
 	var err error
 	var err error
 	o.rangeMap(mapv, keyf.Kind(), func(key protoreflect.MapKey, value protoreflect.Value) bool {
 	o.rangeMap(mapv, keyf.Kind(), func(key protoreflect.MapKey, value protoreflect.Value) bool {
 		b = wire.AppendTag(b, fd.Number(), wire.BytesType)
 		b = wire.AppendTag(b, fd.Number(), wire.BytesType)
@@ -219,22 +209,17 @@ func (o MarshalOptions) marshalMap(b []byte, fd protoreflect.FieldDescriptor, ma
 		b, pos = appendSpeculativeLength(b)
 		b, pos = appendSpeculativeLength(b)
 
 
 		b, err = o.marshalField(b, keyf, key.Value())
 		b, err = o.marshalField(b, keyf, key.Value())
-		if !nerr.Merge(err) {
+		if err != nil {
 			return false
 			return false
 		}
 		}
 		b, err = o.marshalField(b, valf, value)
 		b, err = o.marshalField(b, valf, value)
-		if !nerr.Merge(err) {
+		if err != nil {
 			return false
 			return false
 		}
 		}
-		err = nil
-
 		b = finishSpeculativeLength(b, pos)
 		b = finishSpeculativeLength(b, pos)
 		return true
 		return true
 	})
 	})
-	if err != nil {
-		return b, err
-	}
-	return b, nerr.E
+	return b, err
 }
 }
 
 
 func (o MarshalOptions) rangeMap(mapv protoreflect.Map, kind protoreflect.Kind, f func(protoreflect.MapKey, protoreflect.Value) bool) {
 func (o MarshalOptions) rangeMap(mapv protoreflect.Map, kind protoreflect.Kind, f func(protoreflect.MapKey, protoreflect.Value) bool) {

+ 4 - 5
proto/encode_gen.go

@@ -37,7 +37,6 @@ var wireTypes = map[protoreflect.Kind]wire.Type{
 }
 }
 
 
 func (o MarshalOptions) marshalSingular(b []byte, fd protoreflect.FieldDescriptor, v protoreflect.Value) ([]byte, error) {
 func (o MarshalOptions) marshalSingular(b []byte, fd protoreflect.FieldDescriptor, v protoreflect.Value) ([]byte, error) {
-	var nerr errors.NonFatal
 	switch fd.Kind() {
 	switch fd.Kind() {
 	case protoreflect.BoolKind:
 	case protoreflect.BoolKind:
 		b = wire.AppendVarint(b, wire.EncodeBool(v.Bool()))
 		b = wire.AppendVarint(b, wire.EncodeBool(v.Bool()))
@@ -69,7 +68,7 @@ func (o MarshalOptions) marshalSingular(b []byte, fd protoreflect.FieldDescripto
 		b = wire.AppendFixed64(b, math.Float64bits(v.Float()))
 		b = wire.AppendFixed64(b, math.Float64bits(v.Float()))
 	case protoreflect.StringKind:
 	case protoreflect.StringKind:
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.ValidString(v.String()) {
 		if fd.Syntax() == protoreflect.Proto3 && !utf8.ValidString(v.String()) {
-			nerr.AppendInvalidUTF8(string(fd.FullName()))
+			return b, errors.InvalidUTF8(string(fd.FullName()))
 		}
 		}
 		b = wire.AppendBytes(b, []byte(v.String()))
 		b = wire.AppendBytes(b, []byte(v.String()))
 	case protoreflect.BytesKind:
 	case protoreflect.BytesKind:
@@ -79,19 +78,19 @@ func (o MarshalOptions) marshalSingular(b []byte, fd protoreflect.FieldDescripto
 		var err error
 		var err error
 		b, pos = appendSpeculativeLength(b)
 		b, pos = appendSpeculativeLength(b)
 		b, err = o.marshalMessage(b, v.Message())
 		b, err = o.marshalMessage(b, v.Message())
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 		b = finishSpeculativeLength(b, pos)
 		b = finishSpeculativeLength(b, pos)
 	case protoreflect.GroupKind:
 	case protoreflect.GroupKind:
 		var err error
 		var err error
 		b, err = o.marshalMessage(b, v.Message())
 		b, err = o.marshalMessage(b, v.Message())
-		if !nerr.Merge(err) {
+		if err != nil {
 			return b, err
 			return b, err
 		}
 		}
 		b = wire.AppendVarint(b, wire.EncodeTag(fd.Number(), wire.EndGroupType))
 		b = wire.AppendVarint(b, wire.EncodeTag(fd.Number(), wire.EndGroupType))
 	default:
 	default:
 		return b, errors.New("invalid kind %v", fd.Kind())
 		return b, errors.New("invalid kind %v", fd.Kind())
 	}
 	}
-	return b, nerr.E
+	return b, nil
 }
 }

+ 2 - 10
proto/encode_test.go

@@ -99,18 +99,10 @@ func TestEncodeInvalidUTF8(t *testing.T) {
 	for _, test := range invalidUTF8TestProtos {
 	for _, test := range invalidUTF8TestProtos {
 		for _, want := range test.decodeTo {
 		for _, want := range test.decodeTo {
 			t.Run(fmt.Sprintf("%s (%T)", test.desc, want), func(t *testing.T) {
 			t.Run(fmt.Sprintf("%s (%T)", test.desc, want), func(t *testing.T) {
-				wire, err := proto.Marshal(want)
-				if !isErrInvalidUTF8(err) {
+				_, err := proto.Marshal(want)
+				if err == nil {
 					t.Errorf("Marshal did not return expected error for invalid UTF8: %v\nMessage:\n%v", err, marshalText(want))
 					t.Errorf("Marshal did not return expected error for invalid UTF8: %v\nMessage:\n%v", err, marshalText(want))
 				}
 				}
-				got := want.ProtoReflect().New().Interface()
-				if err := proto.Unmarshal(wire, got); !isErrInvalidUTF8(err) {
-					t.Errorf("Unmarshal error: %v\nMessage:\n%v", err, marshalText(want))
-					return
-				}
-				if !proto.Equal(got, want) {
-					t.Errorf("Unmarshal returned unexpected result; got:\n%v\nwant:\n%v", marshalText(got), marshalText(want))
-				}
 			})
 			})
 		}
 		}
 	}
 	}

+ 1 - 3
proto/isinit.go

@@ -75,7 +75,5 @@ func newRequiredNotSetError(stack []interface{}) error {
 	for _, s := range stack {
 	for _, s := range stack {
 		fmt.Fprint(&buf, s)
 		fmt.Fprint(&buf, s)
 	}
 	}
-	var nerr errors.NonFatal
-	nerr.AppendRequiredNotSet(buf.String())
-	return nerr.E
+	return errors.RequiredNotSet(buf.String())
 }
 }