// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package protojson

import (
	"bytes"
	"fmt"
	"strconv"
	"strings"
	"time"

	"google.golang.org/protobuf/internal/encoding/json"
	"google.golang.org/protobuf/internal/errors"
	"google.golang.org/protobuf/internal/fieldnum"
	"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 name {
	case "google.protobuf.Any",
		"google.protobuf.BoolValue",
		"google.protobuf.DoubleValue",
		"google.protobuf.FloatValue",
		"google.protobuf.Int32Value",
		"google.protobuf.Int64Value",
		"google.protobuf.UInt32Value",
		"google.protobuf.UInt64Value",
		"google.protobuf.StringValue",
		"google.protobuf.BytesValue",
		"google.protobuf.Empty",
		"google.protobuf.Struct",
		"google.protobuf.ListValue",
		"google.protobuf.Value",
		"google.protobuf.Duration",
		"google.protobuf.Timestamp",
		"google.protobuf.FieldMask":
		return true
	}
	return false
}

// 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 (o MarshalOptions) marshalCustomType(m pref.Message) error {
	name := m.Descriptor().FullName()
	switch name {
	case "google.protobuf.Any":
		return o.marshalAny(m)

	case "google.protobuf.BoolValue",
		"google.protobuf.DoubleValue",
		"google.protobuf.FloatValue",
		"google.protobuf.Int32Value",
		"google.protobuf.Int64Value",
		"google.protobuf.UInt32Value",
		"google.protobuf.UInt64Value",
		"google.protobuf.StringValue",
		"google.protobuf.BytesValue":
		return o.marshalWrapperType(m)

	case "google.protobuf.Empty":
		return o.marshalEmpty(m)

	case "google.protobuf.Struct":
		return o.marshalStruct(m)

	case "google.protobuf.ListValue":
		return o.marshalListValue(m)

	case "google.protobuf.Value":
		return o.marshalKnownValue(m)

	case "google.protobuf.Duration":
		return o.marshalDuration(m)

	case "google.protobuf.Timestamp":
		return o.marshalTimestamp(m)

	case "google.protobuf.FieldMask":
		return o.marshalFieldMask(m)
	}

	panic(fmt.Sprintf("%q does not have a custom marshaler", name))
}

// 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 (o UnmarshalOptions) unmarshalCustomType(m pref.Message) error {
	name := m.Descriptor().FullName()
	switch name {
	case "google.protobuf.Any":
		return o.unmarshalAny(m)

	case "google.protobuf.BoolValue",
		"google.protobuf.DoubleValue",
		"google.protobuf.FloatValue",
		"google.protobuf.Int32Value",
		"google.protobuf.Int64Value",
		"google.protobuf.UInt32Value",
		"google.protobuf.UInt64Value",
		"google.protobuf.StringValue",
		"google.protobuf.BytesValue":
		return o.unmarshalWrapperType(m)

	case "google.protobuf.Empty":
		return o.unmarshalEmpty(m)

	case "google.protobuf.Struct":
		return o.unmarshalStruct(m)

	case "google.protobuf.ListValue":
		return o.unmarshalListValue(m)

	case "google.protobuf.Value":
		return o.unmarshalKnownValue(m)

	case "google.protobuf.Duration":
		return o.unmarshalDuration(m)

	case "google.protobuf.Timestamp":
		return o.unmarshalTimestamp(m)

	case "google.protobuf.FieldMask":
		return o.unmarshalFieldMask(m)
	}

	panic(fmt.Sprintf("%q does not have a custom unmarshaler", name))
}

// The JSON representation of an Any message uses the regular representation of
// the deserialized, embedded message, with an additional field `@type` which
// contains the type URL. If the embedded message type is well-known and has a
// custom JSON representation, that representation will be embedded adding a
// field `value` which holds the custom JSON in addition to the `@type` field.

func (o MarshalOptions) 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.
	o.encoder.StartObject()
	defer o.encoder.EndObject()

	if !m.Has(fdType) {
		if !m.Has(fdValue) {
			// If message is empty, marshal out empty JSON object.
			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())
		}
	}

	typeVal := m.Get(fdType)
	valueVal := m.Get(fdValue)

	// Marshal out @type field.
	typeURL := typeVal.String()
	o.encoder.WriteName("@type")
	if err := o.encoder.WriteString(typeURL); err != nil {
		return err
	}

	// Resolve the type in order to unmarshal value field.
	emt, err := o.Resolver.FindMessageByURL(typeURL)
	if err != nil {
		return errors.New("%s: unable to resolve %q: %v", m.Descriptor().FullName(), typeURL, err)
	}

	em := emt.New()
	err = proto.UnmarshalOptions{
		AllowPartial: true, // never check required fields inside an Any
		Resolver:     o.Resolver,
	}.Unmarshal(valueVal.Bytes(), em.Interface())
	if err != nil {
		return errors.New("%s: unable to unmarshal %q: %v", m.Descriptor().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()) {
		o.encoder.WriteName("value")
		return o.marshalCustomType(em)
	}

	// Else, marshal out the embedded message's fields in this Any object.
	if err := o.marshalFields(em); err != nil {
		return err
	}

	return nil
}

func (o UnmarshalOptions) unmarshalAny(m pref.Message) error {
	// Use Peek to check for json.StartObject to avoid advancing a read.
	if o.decoder.Peek() != json.StartObject {
		jval, _ := o.decoder.Read()
		return unexpectedJSONError{jval}
	}

	// Use another json.Decoder to parse the unread bytes from o.decoder for
	// @type field. This avoids advancing a read from o.decoder because the
	// current JSON object may contain the fields of the embedded type.
	dec := o.decoder.Clone()
	typeURL, err := findTypeURL(dec)
	if err == errEmptyObject {
		// An empty JSON object translates to an empty Any message.
		o.decoder.Read() // Read json.StartObject.
		o.decoder.Read() // Read json.EndObject.
		return nil
	}
	if o.DiscardUnknown && err == errMissingType {
		// Treat all fields as unknowns, similar to an empty object.
		return skipJSONValue(o.decoder)
	}
	if err != nil {
		return errors.New("google.protobuf.Any: %v", err)
	}

	emt, err := o.Resolver.FindMessageByURL(typeURL)
	if err != nil {
		return errors.New("google.protobuf.Any: unable to resolve type %q: %v", typeURL, err)
	}

	// Create new message for the embedded message type and unmarshal into it.
	em := emt.New()
	if isCustomType(emt.Descriptor().FullName()) {
		// If embedded message is a custom type, unmarshal the JSON "value" field
		// into it.
		if err := o.unmarshalAnyValue(em); err != nil {
			return errors.New("google.protobuf.Any: %v", err)
		}
	} else {
		// Else unmarshal the current JSON object into it.
		if err := o.unmarshalMessage(em, true); err != nil {
			return errors.New("google.protobuf.Any: %v", err)
		}
	}
	// Serialize the embedded message and assign the resulting bytes to the
	// proto value field.
	b, err := proto.MarshalOptions{
		AllowPartial:  true, // never check required fields inside an Any
		Deterministic: true,
	}.Marshal(em.Interface())
	if err != nil {
		return errors.New("google.protobuf.Any: %v", err)
	}

	fds := m.Descriptor().Fields()
	fdType := fds.ByNumber(fieldnum.Any_TypeUrl)
	fdValue := fds.ByNumber(fieldnum.Any_Value)

	m.Set(fdType, pref.ValueOfString(typeURL))
	m.Set(fdValue, pref.ValueOfBytes(b))
	return nil
}

var errEmptyObject = errors.New(`empty object`)
var errMissingType = errors.New(`missing "@type" field`)

// findTypeURL returns the "@type" field value from the given JSON bytes. It is
// expected that the given bytes start with json.StartObject. It returns
// errEmptyObject if the JSON object is empty. It returns error if the object
// does not contain the field or other decoding problems.
func findTypeURL(dec *json.Decoder) (string, error) {
	var typeURL string
	numFields := 0
	// Skip start object.
	dec.Read()

Loop:
	for {
		jval, err := dec.Read()
		if err != nil {
			return "", err
		}

		switch jval.Type() {
		case json.EndObject:
			if typeURL == "" {
				// Did not find @type field.
				if numFields > 0 {
					return "", errMissingType
				}
				return "", errEmptyObject
			}
			break Loop

		case json.Name:
			numFields++
			name, err := jval.Name()
			if err != nil {
				return "", err
			}
			if name != "@type" {
				// Skip value.
				if err := skipJSONValue(dec); err != nil {
					return "", err
				}
				continue
			}

			// Return error if this was previously set already.
			if typeURL != "" {
				return "", errors.New(`duplicate "@type" field`)
			}
			// Read field value.
			jval, err := dec.Read()
			if err != nil {
				return "", err
			}
			if jval.Type() != json.String {
				return "", unexpectedJSONError{jval}
			}
			typeURL = jval.String()
			if typeURL == "" {
				return "", errors.New(`"@type" field contains empty value`)
			}
		}
	}

	return typeURL, nil
}

// skipJSONValue makes the given decoder parse a JSON value (null, boolean,
// string, number, object and array) in order to advance the read to the next
// JSON value. It relies on Decoder.Read returning an error if the types are
// not in valid sequence.
func skipJSONValue(dec *json.Decoder) error {
	jval, err := dec.Read()
	if err != nil {
		return err
	}
	// Only need to continue reading for objects and arrays.
	switch jval.Type() {
	case json.StartObject:
		for {
			jval, err := dec.Read()
			if err != nil {
				return err
			}
			switch jval.Type() {
			case json.EndObject:
				return nil
			case json.Name:
				// Skip object field value.
				if err := skipJSONValue(dec); err != nil {
					return err
				}
			}
		}

	case json.StartArray:
		for {
			switch dec.Peek() {
			case json.EndArray:
				dec.Read()
				return nil
			case json.Invalid:
				_, err := dec.Read()
				return err
			default:
				// Skip array item.
				if err := skipJSONValue(dec); err != nil {
					return err
				}
			}
		}
	}
	return nil
}

// unmarshalAnyValue unmarshals the given custom-type message from the JSON
// object's "value" field.
func (o UnmarshalOptions) unmarshalAnyValue(m pref.Message) error {
	// Skip StartObject, and start reading the fields.
	o.decoder.Read()

	var found bool // Used for detecting duplicate "value".
	for {
		jval, err := o.decoder.Read()
		if err != nil {
			return err
		}
		switch jval.Type() {
		case json.EndObject:
			if !found {
				return errors.New(`missing "value" field`)
			}
			return nil

		case json.Name:
			name, err := jval.Name()
			if err != nil {
				return err
			}
			switch name {
			default:
				if o.DiscardUnknown {
					if err := skipJSONValue(o.decoder); err != nil {
						return err
					}
					continue
				}
				return errors.New("unknown field %q", name)

			case "@type":
				// Skip the value as this was previously parsed already.
				o.decoder.Read()

			case "value":
				if found {
					return errors.New(`duplicate "value" field`)
				}
				// Unmarshal the field value into the given message.
				if err := o.unmarshalCustomType(m); err != nil {
					return err
				}
				found = true
			}
		}
	}
}

// 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 (o MarshalOptions) marshalWrapperType(m pref.Message) error {
	fd := m.Descriptor().Fields().ByNumber(wrapperFieldNumber)
	val := m.Get(fd)
	return o.marshalSingular(val, fd)
}

func (o UnmarshalOptions) unmarshalWrapperType(m pref.Message) error {
	fd := m.Descriptor().Fields().ByNumber(wrapperFieldNumber)
	val, err := o.unmarshalScalar(fd)
	if err != nil {
		return err
	}
	m.Set(fd, val)
	return nil
}

// The JSON representation for Empty is an empty JSON object.

func (o MarshalOptions) marshalEmpty(pref.Message) error {
	o.encoder.StartObject()
	o.encoder.EndObject()
	return nil
}

func (o UnmarshalOptions) unmarshalEmpty(pref.Message) error {
	jval, err := o.decoder.Read()
	if err != nil {
		return err
	}
	if jval.Type() != json.StartObject {
		return unexpectedJSONError{jval}
	}

	for {
		jval, err := o.decoder.Read()
		if err != nil {
			return err
		}
		switch jval.Type() {
		case json.EndObject:
			return nil

		case json.Name:
			if o.DiscardUnknown {
				if err := skipJSONValue(o.decoder); err != nil {
					return err
				}
				continue
			}
			name, _ := jval.Name()
			return errors.New("unknown field %q", name)

		default:
			return unexpectedJSONError{jval}
		}
	}
}

// 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 (o MarshalOptions) marshalStruct(m pref.Message) error {
	fd := m.Descriptor().Fields().ByNumber(fieldnum.Struct_Fields)
	return o.marshalMap(m.Get(fd).Map(), fd)
}

func (o UnmarshalOptions) unmarshalStruct(m pref.Message) error {
	fd := m.Descriptor().Fields().ByNumber(fieldnum.Struct_Fields)
	return o.unmarshalMap(m.Mutable(fd).Map(), fd)
}

// The JSON representation for ListValue is JSON array that contains the encoded
// ListValue.values repeated field and follows the serialization rules for a
// repeated field.

func (o MarshalOptions) marshalListValue(m pref.Message) error {
	fd := m.Descriptor().Fields().ByNumber(fieldnum.ListValue_Values)
	return o.marshalList(m.Get(fd).List(), fd)
}

func (o UnmarshalOptions) unmarshalListValue(m pref.Message) error {
	fd := m.Descriptor().Fields().ByNumber(fieldnum.ListValue_Values)
	return o.unmarshalList(m.Mutable(fd).List(), fd)
}

// The JSON representation for a Value is dependent on the oneof field that is
// set. Each of the field in the oneof has its own custom serialization rule. A
// Value message needs to be a oneof field set, else it is an error.

func (o MarshalOptions) marshalKnownValue(m pref.Message) error {
	od := m.Descriptor().Oneofs().ByName("kind")
	fd := m.WhichOneof(od)
	if fd == nil {
		return errors.New("%s: none of the oneof fields is set", m.Descriptor().FullName())
	}
	return o.marshalSingular(m.Get(fd), fd)
}

func (o UnmarshalOptions) unmarshalKnownValue(m pref.Message) error {
	switch o.decoder.Peek() {
	case json.Null:
		o.decoder.Read()
		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_NullValue)
		m.Set(fd, pref.ValueOfEnum(0))

	case json.Bool:
		jval, err := o.decoder.Read()
		if err != nil {
			return err
		}
		val, err := unmarshalBool(jval)
		if err != nil {
			return err
		}
		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_BoolValue)
		m.Set(fd, val)

	case json.Number:
		jval, err := o.decoder.Read()
		if err != nil {
			return err
		}
		val, err := unmarshalFloat(jval, 64)
		if err != nil {
			return err
		}
		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_NumberValue)
		m.Set(fd, val)

	case json.String:
		// A JSON string may have been encoded from the number_value field,
		// e.g. "NaN", "Infinity", etc. Parsing a proto double type also allows
		// for it to be in JSON string form. Given this custom encoding spec,
		// however, there is no way to identify that and hence a JSON string is
		// always assigned to the string_value field, which means that certain
		// encoding cannot be parsed back to the same field.
		jval, err := o.decoder.Read()
		if err != nil {
			return err
		}
		val, err := unmarshalString(jval)
		if err != nil {
			return err
		}
		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_StringValue)
		m.Set(fd, val)

	case json.StartObject:
		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_StructValue)
		val := m.NewField(fd)
		if err := o.unmarshalStruct(val.Message()); err != nil {
			return err
		}
		m.Set(fd, val)

	case json.StartArray:
		fd := m.Descriptor().Fields().ByNumber(fieldnum.Value_ListValue)
		val := m.NewField(fd)
		if err := o.unmarshalListValue(val.Message()); err != nil {
			return err
		}
		m.Set(fd, val)

	default:
		jval, err := o.decoder.Read()
		if err != nil {
			return err
		}
		return unexpectedJSONError{jval}
	}
	return nil
}

// The JSON representation for a Duration is a JSON string that ends in the
// suffix "s" (indicating seconds) and is preceded by the number of seconds,
// with nanoseconds expressed as fractional seconds.
//
// Durations less than one second are represented with a 0 seconds field and a
// positive or negative nanos field. For durations of one second or more, a
// non-zero value for the nanos field must be of the same sign as the seconds
// field.
//
// Duration.seconds must be from -315,576,000,000 to +315,576,000,000 inclusive.
// Duration.nanos must be from -999,999,999 to +999,999,999 inclusive.

const (
	secondsInNanos       = 999999999
	maxSecondsInDuration = 315576000000
)

func (o MarshalOptions) marshalDuration(m pref.Message) error {
	fds := m.Descriptor().Fields()
	fdSeconds := fds.ByNumber(fieldnum.Duration_Seconds)
	fdNanos := fds.ByNumber(fieldnum.Duration_Nanos)

	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)
	}
	if nanos < -secondsInNanos || nanos > secondsInNanos {
		return errors.New("%s: nanos out of range %v", m.Descriptor().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())
	}
	// 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"
		}
	}
	x := fmt.Sprintf(f, secs, nanos)
	x = strings.TrimSuffix(x, "000")
	x = strings.TrimSuffix(x, "000")
	x = strings.TrimSuffix(x, ".000")
	o.encoder.WriteString(x + "s")
	return nil
}

func (o UnmarshalOptions) unmarshalDuration(m pref.Message) error {
	jval, err := o.decoder.Read()
	if err != nil {
		return err
	}
	if jval.Type() != json.String {
		return unexpectedJSONError{jval}
	}

	input := jval.String()
	secs, nanos, ok := parseDuration(input)
	if !ok {
		return errors.New("%s: invalid duration value %q", m.Descriptor().FullName(), input)
	}
	// Validate seconds. No need to validate nanos because parseDuration would
	// have covered that already.
	if secs < -maxSecondsInDuration || secs > maxSecondsInDuration {
		return errors.New("%s: out of range %q", m.Descriptor().FullName(), input)
	}

	fds := m.Descriptor().Fields()
	fdSeconds := fds.ByNumber(fieldnum.Duration_Seconds)
	fdNanos := fds.ByNumber(fieldnum.Duration_Nanos)

	m.Set(fdSeconds, pref.ValueOfInt64(secs))
	m.Set(fdNanos, pref.ValueOfInt32(nanos))
	return nil
}

// parseDuration parses the given input string for seconds and nanoseconds value
// for the Duration JSON format. The format is a decimal number with a suffix
// 's'. It can have optional plus/minus sign. There needs to be at least an
// integer or fractional part. Fractional part is limited to 9 digits only for
// nanoseconds precision, regardless of whether there are trailing zero digits.
// Example values are 1s, 0.1s, 1.s, .1s, +1s, -1s, -.1s.
func parseDuration(input string) (int64, int32, bool) {
	b := []byte(input)
	size := len(b)
	if size < 2 {
		return 0, 0, false
	}
	if b[size-1] != 's' {
		return 0, 0, false
	}
	b = b[:size-1]

	// Read optional plus/minus symbol.
	var neg bool
	switch b[0] {
	case '-':
		neg = true
		b = b[1:]
	case '+':
		b = b[1:]
	}
	if len(b) == 0 {
		return 0, 0, false
	}

	// Read the integer part.
	var intp []byte
	switch {
	case b[0] == '0':
		b = b[1:]

	case '1' <= b[0] && b[0] <= '9':
		intp = b[0:]
		b = b[1:]
		n := 1
		for len(b) > 0 && '0' <= b[0] && b[0] <= '9' {
			n++
			b = b[1:]
		}
		intp = intp[:n]

	case b[0] == '.':
		// Continue below.

	default:
		return 0, 0, false
	}

	hasFrac := false
	var frac [9]byte
	if len(b) > 0 {
		if b[0] != '.' {
			return 0, 0, false
		}
		// Read the fractional part.
		b = b[1:]
		n := 0
		for len(b) > 0 && n < 9 && '0' <= b[0] && b[0] <= '9' {
			frac[n] = b[0]
			n++
			b = b[1:]
		}
		// It is not valid if there are more bytes left.
		if len(b) > 0 {
			return 0, 0, false
		}
		// Pad fractional part with 0s.
		for i := n; i < 9; i++ {
			frac[i] = '0'
		}
		hasFrac = true
	}

	var secs int64
	if len(intp) > 0 {
		var err error
		secs, err = strconv.ParseInt(string(intp), 10, 64)
		if err != nil {
			return 0, 0, false
		}
	}

	var nanos int64
	if hasFrac {
		nanob := bytes.TrimLeft(frac[:], "0")
		if len(nanob) > 0 {
			var err error
			nanos, err = strconv.ParseInt(string(nanob), 10, 32)
			if err != nil {
				return 0, 0, false
			}
		}
	}

	if neg {
		if secs > 0 {
			secs = -secs
		}
		if nanos > 0 {
			nanos = -nanos
		}
	}
	return secs, int32(nanos), true
}

// The JSON representation for a Timestamp is a JSON string in the RFC 3339
// format, i.e. "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" where
// {year} is always expressed using four digits while {month}, {day}, {hour},
// {min}, and {sec} are zero-padded to two digits each. The fractional seconds,
// which can go up to 9 digits, up to 1 nanosecond resolution, is optional. The
// "Z" suffix indicates the timezone ("UTC"); the timezone is required. Encoding
// should always use UTC (as indicated by "Z") and a decoder should be able to
// accept both UTC and other timezones (as indicated by an offset).
//
// Timestamp.seconds must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z
// inclusive.
// Timestamp.nanos must be from 0 to 999,999,999 inclusive.

const (
	maxTimestampSeconds = 253402300799
	minTimestampSeconds = -62135596800
)

func (o MarshalOptions) marshalTimestamp(m pref.Message) error {
	fds := m.Descriptor().Fields()
	fdSeconds := fds.ByNumber(fieldnum.Timestamp_Seconds)
	fdNanos := fds.ByNumber(fieldnum.Timestamp_Nanos)

	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)
	}
	if nanos < 0 || nanos > secondsInNanos {
		return errors.New("%s: nanos out of range %v", m.Descriptor().FullName(), nanos)
	}
	// Uses RFC 3339, where generated output will be Z-normalized and uses 0, 3,
	// 6 or 9 fractional digits.
	t := time.Unix(secs, nanos).UTC()
	x := t.Format("2006-01-02T15:04:05.000000000")
	x = strings.TrimSuffix(x, "000")
	x = strings.TrimSuffix(x, "000")
	x = strings.TrimSuffix(x, ".000")
	o.encoder.WriteString(x + "Z")
	return nil
}

func (o UnmarshalOptions) unmarshalTimestamp(m pref.Message) error {
	jval, err := o.decoder.Read()
	if err != nil {
		return err
	}
	if jval.Type() != json.String {
		return unexpectedJSONError{jval}
	}

	input := jval.String()
	t, err := time.Parse(time.RFC3339Nano, input)
	if err != nil {
		return errors.New("%s: invalid timestamp value %q", m.Descriptor().FullName(), input)
	}
	// Validate seconds. No need to validate nanos because time.Parse would have
	// covered that already.
	secs := t.Unix()
	if secs < minTimestampSeconds || secs > maxTimestampSeconds {
		return errors.New("%s: out of range %q", m.Descriptor().FullName(), input)
	}

	fds := m.Descriptor().Fields()
	fdSeconds := fds.ByNumber(fieldnum.Timestamp_Seconds)
	fdNanos := fds.ByNumber(fieldnum.Timestamp_Nanos)

	m.Set(fdSeconds, pref.ValueOfInt64(secs))
	m.Set(fdNanos, pref.ValueOfInt32(int32(t.Nanosecond())))
	return nil
}

// The JSON representation for a FieldMask is a JSON string where paths are
// separated by a comma. Fields name in each path are converted to/from
// lower-camel naming conventions. Encoding should fail if the path name would
// end up differently after a round-trip.

func (o MarshalOptions) marshalFieldMask(m pref.Message) error {
	fd := m.Descriptor().Fields().ByNumber(fieldnum.FieldMask_Paths)
	list := m.Get(fd).List()
	paths := make([]string, 0, list.Len())

	for i := 0; i < list.Len(); i++ {
		s := list.Get(i).String()
		// 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)
		}
		paths = append(paths, cc)
	}

	o.encoder.WriteString(strings.Join(paths, ","))
	return nil
}

func (o UnmarshalOptions) unmarshalFieldMask(m pref.Message) error {
	jval, err := o.decoder.Read()
	if err != nil {
		return err
	}
	if jval.Type() != json.String {
		return unexpectedJSONError{jval}
	}
	str := strings.TrimSpace(jval.String())
	if str == "" {
		return nil
	}
	paths := strings.Split(str, ",")

	fd := m.Descriptor().Fields().ByNumber(fieldnum.FieldMask_Paths)
	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)))
	}
	return nil
}
