1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package protojson
6
7import (
8	"bytes"
9	"fmt"
10	"strconv"
11	"strings"
12	"time"
13
14	"google.golang.org/protobuf/internal/detectknown"
15	"google.golang.org/protobuf/internal/encoding/json"
16	"google.golang.org/protobuf/internal/errors"
17	"google.golang.org/protobuf/internal/fieldnum"
18	"google.golang.org/protobuf/internal/strs"
19	"google.golang.org/protobuf/proto"
20	pref "google.golang.org/protobuf/reflect/protoreflect"
21)
22
23// isCustomType returns true if type name has special JSON conversion rules.
24// The list of custom types here has to match the ones in marshalCustomType and
25// unmarshalCustomType.
26func isCustomType(name pref.FullName) bool {
27	switch detectknown.Which(name) {
28	case detectknown.AnyProto:
29	case detectknown.TimestampProto:
30	case detectknown.DurationProto:
31	case detectknown.WrappersProto:
32	case detectknown.StructProto:
33	case detectknown.FieldMaskProto:
34	case detectknown.EmptyProto:
35	default:
36		return false
37	}
38	return true
39}
40
41// marshalCustomType marshals given well-known type message that have special
42// JSON conversion rules. It needs to be a message type where isCustomType
43// returns true, else it will panic.
44func (e encoder) marshalCustomType(m pref.Message) error {
45	name := m.Descriptor().FullName()
46	switch detectknown.Which(name) {
47	case detectknown.AnyProto:
48		return e.marshalAny(m)
49	case detectknown.TimestampProto:
50		return e.marshalTimestamp(m)
51	case detectknown.DurationProto:
52		return e.marshalDuration(m)
53	case detectknown.WrappersProto:
54		return e.marshalWrapperType(m)
55	case detectknown.StructProto:
56		return e.marshalStructType(m)
57	case detectknown.FieldMaskProto:
58		return e.marshalFieldMask(m)
59	case detectknown.EmptyProto:
60		return e.marshalEmpty(m)
61	default:
62		panic(fmt.Sprintf("%s does not have a custom marshaler", name))
63	}
64}
65
66// unmarshalCustomType unmarshals given well-known type message that have
67// special JSON conversion rules. It needs to be a message type where
68// isCustomType returns true, else it will panic.
69func (d decoder) unmarshalCustomType(m pref.Message) error {
70	name := m.Descriptor().FullName()
71	switch detectknown.Which(name) {
72	case detectknown.AnyProto:
73		return d.unmarshalAny(m)
74	case detectknown.TimestampProto:
75		return d.unmarshalTimestamp(m)
76	case detectknown.DurationProto:
77		return d.unmarshalDuration(m)
78	case detectknown.WrappersProto:
79		return d.unmarshalWrapperType(m)
80	case detectknown.StructProto:
81		return d.unmarshalStructType(m)
82	case detectknown.FieldMaskProto:
83		return d.unmarshalFieldMask(m)
84	case detectknown.EmptyProto:
85		return d.unmarshalEmpty(m)
86	default:
87		panic(fmt.Sprintf("%s does not have a custom unmarshaler", name))
88	}
89}
90
91// The JSON representation of an Any message uses the regular representation of
92// the deserialized, embedded message, with an additional field `@type` which
93// contains the type URL. If the embedded message type is well-known and has a
94// custom JSON representation, that representation will be embedded adding a
95// field `value` which holds the custom JSON in addition to the `@type` field.
96
97func (e encoder) marshalAny(m pref.Message) error {
98	fds := m.Descriptor().Fields()
99	fdType := fds.ByNumber(fieldnum.Any_TypeUrl)
100	fdValue := fds.ByNumber(fieldnum.Any_Value)
101
102	// Start writing the JSON object.
103	e.StartObject()
104	defer e.EndObject()
105
106	if !m.Has(fdType) {
107		if !m.Has(fdValue) {
108			// If message is empty, marshal out empty JSON object.
109			return nil
110		} else {
111			// Return error if type_url field is not set, but value is set.
112			return errors.New("%s: type_url is not set", m.Descriptor().FullName())
113		}
114	}
115
116	typeVal := m.Get(fdType)
117	valueVal := m.Get(fdValue)
118
119	// Marshal out @type field.
120	typeURL := typeVal.String()
121	e.WriteName("@type")
122	if err := e.WriteString(typeURL); err != nil {
123		return err
124	}
125
126	// Resolve the type in order to unmarshal value field.
127	emt, err := e.opts.Resolver.FindMessageByURL(typeURL)
128	if err != nil {
129		return errors.New("%s: unable to resolve %q: %v", m.Descriptor().FullName(), typeURL, err)
130	}
131
132	em := emt.New()
133	err = proto.UnmarshalOptions{
134		AllowPartial: true, // never check required fields inside an Any
135		Resolver:     e.opts.Resolver,
136	}.Unmarshal(valueVal.Bytes(), em.Interface())
137	if err != nil {
138		return errors.New("%s: unable to unmarshal %q: %v", m.Descriptor().FullName(), typeURL, err)
139	}
140
141	// If type of value has custom JSON encoding, marshal out a field "value"
142	// with corresponding custom JSON encoding of the embedded message as a
143	// field.
144	if isCustomType(emt.Descriptor().FullName()) {
145		e.WriteName("value")
146		return e.marshalCustomType(em)
147	}
148
149	// Else, marshal out the embedded message's fields in this Any object.
150	if err := e.marshalFields(em); err != nil {
151		return err
152	}
153
154	return nil
155}
156
157func (d decoder) unmarshalAny(m pref.Message) error {
158	// Peek to check for json.ObjectOpen to avoid advancing a read.
159	start, err := d.Peek()
160	if err != nil {
161		return err
162	}
163	if start.Kind() != json.ObjectOpen {
164		return d.unexpectedTokenError(start)
165	}
166
167	// Use another decoder to parse the unread bytes for @type field. This
168	// avoids advancing a read from current decoder because the current JSON
169	// object may contain the fields of the embedded type.
170	dec := decoder{d.Clone(), UnmarshalOptions{}}
171	tok, err := findTypeURL(dec)
172	switch err {
173	case errEmptyObject:
174		// An empty JSON object translates to an empty Any message.
175		d.Read() // Read json.ObjectOpen.
176		d.Read() // Read json.ObjectClose.
177		return nil
178
179	case errMissingType:
180		if d.opts.DiscardUnknown {
181			// Treat all fields as unknowns, similar to an empty object.
182			return d.skipJSONValue()
183		}
184		// Use start.Pos() for line position.
185		return d.newError(start.Pos(), err.Error())
186
187	default:
188		if err != nil {
189			return err
190		}
191	}
192
193	typeURL := tok.ParsedString()
194	emt, err := d.opts.Resolver.FindMessageByURL(typeURL)
195	if err != nil {
196		return d.newError(tok.Pos(), "unable to resolve %v: %q", tok.RawString(), err)
197	}
198
199	// Create new message for the embedded message type and unmarshal into it.
200	em := emt.New()
201	if isCustomType(emt.Descriptor().FullName()) {
202		// If embedded message is a custom type,
203		// unmarshal the JSON "value" field into it.
204		if err := d.unmarshalAnyValue(em); err != nil {
205			return err
206		}
207	} else {
208		// Else unmarshal the current JSON object into it.
209		if err := d.unmarshalMessage(em, true); err != nil {
210			return err
211		}
212	}
213	// Serialize the embedded message and assign the resulting bytes to the
214	// proto value field.
215	b, err := proto.MarshalOptions{
216		AllowPartial:  true, // No need to check required fields inside an Any.
217		Deterministic: true,
218	}.Marshal(em.Interface())
219	if err != nil {
220		return d.newError(start.Pos(), "error in marshaling Any.value field: %v", err)
221	}
222
223	fds := m.Descriptor().Fields()
224	fdType := fds.ByNumber(fieldnum.Any_TypeUrl)
225	fdValue := fds.ByNumber(fieldnum.Any_Value)
226
227	m.Set(fdType, pref.ValueOfString(typeURL))
228	m.Set(fdValue, pref.ValueOfBytes(b))
229	return nil
230}
231
232var errEmptyObject = fmt.Errorf(`empty object`)
233var errMissingType = fmt.Errorf(`missing "@type" field`)
234
235// findTypeURL returns the token for the "@type" field value from the given
236// JSON bytes. It is expected that the given bytes start with json.ObjectOpen.
237// It returns errEmptyObject if the JSON object is empty or errMissingType if
238// @type field does not exist. It returns other error if the @type field is not
239// valid or other decoding issues.
240func findTypeURL(d decoder) (json.Token, error) {
241	var typeURL string
242	var typeTok json.Token
243	numFields := 0
244	// Skip start object.
245	d.Read()
246
247Loop:
248	for {
249		tok, err := d.Read()
250		if err != nil {
251			return json.Token{}, err
252		}
253
254		switch tok.Kind() {
255		case json.ObjectClose:
256			if typeURL == "" {
257				// Did not find @type field.
258				if numFields > 0 {
259					return json.Token{}, errMissingType
260				}
261				return json.Token{}, errEmptyObject
262			}
263			break Loop
264
265		case json.Name:
266			numFields++
267			if tok.Name() != "@type" {
268				// Skip value.
269				if err := d.skipJSONValue(); err != nil {
270					return json.Token{}, err
271				}
272				continue
273			}
274
275			// Return error if this was previously set already.
276			if typeURL != "" {
277				return json.Token{}, d.newError(tok.Pos(), `duplicate "@type" field`)
278			}
279			// Read field value.
280			tok, err := d.Read()
281			if err != nil {
282				return json.Token{}, err
283			}
284			if tok.Kind() != json.String {
285				return json.Token{}, d.newError(tok.Pos(), `@type field value is not a string: %v`, tok.RawString())
286			}
287			typeURL = tok.ParsedString()
288			if typeURL == "" {
289				return json.Token{}, d.newError(tok.Pos(), `@type field contains empty value`)
290			}
291			typeTok = tok
292		}
293	}
294
295	return typeTok, nil
296}
297
298// skipJSONValue parses a JSON value (null, boolean, string, number, object and
299// array) in order to advance the read to the next JSON value. It relies on
300// the decoder returning an error if the types are not in valid sequence.
301func (d decoder) skipJSONValue() error {
302	tok, err := d.Read()
303	if err != nil {
304		return err
305	}
306	// Only need to continue reading for objects and arrays.
307	switch tok.Kind() {
308	case json.ObjectOpen:
309		for {
310			tok, err := d.Read()
311			if err != nil {
312				return err
313			}
314			switch tok.Kind() {
315			case json.ObjectClose:
316				return nil
317			case json.Name:
318				// Skip object field value.
319				if err := d.skipJSONValue(); err != nil {
320					return err
321				}
322			}
323		}
324
325	case json.ArrayOpen:
326		for {
327			tok, err := d.Peek()
328			if err != nil {
329				return err
330			}
331			switch tok.Kind() {
332			case json.ArrayClose:
333				d.Read()
334				return nil
335			default:
336				// Skip array item.
337				if err := d.skipJSONValue(); err != nil {
338					return err
339				}
340			}
341		}
342	}
343	return nil
344}
345
346// unmarshalAnyValue unmarshals the given custom-type message from the JSON
347// object's "value" field.
348func (d decoder) unmarshalAnyValue(m pref.Message) error {
349	// Skip ObjectOpen, and start reading the fields.
350	d.Read()
351
352	var found bool // Used for detecting duplicate "value".
353	for {
354		tok, err := d.Read()
355		if err != nil {
356			return err
357		}
358		switch tok.Kind() {
359		case json.ObjectClose:
360			if !found {
361				return d.newError(tok.Pos(), `missing "value" field`)
362			}
363			return nil
364
365		case json.Name:
366			switch tok.Name() {
367			case "@type":
368				// Skip the value as this was previously parsed already.
369				d.Read()
370
371			case "value":
372				if found {
373					return d.newError(tok.Pos(), `duplicate "value" field`)
374				}
375				// Unmarshal the field value into the given message.
376				if err := d.unmarshalCustomType(m); err != nil {
377					return err
378				}
379				found = true
380
381			default:
382				if d.opts.DiscardUnknown {
383					if err := d.skipJSONValue(); err != nil {
384						return err
385					}
386					continue
387				}
388				return d.newError(tok.Pos(), "unknown field %v", tok.RawString())
389			}
390		}
391	}
392}
393
394// Wrapper types are encoded as JSON primitives like string, number or boolean.
395
396// The "value" field has the same field number for all wrapper types.
397const wrapperFieldNumber = fieldnum.BoolValue_Value
398
399func (e encoder) marshalWrapperType(m pref.Message) error {
400	fd := m.Descriptor().Fields().ByNumber(wrapperFieldNumber)
401	val := m.Get(fd)
402	return e.marshalSingular(val, fd)
403}
404
405func (d decoder) unmarshalWrapperType(m pref.Message) error {
406	fd := m.Descriptor().Fields().ByNumber(wrapperFieldNumber)
407	val, err := d.unmarshalScalar(fd)
408	if err != nil {
409		return err
410	}
411	m.Set(fd, val)
412	return nil
413}
414
415// The JSON representation for Empty is an empty JSON object.
416
417func (e encoder) marshalEmpty(pref.Message) error {
418	e.StartObject()
419	e.EndObject()
420	return nil
421}
422
423func (d decoder) unmarshalEmpty(pref.Message) error {
424	tok, err := d.Read()
425	if err != nil {
426		return err
427	}
428	if tok.Kind() != json.ObjectOpen {
429		return d.unexpectedTokenError(tok)
430	}
431
432	for {
433		tok, err := d.Read()
434		if err != nil {
435			return err
436		}
437		switch tok.Kind() {
438		case json.ObjectClose:
439			return nil
440
441		case json.Name:
442			if d.opts.DiscardUnknown {
443				if err := d.skipJSONValue(); err != nil {
444					return err
445				}
446				continue
447			}
448			return d.newError(tok.Pos(), "unknown field %v", tok.RawString())
449
450		default:
451			return d.unexpectedTokenError(tok)
452		}
453	}
454}
455
456func (e encoder) marshalStructType(m pref.Message) error {
457	switch m.Descriptor().Name() {
458	case "Struct":
459		return e.marshalStruct(m)
460	case "ListValue":
461		return e.marshalListValue(m)
462	case "Value":
463		return e.marshalKnownValue(m)
464	default:
465		panic(fmt.Sprintf("invalid struct type: %v", m.Descriptor().FullName()))
466	}
467}
468
469func (d decoder) unmarshalStructType(m pref.Message) error {
470	switch m.Descriptor().Name() {
471	case "Struct":
472		return d.unmarshalStruct(m)
473	case "ListValue":
474		return d.unmarshalListValue(m)
475	case "Value":
476		return d.unmarshalKnownValue(m)
477	default:
478		panic(fmt.Sprintf("invalid struct type: %v", m.Descriptor().FullName()))
479	}
480}
481
482// The JSON representation for Struct is a JSON object that contains the encoded
483// Struct.fields map and follows the serialization rules for a map.
484
485func (e encoder) marshalStruct(m pref.Message) error {
486	fd := m.Descriptor().Fields().ByNumber(fieldnum.Struct_Fields)
487	return e.marshalMap(m.Get(fd).Map(), fd)
488}
489
490func (d decoder) unmarshalStruct(m pref.Message) error {
491	fd := m.Descriptor().Fields().ByNumber(fieldnum.Struct_Fields)
492	return d.unmarshalMap(m.Mutable(fd).Map(), fd)
493}
494
495// The JSON representation for ListValue is JSON array that contains the encoded
496// ListValue.values repeated field and follows the serialization rules for a
497// repeated field.
498
499func (e encoder) marshalListValue(m pref.Message) error {
500	fd := m.Descriptor().Fields().ByNumber(fieldnum.ListValue_Values)
501	return e.marshalList(m.Get(fd).List(), fd)
502}
503
504func (d decoder) unmarshalListValue(m pref.Message) error {
505	fd := m.Descriptor().Fields().ByNumber(fieldnum.ListValue_Values)
506	return d.unmarshalList(m.Mutable(fd).List(), fd)
507}
508
509// The JSON representation for a Value is dependent on the oneof field that is
510// set. Each of the field in the oneof has its own custom serialization rule. A
511// Value message needs to be a oneof field set, else it is an error.
512
513func (e encoder) marshalKnownValue(m pref.Message) error {
514	od := m.Descriptor().Oneofs().ByName("kind")
515	fd := m.WhichOneof(od)
516	if fd == nil {
517		return errors.New("%s: none of the oneof fields is set", m.Descriptor().FullName())
518	}
519	return e.marshalSingular(m.Get(fd), fd)
520}
521
522func (d decoder) unmarshalKnownValue(m pref.Message) error {
523	tok, err := d.Peek()
524	if err != nil {
525		return err
526	}
527
528	var fd pref.FieldDescriptor
529	var val pref.Value
530	switch tok.Kind() {
531	case json.Null:
532		d.Read()
533		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_NullValue)
534		val = pref.ValueOfEnum(0)
535
536	case json.Bool:
537		tok, err := d.Read()
538		if err != nil {
539			return err
540		}
541		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_BoolValue)
542		val = pref.ValueOfBool(tok.Bool())
543
544	case json.Number:
545		tok, err := d.Read()
546		if err != nil {
547			return err
548		}
549		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_NumberValue)
550		var ok bool
551		val, ok = unmarshalFloat(tok, 64)
552		if !ok {
553			return d.newError(tok.Pos(), "invalid google.protobuf.Value: %v", tok.RawString())
554		}
555
556	case json.String:
557		// A JSON string may have been encoded from the number_value field,
558		// e.g. "NaN", "Infinity", etc. Parsing a proto double type also allows
559		// for it to be in JSON string form. Given this custom encoding spec,
560		// however, there is no way to identify that and hence a JSON string is
561		// always assigned to the string_value field, which means that certain
562		// encoding cannot be parsed back to the same field.
563		tok, err := d.Read()
564		if err != nil {
565			return err
566		}
567		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_StringValue)
568		val = pref.ValueOfString(tok.ParsedString())
569
570	case json.ObjectOpen:
571		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_StructValue)
572		val = m.NewField(fd)
573		if err := d.unmarshalStruct(val.Message()); err != nil {
574			return err
575		}
576
577	case json.ArrayOpen:
578		fd = m.Descriptor().Fields().ByNumber(fieldnum.Value_ListValue)
579		val = m.NewField(fd)
580		if err := d.unmarshalListValue(val.Message()); err != nil {
581			return err
582		}
583
584	default:
585		return d.newError(tok.Pos(), "invalid google.protobuf.Value: %v", tok.RawString())
586	}
587
588	m.Set(fd, val)
589	return nil
590}
591
592// The JSON representation for a Duration is a JSON string that ends in the
593// suffix "s" (indicating seconds) and is preceded by the number of seconds,
594// with nanoseconds expressed as fractional seconds.
595//
596// Durations less than one second are represented with a 0 seconds field and a
597// positive or negative nanos field. For durations of one second or more, a
598// non-zero value for the nanos field must be of the same sign as the seconds
599// field.
600//
601// Duration.seconds must be from -315,576,000,000 to +315,576,000,000 inclusive.
602// Duration.nanos must be from -999,999,999 to +999,999,999 inclusive.
603
604const (
605	secondsInNanos       = 999999999
606	maxSecondsInDuration = 315576000000
607)
608
609func (e encoder) marshalDuration(m pref.Message) error {
610	fds := m.Descriptor().Fields()
611	fdSeconds := fds.ByNumber(fieldnum.Duration_Seconds)
612	fdNanos := fds.ByNumber(fieldnum.Duration_Nanos)
613
614	secsVal := m.Get(fdSeconds)
615	nanosVal := m.Get(fdNanos)
616	secs := secsVal.Int()
617	nanos := nanosVal.Int()
618	if secs < -maxSecondsInDuration || secs > maxSecondsInDuration {
619		return errors.New("%s: seconds out of range %v", m.Descriptor().FullName(), secs)
620	}
621	if nanos < -secondsInNanos || nanos > secondsInNanos {
622		return errors.New("%s: nanos out of range %v", m.Descriptor().FullName(), nanos)
623	}
624	if (secs > 0 && nanos < 0) || (secs < 0 && nanos > 0) {
625		return errors.New("%s: signs of seconds and nanos do not match", m.Descriptor().FullName())
626	}
627	// Generated output always contains 0, 3, 6, or 9 fractional digits,
628	// depending on required precision, followed by the suffix "s".
629	f := "%d.%09d"
630	if nanos < 0 {
631		nanos = -nanos
632		if secs == 0 {
633			f = "-%d.%09d"
634		}
635	}
636	x := fmt.Sprintf(f, secs, nanos)
637	x = strings.TrimSuffix(x, "000")
638	x = strings.TrimSuffix(x, "000")
639	x = strings.TrimSuffix(x, ".000")
640	e.WriteString(x + "s")
641	return nil
642}
643
644func (d decoder) unmarshalDuration(m pref.Message) error {
645	tok, err := d.Read()
646	if err != nil {
647		return err
648	}
649	if tok.Kind() != json.String {
650		return d.unexpectedTokenError(tok)
651	}
652
653	secs, nanos, ok := parseDuration(tok.ParsedString())
654	if !ok {
655		return d.newError(tok.Pos(), "invalid google.protobuf.Duration value %v", tok.RawString())
656	}
657	// Validate seconds. No need to validate nanos because parseDuration would
658	// have covered that already.
659	if secs < -maxSecondsInDuration || secs > maxSecondsInDuration {
660		return d.newError(tok.Pos(), "google.protobuf.Duration value out of range: %v", tok.RawString())
661	}
662
663	fds := m.Descriptor().Fields()
664	fdSeconds := fds.ByNumber(fieldnum.Duration_Seconds)
665	fdNanos := fds.ByNumber(fieldnum.Duration_Nanos)
666
667	m.Set(fdSeconds, pref.ValueOfInt64(secs))
668	m.Set(fdNanos, pref.ValueOfInt32(nanos))
669	return nil
670}
671
672// parseDuration parses the given input string for seconds and nanoseconds value
673// for the Duration JSON format. The format is a decimal number with a suffix
674// 's'. It can have optional plus/minus sign. There needs to be at least an
675// integer or fractional part. Fractional part is limited to 9 digits only for
676// nanoseconds precision, regardless of whether there are trailing zero digits.
677// Example values are 1s, 0.1s, 1.s, .1s, +1s, -1s, -.1s.
678func parseDuration(input string) (int64, int32, bool) {
679	b := []byte(input)
680	size := len(b)
681	if size < 2 {
682		return 0, 0, false
683	}
684	if b[size-1] != 's' {
685		return 0, 0, false
686	}
687	b = b[:size-1]
688
689	// Read optional plus/minus symbol.
690	var neg bool
691	switch b[0] {
692	case '-':
693		neg = true
694		b = b[1:]
695	case '+':
696		b = b[1:]
697	}
698	if len(b) == 0 {
699		return 0, 0, false
700	}
701
702	// Read the integer part.
703	var intp []byte
704	switch {
705	case b[0] == '0':
706		b = b[1:]
707
708	case '1' <= b[0] && b[0] <= '9':
709		intp = b[0:]
710		b = b[1:]
711		n := 1
712		for len(b) > 0 && '0' <= b[0] && b[0] <= '9' {
713			n++
714			b = b[1:]
715		}
716		intp = intp[:n]
717
718	case b[0] == '.':
719		// Continue below.
720
721	default:
722		return 0, 0, false
723	}
724
725	hasFrac := false
726	var frac [9]byte
727	if len(b) > 0 {
728		if b[0] != '.' {
729			return 0, 0, false
730		}
731		// Read the fractional part.
732		b = b[1:]
733		n := 0
734		for len(b) > 0 && n < 9 && '0' <= b[0] && b[0] <= '9' {
735			frac[n] = b[0]
736			n++
737			b = b[1:]
738		}
739		// It is not valid if there are more bytes left.
740		if len(b) > 0 {
741			return 0, 0, false
742		}
743		// Pad fractional part with 0s.
744		for i := n; i < 9; i++ {
745			frac[i] = '0'
746		}
747		hasFrac = true
748	}
749
750	var secs int64
751	if len(intp) > 0 {
752		var err error
753		secs, err = strconv.ParseInt(string(intp), 10, 64)
754		if err != nil {
755			return 0, 0, false
756		}
757	}
758
759	var nanos int64
760	if hasFrac {
761		nanob := bytes.TrimLeft(frac[:], "0")
762		if len(nanob) > 0 {
763			var err error
764			nanos, err = strconv.ParseInt(string(nanob), 10, 32)
765			if err != nil {
766				return 0, 0, false
767			}
768		}
769	}
770
771	if neg {
772		if secs > 0 {
773			secs = -secs
774		}
775		if nanos > 0 {
776			nanos = -nanos
777		}
778	}
779	return secs, int32(nanos), true
780}
781
782// The JSON representation for a Timestamp is a JSON string in the RFC 3339
783// format, i.e. "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" where
784// {year} is always expressed using four digits while {month}, {day}, {hour},
785// {min}, and {sec} are zero-padded to two digits each. The fractional seconds,
786// which can go up to 9 digits, up to 1 nanosecond resolution, is optional. The
787// "Z" suffix indicates the timezone ("UTC"); the timezone is required. Encoding
788// should always use UTC (as indicated by "Z") and a decoder should be able to
789// accept both UTC and other timezones (as indicated by an offset).
790//
791// Timestamp.seconds must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z
792// inclusive.
793// Timestamp.nanos must be from 0 to 999,999,999 inclusive.
794
795const (
796	maxTimestampSeconds = 253402300799
797	minTimestampSeconds = -62135596800
798)
799
800func (e encoder) marshalTimestamp(m pref.Message) error {
801	fds := m.Descriptor().Fields()
802	fdSeconds := fds.ByNumber(fieldnum.Timestamp_Seconds)
803	fdNanos := fds.ByNumber(fieldnum.Timestamp_Nanos)
804
805	secsVal := m.Get(fdSeconds)
806	nanosVal := m.Get(fdNanos)
807	secs := secsVal.Int()
808	nanos := nanosVal.Int()
809	if secs < minTimestampSeconds || secs > maxTimestampSeconds {
810		return errors.New("%s: seconds out of range %v", m.Descriptor().FullName(), secs)
811	}
812	if nanos < 0 || nanos > secondsInNanos {
813		return errors.New("%s: nanos out of range %v", m.Descriptor().FullName(), nanos)
814	}
815	// Uses RFC 3339, where generated output will be Z-normalized and uses 0, 3,
816	// 6 or 9 fractional digits.
817	t := time.Unix(secs, nanos).UTC()
818	x := t.Format("2006-01-02T15:04:05.000000000")
819	x = strings.TrimSuffix(x, "000")
820	x = strings.TrimSuffix(x, "000")
821	x = strings.TrimSuffix(x, ".000")
822	e.WriteString(x + "Z")
823	return nil
824}
825
826func (d decoder) unmarshalTimestamp(m pref.Message) error {
827	tok, err := d.Read()
828	if err != nil {
829		return err
830	}
831	if tok.Kind() != json.String {
832		return d.unexpectedTokenError(tok)
833	}
834
835	t, err := time.Parse(time.RFC3339Nano, tok.ParsedString())
836	if err != nil {
837		return d.newError(tok.Pos(), "invalid google.protobuf.Timestamp value %v", tok.RawString())
838	}
839	// Validate seconds. No need to validate nanos because time.Parse would have
840	// covered that already.
841	secs := t.Unix()
842	if secs < minTimestampSeconds || secs > maxTimestampSeconds {
843		return d.newError(tok.Pos(), "google.protobuf.Timestamp value out of range: %v", tok.RawString())
844	}
845
846	fds := m.Descriptor().Fields()
847	fdSeconds := fds.ByNumber(fieldnum.Timestamp_Seconds)
848	fdNanos := fds.ByNumber(fieldnum.Timestamp_Nanos)
849
850	m.Set(fdSeconds, pref.ValueOfInt64(secs))
851	m.Set(fdNanos, pref.ValueOfInt32(int32(t.Nanosecond())))
852	return nil
853}
854
855// The JSON representation for a FieldMask is a JSON string where paths are
856// separated by a comma. Fields name in each path are converted to/from
857// lower-camel naming conventions. Encoding should fail if the path name would
858// end up differently after a round-trip.
859
860func (e encoder) marshalFieldMask(m pref.Message) error {
861	fd := m.Descriptor().Fields().ByNumber(fieldnum.FieldMask_Paths)
862	list := m.Get(fd).List()
863	paths := make([]string, 0, list.Len())
864
865	for i := 0; i < list.Len(); i++ {
866		s := list.Get(i).String()
867		// Return error if conversion to camelCase is not reversible.
868		cc := strs.JSONCamelCase(s)
869		if s != strs.JSONSnakeCase(cc) {
870			return errors.New("%s.paths contains irreversible value %q", m.Descriptor().FullName(), s)
871		}
872		paths = append(paths, cc)
873	}
874
875	e.WriteString(strings.Join(paths, ","))
876	return nil
877}
878
879func (d decoder) unmarshalFieldMask(m pref.Message) error {
880	tok, err := d.Read()
881	if err != nil {
882		return err
883	}
884	if tok.Kind() != json.String {
885		return d.unexpectedTokenError(tok)
886	}
887	str := strings.TrimSpace(tok.ParsedString())
888	if str == "" {
889		return nil
890	}
891	paths := strings.Split(str, ",")
892
893	fd := m.Descriptor().Fields().ByNumber(fieldnum.FieldMask_Paths)
894	list := m.Mutable(fd).List()
895
896	for _, s := range paths {
897		s = strings.TrimSpace(s)
898		// Convert to snake_case. Unlike encoding, no validation is done because
899		// it is not possible to know the original path names.
900		list.Append(pref.ValueOfString(strs.JSONSnakeCase(s)))
901	}
902	return nil
903}
904