updated GHA
Update to v2 SDK updated dependencies
This commit is contained in:
		
							
								
								
									
										665
									
								
								vendor/google.golang.org/protobuf/encoding/protojson/decode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										665
									
								
								vendor/google.golang.org/protobuf/encoding/protojson/decode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,665 @@ | ||||
| // 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 ( | ||||
| 	"encoding/base64" | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"google.golang.org/protobuf/internal/encoding/json" | ||||
| 	"google.golang.org/protobuf/internal/encoding/messageset" | ||||
| 	"google.golang.org/protobuf/internal/errors" | ||||
| 	"google.golang.org/protobuf/internal/flags" | ||||
| 	"google.golang.org/protobuf/internal/genid" | ||||
| 	"google.golang.org/protobuf/internal/pragma" | ||||
| 	"google.golang.org/protobuf/internal/set" | ||||
| 	"google.golang.org/protobuf/proto" | ||||
| 	pref "google.golang.org/protobuf/reflect/protoreflect" | ||||
| 	"google.golang.org/protobuf/reflect/protoregistry" | ||||
| ) | ||||
|  | ||||
| // Unmarshal reads the given []byte into the given proto.Message. | ||||
| // The provided message must be mutable (e.g., a non-nil pointer to a message). | ||||
| func Unmarshal(b []byte, m proto.Message) error { | ||||
| 	return UnmarshalOptions{}.Unmarshal(b, m) | ||||
| } | ||||
|  | ||||
| // UnmarshalOptions is a configurable JSON format parser. | ||||
| type UnmarshalOptions struct { | ||||
| 	pragma.NoUnkeyedLiterals | ||||
|  | ||||
| 	// If AllowPartial is set, input for messages that will result in missing | ||||
| 	// required fields will not return an error. | ||||
| 	AllowPartial bool | ||||
|  | ||||
| 	// If DiscardUnknown is set, unknown fields are ignored. | ||||
| 	DiscardUnknown bool | ||||
|  | ||||
| 	// Resolver is used for looking up types when unmarshaling | ||||
| 	// google.protobuf.Any messages or extension fields. | ||||
| 	// If nil, this defaults to using protoregistry.GlobalTypes. | ||||
| 	Resolver interface { | ||||
| 		protoregistry.MessageTypeResolver | ||||
| 		protoregistry.ExtensionTypeResolver | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Unmarshal reads the given []byte and populates the given proto.Message | ||||
| // using options in the UnmarshalOptions object. | ||||
| // It will clear the message first before setting the fields. | ||||
| // If it returns an error, the given message may be partially set. | ||||
| // The provided message must be mutable (e.g., a non-nil pointer to a message). | ||||
| func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error { | ||||
| 	return o.unmarshal(b, m) | ||||
| } | ||||
|  | ||||
| // unmarshal is a centralized function that all unmarshal operations go through. | ||||
| // For profiling purposes, avoid changing the name of this function or | ||||
| // introducing other code paths for unmarshal that do not go through this. | ||||
| func (o UnmarshalOptions) unmarshal(b []byte, m proto.Message) error { | ||||
| 	proto.Reset(m) | ||||
|  | ||||
| 	if o.Resolver == nil { | ||||
| 		o.Resolver = protoregistry.GlobalTypes | ||||
| 	} | ||||
|  | ||||
| 	dec := decoder{json.NewDecoder(b), o} | ||||
| 	if err := dec.unmarshalMessage(m.ProtoReflect(), false); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	// Check for EOF. | ||||
| 	tok, err := dec.Read() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if tok.Kind() != json.EOF { | ||||
| 		return dec.unexpectedTokenError(tok) | ||||
| 	} | ||||
|  | ||||
| 	if o.AllowPartial { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return proto.CheckInitialized(m) | ||||
| } | ||||
|  | ||||
| type decoder struct { | ||||
| 	*json.Decoder | ||||
| 	opts UnmarshalOptions | ||||
| } | ||||
|  | ||||
| // newError returns an error object with position info. | ||||
| func (d decoder) newError(pos int, f string, x ...interface{}) error { | ||||
| 	line, column := d.Position(pos) | ||||
| 	head := fmt.Sprintf("(line %d:%d): ", line, column) | ||||
| 	return errors.New(head+f, x...) | ||||
| } | ||||
|  | ||||
| // unexpectedTokenError returns a syntax error for the given unexpected token. | ||||
| func (d decoder) unexpectedTokenError(tok json.Token) error { | ||||
| 	return d.syntaxError(tok.Pos(), "unexpected token %s", tok.RawString()) | ||||
| } | ||||
|  | ||||
| // syntaxError returns a syntax error for given position. | ||||
| func (d decoder) syntaxError(pos int, f string, x ...interface{}) error { | ||||
| 	line, column := d.Position(pos) | ||||
| 	head := fmt.Sprintf("syntax error (line %d:%d): ", line, column) | ||||
| 	return errors.New(head+f, x...) | ||||
| } | ||||
|  | ||||
| // unmarshalMessage unmarshals a message into the given protoreflect.Message. | ||||
| func (d decoder) unmarshalMessage(m pref.Message, skipTypeURL bool) error { | ||||
| 	if unmarshal := wellKnownTypeUnmarshaler(m.Descriptor().FullName()); unmarshal != nil { | ||||
| 		return unmarshal(d, m) | ||||
| 	} | ||||
|  | ||||
| 	tok, err := d.Read() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if tok.Kind() != json.ObjectOpen { | ||||
| 		return d.unexpectedTokenError(tok) | ||||
| 	} | ||||
|  | ||||
| 	messageDesc := m.Descriptor() | ||||
| 	if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) { | ||||
| 		return errors.New("no support for proto1 MessageSets") | ||||
| 	} | ||||
|  | ||||
| 	var seenNums set.Ints | ||||
| 	var seenOneofs set.Ints | ||||
| 	fieldDescs := messageDesc.Fields() | ||||
| 	for { | ||||
| 		// Read field name. | ||||
| 		tok, err := d.Read() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		switch tok.Kind() { | ||||
| 		default: | ||||
| 			return d.unexpectedTokenError(tok) | ||||
| 		case json.ObjectClose: | ||||
| 			return nil | ||||
| 		case json.Name: | ||||
| 			// Continue below. | ||||
| 		} | ||||
|  | ||||
| 		name := tok.Name() | ||||
| 		// Unmarshaling a non-custom embedded message in Any will contain the | ||||
| 		// JSON field "@type" which should be skipped because it is not a field | ||||
| 		// of the embedded message, but simply an artifact of the Any format. | ||||
| 		if skipTypeURL && name == "@type" { | ||||
| 			d.Read() | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// Get the FieldDescriptor. | ||||
| 		var fd pref.FieldDescriptor | ||||
| 		if strings.HasPrefix(name, "[") && strings.HasSuffix(name, "]") { | ||||
| 			// Only extension names are in [name] format. | ||||
| 			extName := pref.FullName(name[1 : len(name)-1]) | ||||
| 			extType, err := d.opts.Resolver.FindExtensionByName(extName) | ||||
| 			if err != nil && err != protoregistry.NotFound { | ||||
| 				return d.newError(tok.Pos(), "unable to resolve %s: %v", tok.RawString(), err) | ||||
| 			} | ||||
| 			if extType != nil { | ||||
| 				fd = extType.TypeDescriptor() | ||||
| 				if !messageDesc.ExtensionRanges().Has(fd.Number()) || fd.ContainingMessage().FullName() != messageDesc.FullName() { | ||||
| 					return d.newError(tok.Pos(), "message %v cannot be extended by %v", messageDesc.FullName(), fd.FullName()) | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			// The name can either be the JSON name or the proto field name. | ||||
| 			fd = fieldDescs.ByJSONName(name) | ||||
| 			if fd == nil { | ||||
| 				fd = fieldDescs.ByTextName(name) | ||||
| 			} | ||||
| 		} | ||||
| 		if flags.ProtoLegacy { | ||||
| 			if fd != nil && fd.IsWeak() && fd.Message().IsPlaceholder() { | ||||
| 				fd = nil // reset since the weak reference is not linked in | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if fd == nil { | ||||
| 			// Field is unknown. | ||||
| 			if d.opts.DiscardUnknown { | ||||
| 				if err := d.skipJSONValue(); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				continue | ||||
| 			} | ||||
| 			return d.newError(tok.Pos(), "unknown field %v", tok.RawString()) | ||||
| 		} | ||||
|  | ||||
| 		// Do not allow duplicate fields. | ||||
| 		num := uint64(fd.Number()) | ||||
| 		if seenNums.Has(num) { | ||||
| 			return d.newError(tok.Pos(), "duplicate field %v", tok.RawString()) | ||||
| 		} | ||||
| 		seenNums.Set(num) | ||||
|  | ||||
| 		// No need to set values for JSON null unless the field type is | ||||
| 		// google.protobuf.Value or google.protobuf.NullValue. | ||||
| 		if tok, _ := d.Peek(); tok.Kind() == json.Null && !isKnownValue(fd) && !isNullValue(fd) { | ||||
| 			d.Read() | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		switch { | ||||
| 		case fd.IsList(): | ||||
| 			list := m.Mutable(fd).List() | ||||
| 			if err := d.unmarshalList(list, fd); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		case fd.IsMap(): | ||||
| 			mmap := m.Mutable(fd).Map() | ||||
| 			if err := d.unmarshalMap(mmap, fd); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		default: | ||||
| 			// If field is a oneof, check if it has already been set. | ||||
| 			if od := fd.ContainingOneof(); od != nil { | ||||
| 				idx := uint64(od.Index()) | ||||
| 				if seenOneofs.Has(idx) { | ||||
| 					return d.newError(tok.Pos(), "error parsing %s, oneof %v is already set", tok.RawString(), od.FullName()) | ||||
| 				} | ||||
| 				seenOneofs.Set(idx) | ||||
| 			} | ||||
|  | ||||
| 			// Required or optional fields. | ||||
| 			if err := d.unmarshalSingular(m, fd); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func isKnownValue(fd pref.FieldDescriptor) bool { | ||||
| 	md := fd.Message() | ||||
| 	return md != nil && md.FullName() == genid.Value_message_fullname | ||||
| } | ||||
|  | ||||
| func isNullValue(fd pref.FieldDescriptor) bool { | ||||
| 	ed := fd.Enum() | ||||
| 	return ed != nil && ed.FullName() == genid.NullValue_enum_fullname | ||||
| } | ||||
|  | ||||
| // unmarshalSingular unmarshals to the non-repeated field specified | ||||
| // by the given FieldDescriptor. | ||||
| func (d decoder) unmarshalSingular(m pref.Message, fd pref.FieldDescriptor) error { | ||||
| 	var val pref.Value | ||||
| 	var err error | ||||
| 	switch fd.Kind() { | ||||
| 	case pref.MessageKind, pref.GroupKind: | ||||
| 		val = m.NewField(fd) | ||||
| 		err = d.unmarshalMessage(val.Message(), false) | ||||
| 	default: | ||||
| 		val, err = d.unmarshalScalar(fd) | ||||
| 	} | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	m.Set(fd, val) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // unmarshalScalar unmarshals to a scalar/enum protoreflect.Value specified by | ||||
| // the given FieldDescriptor. | ||||
| func (d decoder) unmarshalScalar(fd pref.FieldDescriptor) (pref.Value, error) { | ||||
| 	const b32 int = 32 | ||||
| 	const b64 int = 64 | ||||
|  | ||||
| 	tok, err := d.Read() | ||||
| 	if err != nil { | ||||
| 		return pref.Value{}, err | ||||
| 	} | ||||
|  | ||||
| 	kind := fd.Kind() | ||||
| 	switch kind { | ||||
| 	case pref.BoolKind: | ||||
| 		if tok.Kind() == json.Bool { | ||||
| 			return pref.ValueOfBool(tok.Bool()), nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: | ||||
| 		if v, ok := unmarshalInt(tok, b32); ok { | ||||
| 			return v, nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: | ||||
| 		if v, ok := unmarshalInt(tok, b64); ok { | ||||
| 			return v, nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.Uint32Kind, pref.Fixed32Kind: | ||||
| 		if v, ok := unmarshalUint(tok, b32); ok { | ||||
| 			return v, nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.Uint64Kind, pref.Fixed64Kind: | ||||
| 		if v, ok := unmarshalUint(tok, b64); ok { | ||||
| 			return v, nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.FloatKind: | ||||
| 		if v, ok := unmarshalFloat(tok, b32); ok { | ||||
| 			return v, nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.DoubleKind: | ||||
| 		if v, ok := unmarshalFloat(tok, b64); ok { | ||||
| 			return v, nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.StringKind: | ||||
| 		if tok.Kind() == json.String { | ||||
| 			return pref.ValueOfString(tok.ParsedString()), nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.BytesKind: | ||||
| 		if v, ok := unmarshalBytes(tok); ok { | ||||
| 			return v, nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.EnumKind: | ||||
| 		if v, ok := unmarshalEnum(tok, fd); ok { | ||||
| 			return v, nil | ||||
| 		} | ||||
|  | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("unmarshalScalar: invalid scalar kind %v", kind)) | ||||
| 	} | ||||
|  | ||||
| 	return pref.Value{}, d.newError(tok.Pos(), "invalid value for %v type: %v", kind, tok.RawString()) | ||||
| } | ||||
|  | ||||
| func unmarshalInt(tok json.Token, bitSize int) (pref.Value, bool) { | ||||
| 	switch tok.Kind() { | ||||
| 	case json.Number: | ||||
| 		return getInt(tok, bitSize) | ||||
|  | ||||
| 	case json.String: | ||||
| 		// Decode number from string. | ||||
| 		s := strings.TrimSpace(tok.ParsedString()) | ||||
| 		if len(s) != len(tok.ParsedString()) { | ||||
| 			return pref.Value{}, false | ||||
| 		} | ||||
| 		dec := json.NewDecoder([]byte(s)) | ||||
| 		tok, err := dec.Read() | ||||
| 		if err != nil { | ||||
| 			return pref.Value{}, false | ||||
| 		} | ||||
| 		return getInt(tok, bitSize) | ||||
| 	} | ||||
| 	return pref.Value{}, false | ||||
| } | ||||
|  | ||||
| func getInt(tok json.Token, bitSize int) (pref.Value, bool) { | ||||
| 	n, ok := tok.Int(bitSize) | ||||
| 	if !ok { | ||||
| 		return pref.Value{}, false | ||||
| 	} | ||||
| 	if bitSize == 32 { | ||||
| 		return pref.ValueOfInt32(int32(n)), true | ||||
| 	} | ||||
| 	return pref.ValueOfInt64(n), true | ||||
| } | ||||
|  | ||||
| func unmarshalUint(tok json.Token, bitSize int) (pref.Value, bool) { | ||||
| 	switch tok.Kind() { | ||||
| 	case json.Number: | ||||
| 		return getUint(tok, bitSize) | ||||
|  | ||||
| 	case json.String: | ||||
| 		// Decode number from string. | ||||
| 		s := strings.TrimSpace(tok.ParsedString()) | ||||
| 		if len(s) != len(tok.ParsedString()) { | ||||
| 			return pref.Value{}, false | ||||
| 		} | ||||
| 		dec := json.NewDecoder([]byte(s)) | ||||
| 		tok, err := dec.Read() | ||||
| 		if err != nil { | ||||
| 			return pref.Value{}, false | ||||
| 		} | ||||
| 		return getUint(tok, bitSize) | ||||
| 	} | ||||
| 	return pref.Value{}, false | ||||
| } | ||||
|  | ||||
| func getUint(tok json.Token, bitSize int) (pref.Value, bool) { | ||||
| 	n, ok := tok.Uint(bitSize) | ||||
| 	if !ok { | ||||
| 		return pref.Value{}, false | ||||
| 	} | ||||
| 	if bitSize == 32 { | ||||
| 		return pref.ValueOfUint32(uint32(n)), true | ||||
| 	} | ||||
| 	return pref.ValueOfUint64(n), true | ||||
| } | ||||
|  | ||||
| func unmarshalFloat(tok json.Token, bitSize int) (pref.Value, bool) { | ||||
| 	switch tok.Kind() { | ||||
| 	case json.Number: | ||||
| 		return getFloat(tok, bitSize) | ||||
|  | ||||
| 	case json.String: | ||||
| 		s := tok.ParsedString() | ||||
| 		switch s { | ||||
| 		case "NaN": | ||||
| 			if bitSize == 32 { | ||||
| 				return pref.ValueOfFloat32(float32(math.NaN())), true | ||||
| 			} | ||||
| 			return pref.ValueOfFloat64(math.NaN()), true | ||||
| 		case "Infinity": | ||||
| 			if bitSize == 32 { | ||||
| 				return pref.ValueOfFloat32(float32(math.Inf(+1))), true | ||||
| 			} | ||||
| 			return pref.ValueOfFloat64(math.Inf(+1)), true | ||||
| 		case "-Infinity": | ||||
| 			if bitSize == 32 { | ||||
| 				return pref.ValueOfFloat32(float32(math.Inf(-1))), true | ||||
| 			} | ||||
| 			return pref.ValueOfFloat64(math.Inf(-1)), true | ||||
| 		} | ||||
|  | ||||
| 		// Decode number from string. | ||||
| 		if len(s) != len(strings.TrimSpace(s)) { | ||||
| 			return pref.Value{}, false | ||||
| 		} | ||||
| 		dec := json.NewDecoder([]byte(s)) | ||||
| 		tok, err := dec.Read() | ||||
| 		if err != nil { | ||||
| 			return pref.Value{}, false | ||||
| 		} | ||||
| 		return getFloat(tok, bitSize) | ||||
| 	} | ||||
| 	return pref.Value{}, false | ||||
| } | ||||
|  | ||||
| func getFloat(tok json.Token, bitSize int) (pref.Value, bool) { | ||||
| 	n, ok := tok.Float(bitSize) | ||||
| 	if !ok { | ||||
| 		return pref.Value{}, false | ||||
| 	} | ||||
| 	if bitSize == 32 { | ||||
| 		return pref.ValueOfFloat32(float32(n)), true | ||||
| 	} | ||||
| 	return pref.ValueOfFloat64(n), true | ||||
| } | ||||
|  | ||||
| func unmarshalBytes(tok json.Token) (pref.Value, bool) { | ||||
| 	if tok.Kind() != json.String { | ||||
| 		return pref.Value{}, false | ||||
| 	} | ||||
|  | ||||
| 	s := tok.ParsedString() | ||||
| 	enc := base64.StdEncoding | ||||
| 	if strings.ContainsAny(s, "-_") { | ||||
| 		enc = base64.URLEncoding | ||||
| 	} | ||||
| 	if len(s)%4 != 0 { | ||||
| 		enc = enc.WithPadding(base64.NoPadding) | ||||
| 	} | ||||
| 	b, err := enc.DecodeString(s) | ||||
| 	if err != nil { | ||||
| 		return pref.Value{}, false | ||||
| 	} | ||||
| 	return pref.ValueOfBytes(b), true | ||||
| } | ||||
|  | ||||
| func unmarshalEnum(tok json.Token, fd pref.FieldDescriptor) (pref.Value, bool) { | ||||
| 	switch tok.Kind() { | ||||
| 	case json.String: | ||||
| 		// Lookup EnumNumber based on name. | ||||
| 		s := tok.ParsedString() | ||||
| 		if enumVal := fd.Enum().Values().ByName(pref.Name(s)); enumVal != nil { | ||||
| 			return pref.ValueOfEnum(enumVal.Number()), true | ||||
| 		} | ||||
|  | ||||
| 	case json.Number: | ||||
| 		if n, ok := tok.Int(32); ok { | ||||
| 			return pref.ValueOfEnum(pref.EnumNumber(n)), true | ||||
| 		} | ||||
|  | ||||
| 	case json.Null: | ||||
| 		// This is only valid for google.protobuf.NullValue. | ||||
| 		if isNullValue(fd) { | ||||
| 			return pref.ValueOfEnum(0), true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return pref.Value{}, false | ||||
| } | ||||
|  | ||||
| func (d decoder) unmarshalList(list pref.List, fd pref.FieldDescriptor) error { | ||||
| 	tok, err := d.Read() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if tok.Kind() != json.ArrayOpen { | ||||
| 		return d.unexpectedTokenError(tok) | ||||
| 	} | ||||
|  | ||||
| 	switch fd.Kind() { | ||||
| 	case pref.MessageKind, pref.GroupKind: | ||||
| 		for { | ||||
| 			tok, err := d.Peek() | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			if tok.Kind() == json.ArrayClose { | ||||
| 				d.Read() | ||||
| 				return nil | ||||
| 			} | ||||
|  | ||||
| 			val := list.NewElement() | ||||
| 			if err := d.unmarshalMessage(val.Message(), false); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			list.Append(val) | ||||
| 		} | ||||
| 	default: | ||||
| 		for { | ||||
| 			tok, err := d.Peek() | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			if tok.Kind() == json.ArrayClose { | ||||
| 				d.Read() | ||||
| 				return nil | ||||
| 			} | ||||
|  | ||||
| 			val, err := d.unmarshalScalar(fd) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			list.Append(val) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (d decoder) unmarshalMap(mmap pref.Map, fd pref.FieldDescriptor) error { | ||||
| 	tok, err := d.Read() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if tok.Kind() != json.ObjectOpen { | ||||
| 		return d.unexpectedTokenError(tok) | ||||
| 	} | ||||
|  | ||||
| 	// 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. | ||||
| 	var unmarshalMapValue func() (pref.Value, error) | ||||
| 	switch fd.MapValue().Kind() { | ||||
| 	case pref.MessageKind, pref.GroupKind: | ||||
| 		unmarshalMapValue = func() (pref.Value, error) { | ||||
| 			val := mmap.NewValue() | ||||
| 			if err := d.unmarshalMessage(val.Message(), false); err != nil { | ||||
| 				return pref.Value{}, err | ||||
| 			} | ||||
| 			return val, nil | ||||
| 		} | ||||
| 	default: | ||||
| 		unmarshalMapValue = func() (pref.Value, error) { | ||||
| 			return d.unmarshalScalar(fd.MapValue()) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| Loop: | ||||
| 	for { | ||||
| 		// Read field name. | ||||
| 		tok, err := d.Read() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		switch tok.Kind() { | ||||
| 		default: | ||||
| 			return d.unexpectedTokenError(tok) | ||||
| 		case json.ObjectClose: | ||||
| 			break Loop | ||||
| 		case json.Name: | ||||
| 			// Continue. | ||||
| 		} | ||||
|  | ||||
| 		// Unmarshal field name. | ||||
| 		pkey, err := d.unmarshalMapKey(tok, fd.MapKey()) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		// Check for duplicate field name. | ||||
| 		if mmap.Has(pkey) { | ||||
| 			return d.newError(tok.Pos(), "duplicate map key %v", tok.RawString()) | ||||
| 		} | ||||
|  | ||||
| 		// Read and unmarshal field value. | ||||
| 		pval, err := unmarshalMapValue() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		mmap.Set(pkey, pval) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // unmarshalMapKey converts given token of Name kind into a protoreflect.MapKey. | ||||
| // A map key type is any integral or string type. | ||||
| func (d decoder) unmarshalMapKey(tok json.Token, fd pref.FieldDescriptor) (pref.MapKey, error) { | ||||
| 	const b32 = 32 | ||||
| 	const b64 = 64 | ||||
| 	const base10 = 10 | ||||
|  | ||||
| 	name := tok.Name() | ||||
| 	kind := fd.Kind() | ||||
| 	switch kind { | ||||
| 	case pref.StringKind: | ||||
| 		return pref.ValueOfString(name).MapKey(), nil | ||||
|  | ||||
| 	case pref.BoolKind: | ||||
| 		switch name { | ||||
| 		case "true": | ||||
| 			return pref.ValueOfBool(true).MapKey(), nil | ||||
| 		case "false": | ||||
| 			return pref.ValueOfBool(false).MapKey(), nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: | ||||
| 		if n, err := strconv.ParseInt(name, base10, b32); err == nil { | ||||
| 			return pref.ValueOfInt32(int32(n)).MapKey(), nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: | ||||
| 		if n, err := strconv.ParseInt(name, base10, b64); err == nil { | ||||
| 			return pref.ValueOfInt64(int64(n)).MapKey(), nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.Uint32Kind, pref.Fixed32Kind: | ||||
| 		if n, err := strconv.ParseUint(name, base10, b32); err == nil { | ||||
| 			return pref.ValueOfUint32(uint32(n)).MapKey(), nil | ||||
| 		} | ||||
|  | ||||
| 	case pref.Uint64Kind, pref.Fixed64Kind: | ||||
| 		if n, err := strconv.ParseUint(name, base10, b64); err == nil { | ||||
| 			return pref.ValueOfUint64(uint64(n)).MapKey(), nil | ||||
| 		} | ||||
|  | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("invalid kind for map key: %v", kind)) | ||||
| 	} | ||||
|  | ||||
| 	return pref.MapKey{}, d.newError(tok.Pos(), "invalid value for %v key: %s", kind, tok.RawString()) | ||||
| } | ||||
							
								
								
									
										11
									
								
								vendor/google.golang.org/protobuf/encoding/protojson/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/google.golang.org/protobuf/encoding/protojson/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| // 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 marshals and unmarshals protocol buffer messages as JSON | ||||
| // format. It follows the guide at | ||||
| // https://developers.google.com/protocol-buffers/docs/proto3#json. | ||||
| // | ||||
| // This package produces a different output than the standard "encoding/json" | ||||
| // package, which does not operate correctly on protocol buffer messages. | ||||
| package protojson | ||||
							
								
								
									
										344
									
								
								vendor/google.golang.org/protobuf/encoding/protojson/encode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										344
									
								
								vendor/google.golang.org/protobuf/encoding/protojson/encode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,344 @@ | ||||
| // 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 ( | ||||
| 	"encoding/base64" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"google.golang.org/protobuf/internal/encoding/json" | ||||
| 	"google.golang.org/protobuf/internal/encoding/messageset" | ||||
| 	"google.golang.org/protobuf/internal/errors" | ||||
| 	"google.golang.org/protobuf/internal/filedesc" | ||||
| 	"google.golang.org/protobuf/internal/flags" | ||||
| 	"google.golang.org/protobuf/internal/genid" | ||||
| 	"google.golang.org/protobuf/internal/order" | ||||
| 	"google.golang.org/protobuf/internal/pragma" | ||||
| 	"google.golang.org/protobuf/proto" | ||||
| 	"google.golang.org/protobuf/reflect/protoreflect" | ||||
| 	pref "google.golang.org/protobuf/reflect/protoreflect" | ||||
| 	"google.golang.org/protobuf/reflect/protoregistry" | ||||
| ) | ||||
|  | ||||
| const defaultIndent = "  " | ||||
|  | ||||
| // Format formats the message as a multiline string. | ||||
| // This function is only intended for human consumption and ignores errors. | ||||
| // Do not depend on the output being stable. It may change over time across | ||||
| // different versions of the program. | ||||
| func Format(m proto.Message) string { | ||||
| 	return MarshalOptions{Multiline: true}.Format(m) | ||||
| } | ||||
|  | ||||
| // Marshal writes the given proto.Message in JSON format using default options. | ||||
| // Do not depend on the output being stable. It may change over time across | ||||
| // different versions of the program. | ||||
| func Marshal(m proto.Message) ([]byte, error) { | ||||
| 	return MarshalOptions{}.Marshal(m) | ||||
| } | ||||
|  | ||||
| // MarshalOptions is a configurable JSON format marshaler. | ||||
| type MarshalOptions struct { | ||||
| 	pragma.NoUnkeyedLiterals | ||||
|  | ||||
| 	// Multiline specifies whether the marshaler should format the output in | ||||
| 	// indented-form with every textual element on a new line. | ||||
| 	// If Indent is an empty string, then an arbitrary indent is chosen. | ||||
| 	Multiline bool | ||||
|  | ||||
| 	// Indent specifies the set of indentation characters to use in a multiline | ||||
| 	// formatted output such that every entry is preceded by Indent and | ||||
| 	// terminated by a newline. If non-empty, then Multiline is treated as true. | ||||
| 	// Indent can only be composed of space or tab characters. | ||||
| 	Indent string | ||||
|  | ||||
| 	// AllowPartial allows messages that have missing required fields to marshal | ||||
| 	// without returning an error. If AllowPartial is false (the default), | ||||
| 	// Marshal will return error if there are any missing required fields. | ||||
| 	AllowPartial bool | ||||
|  | ||||
| 	// UseProtoNames uses proto field name instead of lowerCamelCase name in JSON | ||||
| 	// field names. | ||||
| 	UseProtoNames bool | ||||
|  | ||||
| 	// UseEnumNumbers emits enum values as numbers. | ||||
| 	UseEnumNumbers bool | ||||
|  | ||||
| 	// EmitUnpopulated specifies whether to emit unpopulated fields. It does not | ||||
| 	// emit unpopulated oneof fields or unpopulated extension fields. | ||||
| 	// The JSON value emitted for unpopulated fields are as follows: | ||||
| 	//  ╔═══════╤════════════════════════════╗ | ||||
| 	//  ║ JSON  │ Protobuf field             ║ | ||||
| 	//  ╠═══════╪════════════════════════════╣ | ||||
| 	//  ║ false │ proto3 boolean fields      ║ | ||||
| 	//  ║ 0     │ proto3 numeric fields      ║ | ||||
| 	//  ║ ""    │ proto3 string/bytes fields ║ | ||||
| 	//  ║ null  │ proto2 scalar fields       ║ | ||||
| 	//  ║ null  │ message fields             ║ | ||||
| 	//  ║ []    │ list fields                ║ | ||||
| 	//  ║ {}    │ map fields                 ║ | ||||
| 	//  ╚═══════╧════════════════════════════╝ | ||||
| 	EmitUnpopulated bool | ||||
|  | ||||
| 	// Resolver is used for looking up types when expanding google.protobuf.Any | ||||
| 	// messages. If nil, this defaults to using protoregistry.GlobalTypes. | ||||
| 	Resolver interface { | ||||
| 		protoregistry.ExtensionTypeResolver | ||||
| 		protoregistry.MessageTypeResolver | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Format formats the message as a string. | ||||
| // This method is only intended for human consumption and ignores errors. | ||||
| // Do not depend on the output being stable. It may change over time across | ||||
| // different versions of the program. | ||||
| func (o MarshalOptions) Format(m proto.Message) string { | ||||
| 	if m == nil || !m.ProtoReflect().IsValid() { | ||||
| 		return "<nil>" // invalid syntax, but okay since this is for debugging | ||||
| 	} | ||||
| 	o.AllowPartial = true | ||||
| 	b, _ := o.Marshal(m) | ||||
| 	return string(b) | ||||
| } | ||||
|  | ||||
| // Marshal marshals the given proto.Message in the JSON format using options in | ||||
| // MarshalOptions. Do not depend on the output being stable. It may change over | ||||
| // time across different versions of the program. | ||||
| func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) { | ||||
| 	return o.marshal(m) | ||||
| } | ||||
|  | ||||
| // marshal is a centralized function that all marshal operations go through. | ||||
| // For profiling purposes, avoid changing the name of this function or | ||||
| // introducing other code paths for marshal that do not go through this. | ||||
| func (o MarshalOptions) marshal(m proto.Message) ([]byte, error) { | ||||
| 	if o.Multiline && o.Indent == "" { | ||||
| 		o.Indent = defaultIndent | ||||
| 	} | ||||
| 	if o.Resolver == nil { | ||||
| 		o.Resolver = protoregistry.GlobalTypes | ||||
| 	} | ||||
|  | ||||
| 	internalEnc, err := json.NewEncoder(o.Indent) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// Treat nil message interface as an empty message, | ||||
| 	// in which case the output in an empty JSON object. | ||||
| 	if m == nil { | ||||
| 		return []byte("{}"), nil | ||||
| 	} | ||||
|  | ||||
| 	enc := encoder{internalEnc, o} | ||||
| 	if err := enc.marshalMessage(m.ProtoReflect(), ""); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if o.AllowPartial { | ||||
| 		return enc.Bytes(), nil | ||||
| 	} | ||||
| 	return enc.Bytes(), proto.CheckInitialized(m) | ||||
| } | ||||
|  | ||||
| type encoder struct { | ||||
| 	*json.Encoder | ||||
| 	opts MarshalOptions | ||||
| } | ||||
|  | ||||
| // typeFieldDesc is a synthetic field descriptor used for the "@type" field. | ||||
| var typeFieldDesc = func() protoreflect.FieldDescriptor { | ||||
| 	var fd filedesc.Field | ||||
| 	fd.L0.FullName = "@type" | ||||
| 	fd.L0.Index = -1 | ||||
| 	fd.L1.Cardinality = protoreflect.Optional | ||||
| 	fd.L1.Kind = protoreflect.StringKind | ||||
| 	return &fd | ||||
| }() | ||||
|  | ||||
| // typeURLFieldRanger wraps a protoreflect.Message and modifies its Range method | ||||
| // to additionally iterate over a synthetic field for the type URL. | ||||
| type typeURLFieldRanger struct { | ||||
| 	order.FieldRanger | ||||
| 	typeURL string | ||||
| } | ||||
|  | ||||
| func (m typeURLFieldRanger) Range(f func(pref.FieldDescriptor, pref.Value) bool) { | ||||
| 	if !f(typeFieldDesc, pref.ValueOfString(m.typeURL)) { | ||||
| 		return | ||||
| 	} | ||||
| 	m.FieldRanger.Range(f) | ||||
| } | ||||
|  | ||||
| // unpopulatedFieldRanger wraps a protoreflect.Message and modifies its Range | ||||
| // method to additionally iterate over unpopulated fields. | ||||
| type unpopulatedFieldRanger struct{ pref.Message } | ||||
|  | ||||
| func (m unpopulatedFieldRanger) Range(f func(pref.FieldDescriptor, pref.Value) bool) { | ||||
| 	fds := m.Descriptor().Fields() | ||||
| 	for i := 0; i < fds.Len(); i++ { | ||||
| 		fd := fds.Get(i) | ||||
| 		if m.Has(fd) || fd.ContainingOneof() != nil { | ||||
| 			continue // ignore populated fields and fields within a oneofs | ||||
| 		} | ||||
|  | ||||
| 		v := m.Get(fd) | ||||
| 		isProto2Scalar := fd.Syntax() == pref.Proto2 && fd.Default().IsValid() | ||||
| 		isSingularMessage := fd.Cardinality() != pref.Repeated && fd.Message() != nil | ||||
| 		if isProto2Scalar || isSingularMessage { | ||||
| 			v = pref.Value{} // use invalid value to emit null | ||||
| 		} | ||||
| 		if !f(fd, v) { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	m.Message.Range(f) | ||||
| } | ||||
|  | ||||
| // marshalMessage marshals the fields in the given protoreflect.Message. | ||||
| // If the typeURL is non-empty, then a synthetic "@type" field is injected | ||||
| // containing the URL as the value. | ||||
| func (e encoder) marshalMessage(m pref.Message, typeURL string) error { | ||||
| 	if !flags.ProtoLegacy && messageset.IsMessageSet(m.Descriptor()) { | ||||
| 		return errors.New("no support for proto1 MessageSets") | ||||
| 	} | ||||
|  | ||||
| 	if marshal := wellKnownTypeMarshaler(m.Descriptor().FullName()); marshal != nil { | ||||
| 		return marshal(e, m) | ||||
| 	} | ||||
|  | ||||
| 	e.StartObject() | ||||
| 	defer e.EndObject() | ||||
|  | ||||
| 	var fields order.FieldRanger = m | ||||
| 	if e.opts.EmitUnpopulated { | ||||
| 		fields = unpopulatedFieldRanger{m} | ||||
| 	} | ||||
| 	if typeURL != "" { | ||||
| 		fields = typeURLFieldRanger{fields, typeURL} | ||||
| 	} | ||||
|  | ||||
| 	var err error | ||||
| 	order.RangeFields(fields, order.IndexNameFieldOrder, func(fd pref.FieldDescriptor, v pref.Value) bool { | ||||
| 		name := fd.JSONName() | ||||
| 		if e.opts.UseProtoNames { | ||||
| 			name = fd.TextName() | ||||
| 		} | ||||
|  | ||||
| 		if err = e.WriteName(name); err != nil { | ||||
| 			return false | ||||
| 		} | ||||
| 		if err = e.marshalValue(v, fd); err != nil { | ||||
| 			return false | ||||
| 		} | ||||
| 		return true | ||||
| 	}) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // marshalValue marshals the given protoreflect.Value. | ||||
| func (e encoder) marshalValue(val pref.Value, fd pref.FieldDescriptor) error { | ||||
| 	switch { | ||||
| 	case fd.IsList(): | ||||
| 		return e.marshalList(val.List(), fd) | ||||
| 	case fd.IsMap(): | ||||
| 		return e.marshalMap(val.Map(), fd) | ||||
| 	default: | ||||
| 		return e.marshalSingular(val, fd) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // marshalSingular marshals the given non-repeated field value. This includes | ||||
| // all scalar types, enums, messages, and groups. | ||||
| func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error { | ||||
| 	if !val.IsValid() { | ||||
| 		e.WriteNull() | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	switch kind := fd.Kind(); kind { | ||||
| 	case pref.BoolKind: | ||||
| 		e.WriteBool(val.Bool()) | ||||
|  | ||||
| 	case pref.StringKind: | ||||
| 		if e.WriteString(val.String()) != nil { | ||||
| 			return errors.InvalidUTF8(string(fd.FullName())) | ||||
| 		} | ||||
|  | ||||
| 	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: | ||||
| 		e.WriteInt(val.Int()) | ||||
|  | ||||
| 	case pref.Uint32Kind, pref.Fixed32Kind: | ||||
| 		e.WriteUint(val.Uint()) | ||||
|  | ||||
| 	case pref.Int64Kind, pref.Sint64Kind, pref.Uint64Kind, | ||||
| 		pref.Sfixed64Kind, pref.Fixed64Kind: | ||||
| 		// 64-bit integers are written out as JSON string. | ||||
| 		e.WriteString(val.String()) | ||||
|  | ||||
| 	case pref.FloatKind: | ||||
| 		// Encoder.WriteFloat handles the special numbers NaN and infinites. | ||||
| 		e.WriteFloat(val.Float(), 32) | ||||
|  | ||||
| 	case pref.DoubleKind: | ||||
| 		// Encoder.WriteFloat handles the special numbers NaN and infinites. | ||||
| 		e.WriteFloat(val.Float(), 64) | ||||
|  | ||||
| 	case pref.BytesKind: | ||||
| 		e.WriteString(base64.StdEncoding.EncodeToString(val.Bytes())) | ||||
|  | ||||
| 	case pref.EnumKind: | ||||
| 		if fd.Enum().FullName() == genid.NullValue_enum_fullname { | ||||
| 			e.WriteNull() | ||||
| 		} else { | ||||
| 			desc := fd.Enum().Values().ByNumber(val.Enum()) | ||||
| 			if e.opts.UseEnumNumbers || desc == nil { | ||||
| 				e.WriteInt(int64(val.Enum())) | ||||
| 			} else { | ||||
| 				e.WriteString(string(desc.Name())) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 	case pref.MessageKind, pref.GroupKind: | ||||
| 		if err := e.marshalMessage(val.Message(), ""); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("%v has unknown kind: %v", fd.FullName(), kind)) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // marshalList marshals the given protoreflect.List. | ||||
| func (e encoder) marshalList(list pref.List, fd pref.FieldDescriptor) error { | ||||
| 	e.StartArray() | ||||
| 	defer e.EndArray() | ||||
|  | ||||
| 	for i := 0; i < list.Len(); i++ { | ||||
| 		item := list.Get(i) | ||||
| 		if err := e.marshalSingular(item, fd); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // marshalMap marshals given protoreflect.Map. | ||||
| func (e encoder) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) error { | ||||
| 	e.StartObject() | ||||
| 	defer e.EndObject() | ||||
|  | ||||
| 	var err error | ||||
| 	order.RangeEntries(mmap, order.GenericKeyOrder, func(k pref.MapKey, v pref.Value) bool { | ||||
| 		if err = e.WriteName(k.String()); err != nil { | ||||
| 			return false | ||||
| 		} | ||||
| 		if err = e.marshalSingular(v, fd.MapValue()); err != nil { | ||||
| 			return false | ||||
| 		} | ||||
| 		return true | ||||
| 	}) | ||||
| 	return err | ||||
| } | ||||
							
								
								
									
										889
									
								
								vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										889
									
								
								vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,889 @@ | ||||
| // 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" | ||||
| 	"math" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"google.golang.org/protobuf/internal/encoding/json" | ||||
| 	"google.golang.org/protobuf/internal/errors" | ||||
| 	"google.golang.org/protobuf/internal/genid" | ||||
| 	"google.golang.org/protobuf/internal/strs" | ||||
| 	"google.golang.org/protobuf/proto" | ||||
| 	pref "google.golang.org/protobuf/reflect/protoreflect" | ||||
| ) | ||||
|  | ||||
| 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 nil | ||||
| } | ||||
|  | ||||
| type unmarshalFunc func(decoder, pref.Message) error | ||||
|  | ||||
| // 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 | ||||
| // 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 (e encoder) marshalAny(m pref.Message) error { | ||||
| 	fds := m.Descriptor().Fields() | ||||
| 	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: %v is not set", genid.Any_message_fullname, genid.Any_TypeUrl_field_name) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	typeVal := m.Get(fdType) | ||||
| 	valueVal := m.Get(fdValue) | ||||
|  | ||||
| 	// 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", genid.Any_message_fullname, typeURL, err) | ||||
| 	} | ||||
|  | ||||
| 	em := emt.New() | ||||
| 	err = proto.UnmarshalOptions{ | ||||
| 		AllowPartial: true, // never check required fields inside an Any | ||||
| 		Resolver:     e.opts.Resolver, | ||||
| 	}.Unmarshal(valueVal.Bytes(), em.Interface()) | ||||
| 	if err != nil { | ||||
| 		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 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 marshal(e, em) | ||||
| 	} | ||||
|  | ||||
| 	// Else, marshal out the embedded message's fields in this Any object. | ||||
| 	if err := e.marshalMessage(em, typeURL); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (d decoder) unmarshalAny(m pref.Message) error { | ||||
| 	// Peek to check for json.ObjectOpen to avoid advancing a read. | ||||
| 	start, err := d.Peek() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if start.Kind() != json.ObjectOpen { | ||||
| 		return d.unexpectedTokenError(start) | ||||
| 	} | ||||
|  | ||||
| 	// Use another decoder to parse the unread bytes for @type field. This | ||||
| 	// avoids advancing a read from current decoder because the current JSON | ||||
| 	// object may contain the fields of the embedded type. | ||||
| 	dec := decoder{d.Clone(), UnmarshalOptions{}} | ||||
| 	tok, err := findTypeURL(dec) | ||||
| 	switch err { | ||||
| 	case errEmptyObject: | ||||
| 		// An empty JSON object translates to an empty Any message. | ||||
| 		d.Read() // Read json.ObjectOpen. | ||||
| 		d.Read() // Read json.ObjectClose. | ||||
| 		return nil | ||||
|  | ||||
| 	case errMissingType: | ||||
| 		if d.opts.DiscardUnknown { | ||||
| 			// Treat all fields as unknowns, similar to an empty object. | ||||
| 			return d.skipJSONValue() | ||||
| 		} | ||||
| 		// Use start.Pos() for line position. | ||||
| 		return d.newError(start.Pos(), err.Error()) | ||||
|  | ||||
| 	default: | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	typeURL := tok.ParsedString() | ||||
| 	emt, err := d.opts.Resolver.FindMessageByURL(typeURL) | ||||
| 	if err != nil { | ||||
| 		return d.newError(tok.Pos(), "unable to resolve %v: %q", tok.RawString(), err) | ||||
| 	} | ||||
|  | ||||
| 	// Create new message for the embedded message type and unmarshal into it. | ||||
| 	em := emt.New() | ||||
| 	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(unmarshal, em); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else { | ||||
| 		// Else unmarshal the current JSON object into it. | ||||
| 		if err := d.unmarshalMessage(em, true); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	// Serialize the embedded message and assign the resulting bytes to the | ||||
| 	// proto value field. | ||||
| 	b, err := proto.MarshalOptions{ | ||||
| 		AllowPartial:  true, // No need to check required fields inside an Any. | ||||
| 		Deterministic: true, | ||||
| 	}.Marshal(em.Interface()) | ||||
| 	if err != nil { | ||||
| 		return d.newError(start.Pos(), "error in marshaling Any.value field: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	fds := m.Descriptor().Fields() | ||||
| 	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)) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| var errEmptyObject = fmt.Errorf(`empty object`) | ||||
| var errMissingType = fmt.Errorf(`missing "@type" field`) | ||||
|  | ||||
| // findTypeURL returns the token for the "@type" field value from the given | ||||
| // JSON bytes. It is expected that the given bytes start with json.ObjectOpen. | ||||
| // It returns errEmptyObject if the JSON object is empty or errMissingType if | ||||
| // @type field does not exist. It returns other error if the @type field is not | ||||
| // valid or other decoding issues. | ||||
| func findTypeURL(d decoder) (json.Token, error) { | ||||
| 	var typeURL string | ||||
| 	var typeTok json.Token | ||||
| 	numFields := 0 | ||||
| 	// Skip start object. | ||||
| 	d.Read() | ||||
|  | ||||
| Loop: | ||||
| 	for { | ||||
| 		tok, err := d.Read() | ||||
| 		if err != nil { | ||||
| 			return json.Token{}, err | ||||
| 		} | ||||
|  | ||||
| 		switch tok.Kind() { | ||||
| 		case json.ObjectClose: | ||||
| 			if typeURL == "" { | ||||
| 				// Did not find @type field. | ||||
| 				if numFields > 0 { | ||||
| 					return json.Token{}, errMissingType | ||||
| 				} | ||||
| 				return json.Token{}, errEmptyObject | ||||
| 			} | ||||
| 			break Loop | ||||
|  | ||||
| 		case json.Name: | ||||
| 			numFields++ | ||||
| 			if tok.Name() != "@type" { | ||||
| 				// Skip value. | ||||
| 				if err := d.skipJSONValue(); err != nil { | ||||
| 					return json.Token{}, err | ||||
| 				} | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			// Return error if this was previously set already. | ||||
| 			if typeURL != "" { | ||||
| 				return json.Token{}, d.newError(tok.Pos(), `duplicate "@type" field`) | ||||
| 			} | ||||
| 			// Read field value. | ||||
| 			tok, err := d.Read() | ||||
| 			if err != nil { | ||||
| 				return json.Token{}, err | ||||
| 			} | ||||
| 			if tok.Kind() != json.String { | ||||
| 				return json.Token{}, d.newError(tok.Pos(), `@type field value is not a string: %v`, tok.RawString()) | ||||
| 			} | ||||
| 			typeURL = tok.ParsedString() | ||||
| 			if typeURL == "" { | ||||
| 				return json.Token{}, d.newError(tok.Pos(), `@type field contains empty value`) | ||||
| 			} | ||||
| 			typeTok = tok | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return typeTok, nil | ||||
| } | ||||
|  | ||||
| // skipJSONValue parses a JSON value (null, boolean, string, number, object and | ||||
| // array) in order to advance the read to the next JSON value. It relies on | ||||
| // the decoder returning an error if the types are not in valid sequence. | ||||
| func (d decoder) skipJSONValue() error { | ||||
| 	tok, err := d.Read() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	// Only need to continue reading for objects and arrays. | ||||
| 	switch tok.Kind() { | ||||
| 	case json.ObjectOpen: | ||||
| 		for { | ||||
| 			tok, err := d.Read() | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			switch tok.Kind() { | ||||
| 			case json.ObjectClose: | ||||
| 				return nil | ||||
| 			case json.Name: | ||||
| 				// Skip object field value. | ||||
| 				if err := d.skipJSONValue(); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 	case json.ArrayOpen: | ||||
| 		for { | ||||
| 			tok, err := d.Peek() | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			switch tok.Kind() { | ||||
| 			case json.ArrayClose: | ||||
| 				d.Read() | ||||
| 				return nil | ||||
| 			default: | ||||
| 				// Skip array item. | ||||
| 				if err := d.skipJSONValue(); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // unmarshalAnyValue unmarshals the given custom-type message from the JSON | ||||
| // object's "value" field. | ||||
| func (d decoder) unmarshalAnyValue(unmarshal unmarshalFunc, m pref.Message) error { | ||||
| 	// Skip ObjectOpen, and start reading the fields. | ||||
| 	d.Read() | ||||
|  | ||||
| 	var found bool // Used for detecting duplicate "value". | ||||
| 	for { | ||||
| 		tok, err := d.Read() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		switch tok.Kind() { | ||||
| 		case json.ObjectClose: | ||||
| 			if !found { | ||||
| 				return d.newError(tok.Pos(), `missing "value" field`) | ||||
| 			} | ||||
| 			return nil | ||||
|  | ||||
| 		case json.Name: | ||||
| 			switch tok.Name() { | ||||
| 			case "@type": | ||||
| 				// Skip the value as this was previously parsed already. | ||||
| 				d.Read() | ||||
|  | ||||
| 			case "value": | ||||
| 				if found { | ||||
| 					return d.newError(tok.Pos(), `duplicate "value" field`) | ||||
| 				} | ||||
| 				// Unmarshal the field value into the given message. | ||||
| 				if err := unmarshal(d, m); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				found = true | ||||
|  | ||||
| 			default: | ||||
| 				if d.opts.DiscardUnknown { | ||||
| 					if err := d.skipJSONValue(); err != nil { | ||||
| 						return err | ||||
| 					} | ||||
| 					continue | ||||
| 				} | ||||
| 				return d.newError(tok.Pos(), "unknown field %v", tok.RawString()) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Wrapper types are encoded as JSON primitives like string, number or boolean. | ||||
|  | ||||
| func (e encoder) marshalWrapperType(m pref.Message) error { | ||||
| 	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(genid.WrapperValue_Value_field_number) | ||||
| 	val, err := d.unmarshalScalar(fd) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	m.Set(fd, val) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // The JSON representation for Empty is an empty JSON object. | ||||
|  | ||||
| func (e encoder) marshalEmpty(pref.Message) error { | ||||
| 	e.StartObject() | ||||
| 	e.EndObject() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (d decoder) unmarshalEmpty(pref.Message) error { | ||||
| 	tok, err := d.Read() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if tok.Kind() != json.ObjectOpen { | ||||
| 		return d.unexpectedTokenError(tok) | ||||
| 	} | ||||
|  | ||||
| 	for { | ||||
| 		tok, err := d.Read() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		switch tok.Kind() { | ||||
| 		case json.ObjectClose: | ||||
| 			return nil | ||||
|  | ||||
| 		case json.Name: | ||||
| 			if d.opts.DiscardUnknown { | ||||
| 				if err := d.skipJSONValue(); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				continue | ||||
| 			} | ||||
| 			return d.newError(tok.Pos(), "unknown field %v", tok.RawString()) | ||||
|  | ||||
| 		default: | ||||
| 			return d.unexpectedTokenError(tok) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // 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(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(genid.Struct_Fields_field_number) | ||||
| 	return d.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 (e encoder) marshalListValue(m pref.Message) error { | ||||
| 	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(genid.ListValue_Values_field_number) | ||||
| 	return d.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 (e encoder) marshalKnownValue(m pref.Message) error { | ||||
| 	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", 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) | ||||
| } | ||||
|  | ||||
| func (d decoder) unmarshalKnownValue(m pref.Message) error { | ||||
| 	tok, err := d.Peek() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	var fd pref.FieldDescriptor | ||||
| 	var val pref.Value | ||||
| 	switch tok.Kind() { | ||||
| 	case json.Null: | ||||
| 		d.Read() | ||||
| 		fd = m.Descriptor().Fields().ByNumber(genid.Value_NullValue_field_number) | ||||
| 		val = pref.ValueOfEnum(0) | ||||
|  | ||||
| 	case json.Bool: | ||||
| 		tok, err := d.Read() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		fd = m.Descriptor().Fields().ByNumber(genid.Value_BoolValue_field_number) | ||||
| 		val = pref.ValueOfBool(tok.Bool()) | ||||
|  | ||||
| 	case json.Number: | ||||
| 		tok, err := d.Read() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		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 %v: %v", genid.Value_message_fullname, tok.RawString()) | ||||
| 		} | ||||
|  | ||||
| 	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. | ||||
| 		tok, err := d.Read() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		fd = m.Descriptor().Fields().ByNumber(genid.Value_StringValue_field_number) | ||||
| 		val = pref.ValueOfString(tok.ParsedString()) | ||||
|  | ||||
| 	case json.ObjectOpen: | ||||
| 		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(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 %v: %v", genid.Value_message_fullname, tok.RawString()) | ||||
| 	} | ||||
|  | ||||
| 	m.Set(fd, val) | ||||
| 	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 (e encoder) marshalDuration(m pref.Message) error { | ||||
| 	fds := m.Descriptor().Fields() | ||||
| 	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", genid.Duration_message_fullname, secs) | ||||
| 	} | ||||
| 	if nanos < -secondsInNanos || nanos > secondsInNanos { | ||||
| 		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", genid.Duration_message_fullname) | ||||
| 	} | ||||
| 	// Generated output always contains 0, 3, 6, or 9 fractional digits, | ||||
| 	// depending on required precision, followed by the suffix "s". | ||||
| 	var sign string | ||||
| 	if secs < 0 || nanos < 0 { | ||||
| 		sign, secs, nanos = "-", -1*secs, -1*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") | ||||
| 	e.WriteString(x + "s") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (d decoder) unmarshalDuration(m pref.Message) error { | ||||
| 	tok, err := d.Read() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if tok.Kind() != json.String { | ||||
| 		return d.unexpectedTokenError(tok) | ||||
| 	} | ||||
|  | ||||
| 	secs, nanos, ok := parseDuration(tok.ParsedString()) | ||||
| 	if !ok { | ||||
| 		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(), "%v value out of range: %v", genid.Duration_message_fullname, tok.RawString()) | ||||
| 	} | ||||
|  | ||||
| 	fds := m.Descriptor().Fields() | ||||
| 	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)) | ||||
| 	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 (e encoder) marshalTimestamp(m pref.Message) error { | ||||
| 	fds := m.Descriptor().Fields() | ||||
| 	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", genid.Timestamp_message_fullname, secs) | ||||
| 	} | ||||
| 	if nanos < 0 || nanos > secondsInNanos { | ||||
| 		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. | ||||
| 	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") | ||||
| 	e.WriteString(x + "Z") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (d decoder) unmarshalTimestamp(m pref.Message) error { | ||||
| 	tok, err := d.Read() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if tok.Kind() != json.String { | ||||
| 		return d.unexpectedTokenError(tok) | ||||
| 	} | ||||
|  | ||||
| 	t, err := time.Parse(time.RFC3339Nano, tok.ParsedString()) | ||||
| 	if err != nil { | ||||
| 		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(), "%v value out of range: %v", genid.Timestamp_message_fullname, tok.RawString()) | ||||
| 	} | ||||
|  | ||||
| 	fds := m.Descriptor().Fields() | ||||
| 	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()))) | ||||
| 	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 (e encoder) marshalFieldMask(m pref.Message) error { | ||||
| 	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 contains irreversible value %q", genid.FieldMask_Paths_field_fullname, s) | ||||
| 		} | ||||
| 		paths = append(paths, cc) | ||||
| 	} | ||||
|  | ||||
| 	e.WriteString(strings.Join(paths, ",")) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (d decoder) unmarshalFieldMask(m pref.Message) error { | ||||
| 	tok, err := d.Read() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if tok.Kind() != json.String { | ||||
| 		return d.unexpectedTokenError(tok) | ||||
| 	} | ||||
| 	str := strings.TrimSpace(tok.ParsedString()) | ||||
| 	if str == "" { | ||||
| 		return nil | ||||
| 	} | ||||
| 	paths := strings.Split(str, ",") | ||||
|  | ||||
| 	fd := m.Descriptor().Fields().ByNumber(genid.FieldMask_Paths_field_number) | ||||
| 	list := m.Mutable(fd).List() | ||||
|  | ||||
| 	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 | ||||
| } | ||||
		Reference in New Issue
	
	Block a user