gRPC migration

Change-Id: Ib390f6dde0d5a8d6db12ccd7da41135570ad1354
diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go
index 3c3ef14..72924a9 100644
--- a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go
+++ b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go
@@ -7,85 +7,93 @@
 import (
 	"bytes"
 	"fmt"
+	"math"
 	"strconv"
 	"strings"
 	"time"
 
-	"google.golang.org/protobuf/internal/detectknown"
 	"google.golang.org/protobuf/internal/encoding/json"
 	"google.golang.org/protobuf/internal/errors"
-	"google.golang.org/protobuf/internal/fieldnum"
+	"google.golang.org/protobuf/internal/genid"
 	"google.golang.org/protobuf/internal/strs"
 	"google.golang.org/protobuf/proto"
 	pref "google.golang.org/protobuf/reflect/protoreflect"
 )
 
-// isCustomType returns true if type name has special JSON conversion rules.
-// The list of custom types here has to match the ones in marshalCustomType and
-// unmarshalCustomType.
-func isCustomType(name pref.FullName) bool {
-	switch detectknown.Which(name) {
-	case detectknown.AnyProto:
-	case detectknown.TimestampProto:
-	case detectknown.DurationProto:
-	case detectknown.WrappersProto:
-	case detectknown.StructProto:
-	case detectknown.FieldMaskProto:
-	case detectknown.EmptyProto:
-	default:
-		return false
+type marshalFunc func(encoder, pref.Message) error
+
+// wellKnownTypeMarshaler returns a marshal function if the message type
+// has specialized serialization behavior. It returns nil otherwise.
+func wellKnownTypeMarshaler(name pref.FullName) marshalFunc {
+	if name.Parent() == genid.GoogleProtobuf_package {
+		switch name.Name() {
+		case genid.Any_message_name:
+			return encoder.marshalAny
+		case genid.Timestamp_message_name:
+			return encoder.marshalTimestamp
+		case genid.Duration_message_name:
+			return encoder.marshalDuration
+		case genid.BoolValue_message_name,
+			genid.Int32Value_message_name,
+			genid.Int64Value_message_name,
+			genid.UInt32Value_message_name,
+			genid.UInt64Value_message_name,
+			genid.FloatValue_message_name,
+			genid.DoubleValue_message_name,
+			genid.StringValue_message_name,
+			genid.BytesValue_message_name:
+			return encoder.marshalWrapperType
+		case genid.Struct_message_name:
+			return encoder.marshalStruct
+		case genid.ListValue_message_name:
+			return encoder.marshalListValue
+		case genid.Value_message_name:
+			return encoder.marshalKnownValue
+		case genid.FieldMask_message_name:
+			return encoder.marshalFieldMask
+		case genid.Empty_message_name:
+			return encoder.marshalEmpty
+		}
 	}
-	return true
+	return nil
 }
 
-// marshalCustomType marshals given well-known type message that have special
-// JSON conversion rules. It needs to be a message type where isCustomType
-// returns true, else it will panic.
-func (e encoder) marshalCustomType(m pref.Message) error {
-	name := m.Descriptor().FullName()
-	switch detectknown.Which(name) {
-	case detectknown.AnyProto:
-		return e.marshalAny(m)
-	case detectknown.TimestampProto:
-		return e.marshalTimestamp(m)
-	case detectknown.DurationProto:
-		return e.marshalDuration(m)
-	case detectknown.WrappersProto:
-		return e.marshalWrapperType(m)
-	case detectknown.StructProto:
-		return e.marshalStructType(m)
-	case detectknown.FieldMaskProto:
-		return e.marshalFieldMask(m)
-	case detectknown.EmptyProto:
-		return e.marshalEmpty(m)
-	default:
-		panic(fmt.Sprintf("%s does not have a custom marshaler", name))
-	}
-}
+type unmarshalFunc func(decoder, pref.Message) error
 
-// unmarshalCustomType unmarshals given well-known type message that have
-// special JSON conversion rules. It needs to be a message type where
-// isCustomType returns true, else it will panic.
-func (d decoder) unmarshalCustomType(m pref.Message) error {
-	name := m.Descriptor().FullName()
-	switch detectknown.Which(name) {
-	case detectknown.AnyProto:
-		return d.unmarshalAny(m)
-	case detectknown.TimestampProto:
-		return d.unmarshalTimestamp(m)
-	case detectknown.DurationProto:
-		return d.unmarshalDuration(m)
-	case detectknown.WrappersProto:
-		return d.unmarshalWrapperType(m)
-	case detectknown.StructProto:
-		return d.unmarshalStructType(m)
-	case detectknown.FieldMaskProto:
-		return d.unmarshalFieldMask(m)
-	case detectknown.EmptyProto:
-		return d.unmarshalEmpty(m)
-	default:
-		panic(fmt.Sprintf("%s does not have a custom unmarshaler", name))
+// wellKnownTypeUnmarshaler returns a unmarshal function if the message type
+// has specialized serialization behavior. It returns nil otherwise.
+func wellKnownTypeUnmarshaler(name pref.FullName) unmarshalFunc {
+	if name.Parent() == genid.GoogleProtobuf_package {
+		switch name.Name() {
+		case genid.Any_message_name:
+			return decoder.unmarshalAny
+		case genid.Timestamp_message_name:
+			return decoder.unmarshalTimestamp
+		case genid.Duration_message_name:
+			return decoder.unmarshalDuration
+		case genid.BoolValue_message_name,
+			genid.Int32Value_message_name,
+			genid.Int64Value_message_name,
+			genid.UInt32Value_message_name,
+			genid.UInt64Value_message_name,
+			genid.FloatValue_message_name,
+			genid.DoubleValue_message_name,
+			genid.StringValue_message_name,
+			genid.BytesValue_message_name:
+			return decoder.unmarshalWrapperType
+		case genid.Struct_message_name:
+			return decoder.unmarshalStruct
+		case genid.ListValue_message_name:
+			return decoder.unmarshalListValue
+		case genid.Value_message_name:
+			return decoder.unmarshalKnownValue
+		case genid.FieldMask_message_name:
+			return decoder.unmarshalFieldMask
+		case genid.Empty_message_name:
+			return decoder.unmarshalEmpty
+		}
 	}
+	return nil
 }
 
 // The JSON representation of an Any message uses the regular representation of
@@ -96,37 +104,29 @@
 
 func (e encoder) marshalAny(m pref.Message) error {
 	fds := m.Descriptor().Fields()
-	fdType := fds.ByNumber(fieldnum.Any_TypeUrl)
-	fdValue := fds.ByNumber(fieldnum.Any_Value)
-
-	// Start writing the JSON object.
-	e.StartObject()
-	defer e.EndObject()
+	fdType := fds.ByNumber(genid.Any_TypeUrl_field_number)
+	fdValue := fds.ByNumber(genid.Any_Value_field_number)
 
 	if !m.Has(fdType) {
 		if !m.Has(fdValue) {
 			// If message is empty, marshal out empty JSON object.
+			e.StartObject()
+			e.EndObject()
 			return nil
 		} else {
 			// Return error if type_url field is not set, but value is set.
-			return errors.New("%s: type_url is not set", m.Descriptor().FullName())
+			return errors.New("%s: %v is not set", genid.Any_message_fullname, genid.Any_TypeUrl_field_name)
 		}
 	}
 
 	typeVal := m.Get(fdType)
 	valueVal := m.Get(fdValue)
 
-	// Marshal out @type field.
-	typeURL := typeVal.String()
-	e.WriteName("@type")
-	if err := e.WriteString(typeURL); err != nil {
-		return err
-	}
-
 	// Resolve the type in order to unmarshal value field.
+	typeURL := typeVal.String()
 	emt, err := e.opts.Resolver.FindMessageByURL(typeURL)
 	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", genid.Any_message_fullname, typeURL, err)
 	}
 
 	em := emt.New()
@@ -135,19 +135,28 @@
 		Resolver:     e.opts.Resolver,
 	}.Unmarshal(valueVal.Bytes(), em.Interface())
 	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", genid.Any_message_fullname, typeURL, err)
 	}
 
 	// If type of value has custom JSON encoding, marshal out a field "value"
 	// with corresponding custom JSON encoding of the embedded message as a
 	// field.
-	if isCustomType(emt.Descriptor().FullName()) {
+	if marshal := wellKnownTypeMarshaler(emt.Descriptor().FullName()); marshal != nil {
+		e.StartObject()
+		defer e.EndObject()
+
+		// Marshal out @type field.
+		e.WriteName("@type")
+		if err := e.WriteString(typeURL); err != nil {
+			return err
+		}
+
 		e.WriteName("value")
-		return e.marshalCustomType(em)
+		return marshal(e, em)
 	}
 
 	// Else, marshal out the embedded message's fields in this Any object.
-	if err := e.marshalFields(em); err != nil {
+	if err := e.marshalMessage(em, typeURL); err != nil {
 		return err
 	}
 
@@ -198,10 +207,10 @@
 
 	// Create new message for the embedded message type and unmarshal into it.
 	em := emt.New()
-	if isCustomType(emt.Descriptor().FullName()) {
+	if unmarshal := wellKnownTypeUnmarshaler(emt.Descriptor().FullName()); unmarshal != nil {
 		// If embedded message is a custom type,
 		// unmarshal the JSON "value" field into it.
-		if err := d.unmarshalAnyValue(em); err != nil {
+		if err := d.unmarshalAnyValue(unmarshal, em); err != nil {
 			return err
 		}
 	} else {
@@ -221,8 +230,8 @@
 	}
 
 	fds := m.Descriptor().Fields()
-	fdType := fds.ByNumber(fieldnum.Any_TypeUrl)
-	fdValue := fds.ByNumber(fieldnum.Any_Value)
+	fdType := fds.ByNumber(genid.Any_TypeUrl_field_number)
+	fdValue := fds.ByNumber(genid.Any_Value_field_number)
 
 	m.Set(fdType, pref.ValueOfString(typeURL))
 	m.Set(fdValue, pref.ValueOfBytes(b))
@@ -345,7 +354,7 @@
 
 // unmarshalAnyValue unmarshals the given custom-type message from the JSON
 // object's "value" field.
-func (d decoder) unmarshalAnyValue(m pref.Message) error {
+func (d decoder) unmarshalAnyValue(unmarshal unmarshalFunc, m pref.Message) error {
 	// Skip ObjectOpen, and start reading the fields.
 	d.Read()
 
@@ -373,7 +382,7 @@
 					return d.newError(tok.Pos(), `duplicate "value" field`)
 				}
 				// Unmarshal the field value into the given message.
-				if err := d.unmarshalCustomType(m); err != nil {
+				if err := unmarshal(d, m); err != nil {
 					return err
 				}
 				found = true
@@ -393,17 +402,14 @@
 
 // Wrapper types are encoded as JSON primitives like string, number or boolean.
 
-// The "value" field has the same field number for all wrapper types.
-const wrapperFieldNumber = fieldnum.BoolValue_Value
-
 func (e encoder) marshalWrapperType(m pref.Message) error {
-	fd := m.Descriptor().Fields().ByNumber(wrapperFieldNumber)
+	fd := m.Descriptor().Fields().ByNumber(genid.WrapperValue_Value_field_number)
 	val := m.Get(fd)
 	return e.marshalSingular(val, fd)
 }
 
 func (d decoder) unmarshalWrapperType(m pref.Message) error {
-	fd := m.Descriptor().Fields().ByNumber(wrapperFieldNumber)
+	fd := m.Descriptor().Fields().ByNumber(genid.WrapperValue_Value_field_number)
 	val, err := d.unmarshalScalar(fd)
 	if err != nil {
 		return err
@@ -453,42 +459,16 @@
 	}
 }
 
-func (e encoder) marshalStructType(m pref.Message) error {
-	switch m.Descriptor().Name() {
-	case "Struct":
-		return e.marshalStruct(m)
-	case "ListValue":
-		return e.marshalListValue(m)
-	case "Value":
-		return e.marshalKnownValue(m)
-	default:
-		panic(fmt.Sprintf("invalid struct type: %v", m.Descriptor().FullName()))
-	}
-}
-
-func (d decoder) unmarshalStructType(m pref.Message) error {
-	switch m.Descriptor().Name() {
-	case "Struct":
-		return d.unmarshalStruct(m)
-	case "ListValue":
-		return d.unmarshalListValue(m)
-	case "Value":
-		return d.unmarshalKnownValue(m)
-	default:
-		panic(fmt.Sprintf("invalid struct type: %v", m.Descriptor().FullName()))
-	}
-}
-
 // The JSON representation for Struct is a JSON object that contains the encoded
 // Struct.fields map and follows the serialization rules for a map.
 
 func (e encoder) marshalStruct(m pref.Message) error {
-	fd := m.Descriptor().Fields().ByNumber(fieldnum.Struct_Fields)
+	fd := m.Descriptor().Fields().ByNumber(genid.Struct_Fields_field_number)
 	return e.marshalMap(m.Get(fd).Map(), fd)
 }
 
 func (d decoder) unmarshalStruct(m pref.Message) error {
-	fd := m.Descriptor().Fields().ByNumber(fieldnum.Struct_Fields)
+	fd := m.Descriptor().Fields().ByNumber(genid.Struct_Fields_field_number)
 	return d.unmarshalMap(m.Mutable(fd).Map(), fd)
 }
 
@@ -497,12 +477,12 @@
 // repeated field.
 
 func (e encoder) marshalListValue(m pref.Message) error {
-	fd := m.Descriptor().Fields().ByNumber(fieldnum.ListValue_Values)
+	fd := m.Descriptor().Fields().ByNumber(genid.ListValue_Values_field_number)
 	return e.marshalList(m.Get(fd).List(), fd)
 }
 
 func (d decoder) unmarshalListValue(m pref.Message) error {
-	fd := m.Descriptor().Fields().ByNumber(fieldnum.ListValue_Values)
+	fd := m.Descriptor().Fields().ByNumber(genid.ListValue_Values_field_number)
 	return d.unmarshalList(m.Mutable(fd).List(), fd)
 }
 
@@ -511,10 +491,15 @@
 // Value message needs to be a oneof field set, else it is an error.
 
 func (e encoder) marshalKnownValue(m pref.Message) error {
-	od := m.Descriptor().Oneofs().ByName("kind")
+	od := m.Descriptor().Oneofs().ByName(genid.Value_Kind_oneof_name)
 	fd := m.WhichOneof(od)
 	if fd == nil {
-		return errors.New("%s: none of the oneof fields is set", m.Descriptor().FullName())
+		return errors.New("%s: none of the oneof fields is set", genid.Value_message_fullname)
+	}
+	if fd.Number() == genid.Value_NumberValue_field_number {
+		if v := m.Get(fd).Float(); math.IsNaN(v) || math.IsInf(v, 0) {
+			return errors.New("%s: invalid %v value", genid.Value_NumberValue_field_fullname, v)
+		}
 	}
 	return e.marshalSingular(m.Get(fd), fd)
 }
@@ -530,7 +515,7 @@
 	switch tok.Kind() {
 	case json.Null:
 		d.Read()
-		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_NullValue)
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_NullValue_field_number)
 		val = pref.ValueOfEnum(0)
 
 	case json.Bool:
@@ -538,7 +523,7 @@
 		if err != nil {
 			return err
 		}
-		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_BoolValue)
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_BoolValue_field_number)
 		val = pref.ValueOfBool(tok.Bool())
 
 	case json.Number:
@@ -546,11 +531,11 @@
 		if err != nil {
 			return err
 		}
-		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_NumberValue)
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_NumberValue_field_number)
 		var ok bool
 		val, ok = unmarshalFloat(tok, 64)
 		if !ok {
-			return d.newError(tok.Pos(), "invalid google.protobuf.Value: %v", tok.RawString())
+			return d.newError(tok.Pos(), "invalid %v: %v", genid.Value_message_fullname, tok.RawString())
 		}
 
 	case json.String:
@@ -564,25 +549,25 @@
 		if err != nil {
 			return err
 		}
-		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_StringValue)
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_StringValue_field_number)
 		val = pref.ValueOfString(tok.ParsedString())
 
 	case json.ObjectOpen:
-		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_StructValue)
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_StructValue_field_number)
 		val = m.NewField(fd)
 		if err := d.unmarshalStruct(val.Message()); err != nil {
 			return err
 		}
 
 	case json.ArrayOpen:
-		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_ListValue)
+		fd = m.Descriptor().Fields().ByNumber(genid.Value_ListValue_field_number)
 		val = m.NewField(fd)
 		if err := d.unmarshalListValue(val.Message()); err != nil {
 			return err
 		}
 
 	default:
-		return d.newError(tok.Pos(), "invalid google.protobuf.Value: %v", tok.RawString())
+		return d.newError(tok.Pos(), "invalid %v: %v", genid.Value_message_fullname, tok.RawString())
 	}
 
 	m.Set(fd, val)
@@ -608,32 +593,29 @@
 
 func (e encoder) marshalDuration(m pref.Message) error {
 	fds := m.Descriptor().Fields()
-	fdSeconds := fds.ByNumber(fieldnum.Duration_Seconds)
-	fdNanos := fds.ByNumber(fieldnum.Duration_Nanos)
+	fdSeconds := fds.ByNumber(genid.Duration_Seconds_field_number)
+	fdNanos := fds.ByNumber(genid.Duration_Nanos_field_number)
 
 	secsVal := m.Get(fdSeconds)
 	nanosVal := m.Get(fdNanos)
 	secs := secsVal.Int()
 	nanos := nanosVal.Int()
 	if secs < -maxSecondsInDuration || secs > maxSecondsInDuration {
-		return errors.New("%s: seconds out of range %v", m.Descriptor().FullName(), secs)
+		return errors.New("%s: seconds out of range %v", genid.Duration_message_fullname, secs)
 	}
 	if nanos < -secondsInNanos || nanos > secondsInNanos {
-		return errors.New("%s: nanos out of range %v", m.Descriptor().FullName(), nanos)
+		return errors.New("%s: nanos out of range %v", genid.Duration_message_fullname, nanos)
 	}
 	if (secs > 0 && nanos < 0) || (secs < 0 && nanos > 0) {
-		return errors.New("%s: signs of seconds and nanos do not match", m.Descriptor().FullName())
+		return errors.New("%s: signs of seconds and nanos do not match", genid.Duration_message_fullname)
 	}
 	// Generated output always contains 0, 3, 6, or 9 fractional digits,
 	// depending on required precision, followed by the suffix "s".
-	f := "%d.%09d"
-	if nanos < 0 {
-		nanos = -nanos
-		if secs == 0 {
-			f = "-%d.%09d"
-		}
+	var sign string
+	if secs < 0 || nanos < 0 {
+		sign, secs, nanos = "-", -1*secs, -1*nanos
 	}
-	x := fmt.Sprintf(f, secs, nanos)
+	x := fmt.Sprintf("%s%d.%09d", sign, secs, nanos)
 	x = strings.TrimSuffix(x, "000")
 	x = strings.TrimSuffix(x, "000")
 	x = strings.TrimSuffix(x, ".000")
@@ -652,17 +634,17 @@
 
 	secs, nanos, ok := parseDuration(tok.ParsedString())
 	if !ok {
-		return d.newError(tok.Pos(), "invalid google.protobuf.Duration value %v", tok.RawString())
+		return d.newError(tok.Pos(), "invalid %v value %v", genid.Duration_message_fullname, tok.RawString())
 	}
 	// Validate seconds. No need to validate nanos because parseDuration would
 	// have covered that already.
 	if secs < -maxSecondsInDuration || secs > maxSecondsInDuration {
-		return d.newError(tok.Pos(), "google.protobuf.Duration value out of range: %v", tok.RawString())
+		return d.newError(tok.Pos(), "%v value out of range: %v", genid.Duration_message_fullname, tok.RawString())
 	}
 
 	fds := m.Descriptor().Fields()
-	fdSeconds := fds.ByNumber(fieldnum.Duration_Seconds)
-	fdNanos := fds.ByNumber(fieldnum.Duration_Nanos)
+	fdSeconds := fds.ByNumber(genid.Duration_Seconds_field_number)
+	fdNanos := fds.ByNumber(genid.Duration_Nanos_field_number)
 
 	m.Set(fdSeconds, pref.ValueOfInt64(secs))
 	m.Set(fdNanos, pref.ValueOfInt32(nanos))
@@ -799,18 +781,18 @@
 
 func (e encoder) marshalTimestamp(m pref.Message) error {
 	fds := m.Descriptor().Fields()
-	fdSeconds := fds.ByNumber(fieldnum.Timestamp_Seconds)
-	fdNanos := fds.ByNumber(fieldnum.Timestamp_Nanos)
+	fdSeconds := fds.ByNumber(genid.Timestamp_Seconds_field_number)
+	fdNanos := fds.ByNumber(genid.Timestamp_Nanos_field_number)
 
 	secsVal := m.Get(fdSeconds)
 	nanosVal := m.Get(fdNanos)
 	secs := secsVal.Int()
 	nanos := nanosVal.Int()
 	if secs < minTimestampSeconds || secs > maxTimestampSeconds {
-		return errors.New("%s: seconds out of range %v", m.Descriptor().FullName(), secs)
+		return errors.New("%s: seconds out of range %v", genid.Timestamp_message_fullname, secs)
 	}
 	if nanos < 0 || nanos > secondsInNanos {
-		return errors.New("%s: nanos out of range %v", m.Descriptor().FullName(), nanos)
+		return errors.New("%s: nanos out of range %v", genid.Timestamp_message_fullname, nanos)
 	}
 	// Uses RFC 3339, where generated output will be Z-normalized and uses 0, 3,
 	// 6 or 9 fractional digits.
@@ -834,18 +816,18 @@
 
 	t, err := time.Parse(time.RFC3339Nano, tok.ParsedString())
 	if err != nil {
-		return d.newError(tok.Pos(), "invalid google.protobuf.Timestamp value %v", tok.RawString())
+		return d.newError(tok.Pos(), "invalid %v value %v", genid.Timestamp_message_fullname, tok.RawString())
 	}
 	// Validate seconds. No need to validate nanos because time.Parse would have
 	// covered that already.
 	secs := t.Unix()
 	if secs < minTimestampSeconds || secs > maxTimestampSeconds {
-		return d.newError(tok.Pos(), "google.protobuf.Timestamp value out of range: %v", tok.RawString())
+		return d.newError(tok.Pos(), "%v value out of range: %v", genid.Timestamp_message_fullname, tok.RawString())
 	}
 
 	fds := m.Descriptor().Fields()
-	fdSeconds := fds.ByNumber(fieldnum.Timestamp_Seconds)
-	fdNanos := fds.ByNumber(fieldnum.Timestamp_Nanos)
+	fdSeconds := fds.ByNumber(genid.Timestamp_Seconds_field_number)
+	fdNanos := fds.ByNumber(genid.Timestamp_Nanos_field_number)
 
 	m.Set(fdSeconds, pref.ValueOfInt64(secs))
 	m.Set(fdNanos, pref.ValueOfInt32(int32(t.Nanosecond())))
@@ -858,16 +840,19 @@
 // end up differently after a round-trip.
 
 func (e encoder) marshalFieldMask(m pref.Message) error {
-	fd := m.Descriptor().Fields().ByNumber(fieldnum.FieldMask_Paths)
+	fd := m.Descriptor().Fields().ByNumber(genid.FieldMask_Paths_field_number)
 	list := m.Get(fd).List()
 	paths := make([]string, 0, list.Len())
 
 	for i := 0; i < list.Len(); i++ {
 		s := list.Get(i).String()
+		if !pref.FullName(s).IsValid() {
+			return errors.New("%s contains invalid path: %q", genid.FieldMask_Paths_field_fullname, s)
+		}
 		// Return error if conversion to camelCase is not reversible.
 		cc := strs.JSONCamelCase(s)
 		if s != strs.JSONSnakeCase(cc) {
-			return errors.New("%s.paths contains irreversible value %q", m.Descriptor().FullName(), s)
+			return errors.New("%s contains irreversible value %q", genid.FieldMask_Paths_field_fullname, s)
 		}
 		paths = append(paths, cc)
 	}
@@ -890,14 +875,15 @@
 	}
 	paths := strings.Split(str, ",")
 
-	fd := m.Descriptor().Fields().ByNumber(fieldnum.FieldMask_Paths)
+	fd := m.Descriptor().Fields().ByNumber(genid.FieldMask_Paths_field_number)
 	list := m.Mutable(fd).List()
 
-	for _, s := range paths {
-		s = strings.TrimSpace(s)
-		// Convert to snake_case. Unlike encoding, no validation is done because
-		// it is not possible to know the original path names.
-		list.Append(pref.ValueOfString(strs.JSONSnakeCase(s)))
+	for _, s0 := range paths {
+		s := strs.JSONSnakeCase(s0)
+		if strings.Contains(s0, "_") || !pref.FullName(s).IsValid() {
+			return d.newError(tok.Pos(), "%v contains invalid path: %q", genid.FieldMask_Paths_field_fullname, s0)
+		}
+		list.Append(pref.ValueOfString(s))
 	}
 	return nil
 }