update kubernetes dependencies to v1.25.0
Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
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
|
||||
}
|
19
vendor/google.golang.org/protobuf/encoding/protowire/wire.go
generated
vendored
19
vendor/google.golang.org/protobuf/encoding/protowire/wire.go
generated
vendored
@@ -21,10 +21,11 @@ import (
|
||||
type Number int32
|
||||
|
||||
const (
|
||||
MinValidNumber Number = 1
|
||||
FirstReservedNumber Number = 19000
|
||||
LastReservedNumber Number = 19999
|
||||
MaxValidNumber Number = 1<<29 - 1
|
||||
MinValidNumber Number = 1
|
||||
FirstReservedNumber Number = 19000
|
||||
LastReservedNumber Number = 19999
|
||||
MaxValidNumber Number = 1<<29 - 1
|
||||
DefaultRecursionLimit = 10000
|
||||
)
|
||||
|
||||
// IsValid reports whether the field number is semantically valid.
|
||||
@@ -55,6 +56,7 @@ const (
|
||||
errCodeOverflow
|
||||
errCodeReserved
|
||||
errCodeEndGroup
|
||||
errCodeRecursionDepth
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -112,6 +114,10 @@ func ConsumeField(b []byte) (Number, Type, int) {
|
||||
// When parsing a group, the length includes the end group marker and
|
||||
// the end group is verified to match the starting field number.
|
||||
func ConsumeFieldValue(num Number, typ Type, b []byte) (n int) {
|
||||
return consumeFieldValueD(num, typ, b, DefaultRecursionLimit)
|
||||
}
|
||||
|
||||
func consumeFieldValueD(num Number, typ Type, b []byte, depth int) (n int) {
|
||||
switch typ {
|
||||
case VarintType:
|
||||
_, n = ConsumeVarint(b)
|
||||
@@ -126,6 +132,9 @@ func ConsumeFieldValue(num Number, typ Type, b []byte) (n int) {
|
||||
_, n = ConsumeBytes(b)
|
||||
return n
|
||||
case StartGroupType:
|
||||
if depth < 0 {
|
||||
return errCodeRecursionDepth
|
||||
}
|
||||
n0 := len(b)
|
||||
for {
|
||||
num2, typ2, n := ConsumeTag(b)
|
||||
@@ -140,7 +149,7 @@ func ConsumeFieldValue(num Number, typ Type, b []byte) (n int) {
|
||||
return n0 - len(b)
|
||||
}
|
||||
|
||||
n = ConsumeFieldValue(num2, typ2, b)
|
||||
n = consumeFieldValueD(num2, typ2, b, depth-1)
|
||||
if n < 0 {
|
||||
return n // forward error code
|
||||
}
|
||||
|
340
vendor/google.golang.org/protobuf/internal/encoding/json/decode.go
generated
vendored
Normal file
340
vendor/google.golang.org/protobuf/internal/encoding/json/decode.go
generated
vendored
Normal file
@@ -0,0 +1,340 @@
|
||||
// Copyright 2018 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 json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"unicode/utf8"
|
||||
|
||||
"google.golang.org/protobuf/internal/errors"
|
||||
)
|
||||
|
||||
// call specifies which Decoder method was invoked.
|
||||
type call uint8
|
||||
|
||||
const (
|
||||
readCall call = iota
|
||||
peekCall
|
||||
)
|
||||
|
||||
const unexpectedFmt = "unexpected token %s"
|
||||
|
||||
// ErrUnexpectedEOF means that EOF was encountered in the middle of the input.
|
||||
var ErrUnexpectedEOF = errors.New("%v", io.ErrUnexpectedEOF)
|
||||
|
||||
// Decoder is a token-based JSON decoder.
|
||||
type Decoder struct {
|
||||
// lastCall is last method called, either readCall or peekCall.
|
||||
// Initial value is readCall.
|
||||
lastCall call
|
||||
|
||||
// lastToken contains the last read token.
|
||||
lastToken Token
|
||||
|
||||
// lastErr contains the last read error.
|
||||
lastErr error
|
||||
|
||||
// openStack is a stack containing ObjectOpen and ArrayOpen values. The
|
||||
// top of stack represents the object or the array the current value is
|
||||
// directly located in.
|
||||
openStack []Kind
|
||||
|
||||
// orig is used in reporting line and column.
|
||||
orig []byte
|
||||
// in contains the unconsumed input.
|
||||
in []byte
|
||||
}
|
||||
|
||||
// NewDecoder returns a Decoder to read the given []byte.
|
||||
func NewDecoder(b []byte) *Decoder {
|
||||
return &Decoder{orig: b, in: b}
|
||||
}
|
||||
|
||||
// Peek looks ahead and returns the next token kind without advancing a read.
|
||||
func (d *Decoder) Peek() (Token, error) {
|
||||
defer func() { d.lastCall = peekCall }()
|
||||
if d.lastCall == readCall {
|
||||
d.lastToken, d.lastErr = d.Read()
|
||||
}
|
||||
return d.lastToken, d.lastErr
|
||||
}
|
||||
|
||||
// Read returns the next JSON token.
|
||||
// It will return an error if there is no valid token.
|
||||
func (d *Decoder) Read() (Token, error) {
|
||||
const scalar = Null | Bool | Number | String
|
||||
|
||||
defer func() { d.lastCall = readCall }()
|
||||
if d.lastCall == peekCall {
|
||||
return d.lastToken, d.lastErr
|
||||
}
|
||||
|
||||
tok, err := d.parseNext()
|
||||
if err != nil {
|
||||
return Token{}, err
|
||||
}
|
||||
|
||||
switch tok.kind {
|
||||
case EOF:
|
||||
if len(d.openStack) != 0 ||
|
||||
d.lastToken.kind&scalar|ObjectClose|ArrayClose == 0 {
|
||||
return Token{}, ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
case Null:
|
||||
if !d.isValueNext() {
|
||||
return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
|
||||
}
|
||||
|
||||
case Bool, Number:
|
||||
if !d.isValueNext() {
|
||||
return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
|
||||
}
|
||||
|
||||
case String:
|
||||
if d.isValueNext() {
|
||||
break
|
||||
}
|
||||
// This string token should only be for a field name.
|
||||
if d.lastToken.kind&(ObjectOpen|comma) == 0 {
|
||||
return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
|
||||
}
|
||||
if len(d.in) == 0 {
|
||||
return Token{}, ErrUnexpectedEOF
|
||||
}
|
||||
if c := d.in[0]; c != ':' {
|
||||
return Token{}, d.newSyntaxError(d.currPos(), `unexpected character %s, missing ":" after field name`, string(c))
|
||||
}
|
||||
tok.kind = Name
|
||||
d.consume(1)
|
||||
|
||||
case ObjectOpen, ArrayOpen:
|
||||
if !d.isValueNext() {
|
||||
return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
|
||||
}
|
||||
d.openStack = append(d.openStack, tok.kind)
|
||||
|
||||
case ObjectClose:
|
||||
if len(d.openStack) == 0 ||
|
||||
d.lastToken.kind == comma ||
|
||||
d.openStack[len(d.openStack)-1] != ObjectOpen {
|
||||
return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
|
||||
}
|
||||
d.openStack = d.openStack[:len(d.openStack)-1]
|
||||
|
||||
case ArrayClose:
|
||||
if len(d.openStack) == 0 ||
|
||||
d.lastToken.kind == comma ||
|
||||
d.openStack[len(d.openStack)-1] != ArrayOpen {
|
||||
return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
|
||||
}
|
||||
d.openStack = d.openStack[:len(d.openStack)-1]
|
||||
|
||||
case comma:
|
||||
if len(d.openStack) == 0 ||
|
||||
d.lastToken.kind&(scalar|ObjectClose|ArrayClose) == 0 {
|
||||
return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
|
||||
}
|
||||
}
|
||||
|
||||
// Update d.lastToken only after validating token to be in the right sequence.
|
||||
d.lastToken = tok
|
||||
|
||||
if d.lastToken.kind == comma {
|
||||
return d.Read()
|
||||
}
|
||||
return tok, nil
|
||||
}
|
||||
|
||||
// Any sequence that looks like a non-delimiter (for error reporting).
|
||||
var errRegexp = regexp.MustCompile(`^([-+._a-zA-Z0-9]{1,32}|.)`)
|
||||
|
||||
// parseNext parses for the next JSON token. It returns a Token object for
|
||||
// different types, except for Name. It does not handle whether the next token
|
||||
// is in a valid sequence or not.
|
||||
func (d *Decoder) parseNext() (Token, error) {
|
||||
// Trim leading spaces.
|
||||
d.consume(0)
|
||||
|
||||
in := d.in
|
||||
if len(in) == 0 {
|
||||
return d.consumeToken(EOF, 0), nil
|
||||
}
|
||||
|
||||
switch in[0] {
|
||||
case 'n':
|
||||
if n := matchWithDelim("null", in); n != 0 {
|
||||
return d.consumeToken(Null, n), nil
|
||||
}
|
||||
|
||||
case 't':
|
||||
if n := matchWithDelim("true", in); n != 0 {
|
||||
return d.consumeBoolToken(true, n), nil
|
||||
}
|
||||
|
||||
case 'f':
|
||||
if n := matchWithDelim("false", in); n != 0 {
|
||||
return d.consumeBoolToken(false, n), nil
|
||||
}
|
||||
|
||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
if n, ok := parseNumber(in); ok {
|
||||
return d.consumeToken(Number, n), nil
|
||||
}
|
||||
|
||||
case '"':
|
||||
s, n, err := d.parseString(in)
|
||||
if err != nil {
|
||||
return Token{}, err
|
||||
}
|
||||
return d.consumeStringToken(s, n), nil
|
||||
|
||||
case '{':
|
||||
return d.consumeToken(ObjectOpen, 1), nil
|
||||
|
||||
case '}':
|
||||
return d.consumeToken(ObjectClose, 1), nil
|
||||
|
||||
case '[':
|
||||
return d.consumeToken(ArrayOpen, 1), nil
|
||||
|
||||
case ']':
|
||||
return d.consumeToken(ArrayClose, 1), nil
|
||||
|
||||
case ',':
|
||||
return d.consumeToken(comma, 1), nil
|
||||
}
|
||||
return Token{}, d.newSyntaxError(d.currPos(), "invalid value %s", errRegexp.Find(in))
|
||||
}
|
||||
|
||||
// newSyntaxError returns an error with line and column information useful for
|
||||
// syntax errors.
|
||||
func (d *Decoder) newSyntaxError(pos int, f string, x ...interface{}) error {
|
||||
e := errors.New(f, x...)
|
||||
line, column := d.Position(pos)
|
||||
return errors.New("syntax error (line %d:%d): %v", line, column, e)
|
||||
}
|
||||
|
||||
// Position returns line and column number of given index of the original input.
|
||||
// It will panic if index is out of range.
|
||||
func (d *Decoder) Position(idx int) (line int, column int) {
|
||||
b := d.orig[:idx]
|
||||
line = bytes.Count(b, []byte("\n")) + 1
|
||||
if i := bytes.LastIndexByte(b, '\n'); i >= 0 {
|
||||
b = b[i+1:]
|
||||
}
|
||||
column = utf8.RuneCount(b) + 1 // ignore multi-rune characters
|
||||
return line, column
|
||||
}
|
||||
|
||||
// currPos returns the current index position of d.in from d.orig.
|
||||
func (d *Decoder) currPos() int {
|
||||
return len(d.orig) - len(d.in)
|
||||
}
|
||||
|
||||
// matchWithDelim matches s with the input b and verifies that the match
|
||||
// terminates with a delimiter of some form (e.g., r"[^-+_.a-zA-Z0-9]").
|
||||
// As a special case, EOF is considered a delimiter. It returns the length of s
|
||||
// if there is a match, else 0.
|
||||
func matchWithDelim(s string, b []byte) int {
|
||||
if !bytes.HasPrefix(b, []byte(s)) {
|
||||
return 0
|
||||
}
|
||||
|
||||
n := len(s)
|
||||
if n < len(b) && isNotDelim(b[n]) {
|
||||
return 0
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// isNotDelim returns true if given byte is a not delimiter character.
|
||||
func isNotDelim(c byte) bool {
|
||||
return (c == '-' || c == '+' || c == '.' || c == '_' ||
|
||||
('a' <= c && c <= 'z') ||
|
||||
('A' <= c && c <= 'Z') ||
|
||||
('0' <= c && c <= '9'))
|
||||
}
|
||||
|
||||
// consume consumes n bytes of input and any subsequent whitespace.
|
||||
func (d *Decoder) consume(n int) {
|
||||
d.in = d.in[n:]
|
||||
for len(d.in) > 0 {
|
||||
switch d.in[0] {
|
||||
case ' ', '\n', '\r', '\t':
|
||||
d.in = d.in[1:]
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// isValueNext returns true if next type should be a JSON value: Null,
|
||||
// Number, String or Bool.
|
||||
func (d *Decoder) isValueNext() bool {
|
||||
if len(d.openStack) == 0 {
|
||||
return d.lastToken.kind == 0
|
||||
}
|
||||
|
||||
start := d.openStack[len(d.openStack)-1]
|
||||
switch start {
|
||||
case ObjectOpen:
|
||||
return d.lastToken.kind&Name != 0
|
||||
case ArrayOpen:
|
||||
return d.lastToken.kind&(ArrayOpen|comma) != 0
|
||||
}
|
||||
panic(fmt.Sprintf(
|
||||
"unreachable logic in Decoder.isValueNext, lastToken.kind: %v, openStack: %v",
|
||||
d.lastToken.kind, start))
|
||||
}
|
||||
|
||||
// consumeToken constructs a Token for given Kind with raw value derived from
|
||||
// current d.in and given size, and consumes the given size-lenght of it.
|
||||
func (d *Decoder) consumeToken(kind Kind, size int) Token {
|
||||
tok := Token{
|
||||
kind: kind,
|
||||
raw: d.in[:size],
|
||||
pos: len(d.orig) - len(d.in),
|
||||
}
|
||||
d.consume(size)
|
||||
return tok
|
||||
}
|
||||
|
||||
// consumeBoolToken constructs a Token for a Bool kind with raw value derived from
|
||||
// current d.in and given size.
|
||||
func (d *Decoder) consumeBoolToken(b bool, size int) Token {
|
||||
tok := Token{
|
||||
kind: Bool,
|
||||
raw: d.in[:size],
|
||||
pos: len(d.orig) - len(d.in),
|
||||
boo: b,
|
||||
}
|
||||
d.consume(size)
|
||||
return tok
|
||||
}
|
||||
|
||||
// consumeStringToken constructs a Token for a String kind with raw value derived
|
||||
// from current d.in and given size.
|
||||
func (d *Decoder) consumeStringToken(s string, size int) Token {
|
||||
tok := Token{
|
||||
kind: String,
|
||||
raw: d.in[:size],
|
||||
pos: len(d.orig) - len(d.in),
|
||||
str: s,
|
||||
}
|
||||
d.consume(size)
|
||||
return tok
|
||||
}
|
||||
|
||||
// Clone returns a copy of the Decoder for use in reading ahead the next JSON
|
||||
// object, array or other values without affecting current Decoder.
|
||||
func (d *Decoder) Clone() *Decoder {
|
||||
ret := *d
|
||||
ret.openStack = append([]Kind(nil), ret.openStack...)
|
||||
return &ret
|
||||
}
|
254
vendor/google.golang.org/protobuf/internal/encoding/json/decode_number.go
generated
vendored
Normal file
254
vendor/google.golang.org/protobuf/internal/encoding/json/decode_number.go
generated
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
// Copyright 2018 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 json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// parseNumber reads the given []byte for a valid JSON number. If it is valid,
|
||||
// it returns the number of bytes. Parsing logic follows the definition in
|
||||
// https://tools.ietf.org/html/rfc7159#section-6, and is based off
|
||||
// encoding/json.isValidNumber function.
|
||||
func parseNumber(input []byte) (int, bool) {
|
||||
var n int
|
||||
|
||||
s := input
|
||||
if len(s) == 0 {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Optional -
|
||||
if s[0] == '-' {
|
||||
s = s[1:]
|
||||
n++
|
||||
if len(s) == 0 {
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
// Digits
|
||||
switch {
|
||||
case s[0] == '0':
|
||||
s = s[1:]
|
||||
n++
|
||||
|
||||
case '1' <= s[0] && s[0] <= '9':
|
||||
s = s[1:]
|
||||
n++
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
|
||||
s = s[1:]
|
||||
n++
|
||||
}
|
||||
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// . followed by 1 or more digits.
|
||||
if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
|
||||
s = s[2:]
|
||||
n += 2
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
|
||||
s = s[1:]
|
||||
n++
|
||||
}
|
||||
}
|
||||
|
||||
// e or E followed by an optional - or + and
|
||||
// 1 or more digits.
|
||||
if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
|
||||
s = s[1:]
|
||||
n++
|
||||
if s[0] == '+' || s[0] == '-' {
|
||||
s = s[1:]
|
||||
n++
|
||||
if len(s) == 0 {
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
|
||||
s = s[1:]
|
||||
n++
|
||||
}
|
||||
}
|
||||
|
||||
// Check that next byte is a delimiter or it is at the end.
|
||||
if n < len(input) && isNotDelim(input[n]) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return n, true
|
||||
}
|
||||
|
||||
// numberParts is the result of parsing out a valid JSON number. It contains
|
||||
// the parts of a number. The parts are used for integer conversion.
|
||||
type numberParts struct {
|
||||
neg bool
|
||||
intp []byte
|
||||
frac []byte
|
||||
exp []byte
|
||||
}
|
||||
|
||||
// parseNumber constructs numberParts from given []byte. The logic here is
|
||||
// similar to consumeNumber above with the difference of having to construct
|
||||
// numberParts. The slice fields in numberParts are subslices of the input.
|
||||
func parseNumberParts(input []byte) (numberParts, bool) {
|
||||
var neg bool
|
||||
var intp []byte
|
||||
var frac []byte
|
||||
var exp []byte
|
||||
|
||||
s := input
|
||||
if len(s) == 0 {
|
||||
return numberParts{}, false
|
||||
}
|
||||
|
||||
// Optional -
|
||||
if s[0] == '-' {
|
||||
neg = true
|
||||
s = s[1:]
|
||||
if len(s) == 0 {
|
||||
return numberParts{}, false
|
||||
}
|
||||
}
|
||||
|
||||
// Digits
|
||||
switch {
|
||||
case s[0] == '0':
|
||||
// Skip first 0 and no need to store.
|
||||
s = s[1:]
|
||||
|
||||
case '1' <= s[0] && s[0] <= '9':
|
||||
intp = s
|
||||
n := 1
|
||||
s = s[1:]
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
|
||||
s = s[1:]
|
||||
n++
|
||||
}
|
||||
intp = intp[:n]
|
||||
|
||||
default:
|
||||
return numberParts{}, false
|
||||
}
|
||||
|
||||
// . followed by 1 or more digits.
|
||||
if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
|
||||
frac = s[1:]
|
||||
n := 1
|
||||
s = s[2:]
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
|
||||
s = s[1:]
|
||||
n++
|
||||
}
|
||||
frac = frac[:n]
|
||||
}
|
||||
|
||||
// e or E followed by an optional - or + and
|
||||
// 1 or more digits.
|
||||
if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
|
||||
s = s[1:]
|
||||
exp = s
|
||||
n := 0
|
||||
if s[0] == '+' || s[0] == '-' {
|
||||
s = s[1:]
|
||||
n++
|
||||
if len(s) == 0 {
|
||||
return numberParts{}, false
|
||||
}
|
||||
}
|
||||
for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
|
||||
s = s[1:]
|
||||
n++
|
||||
}
|
||||
exp = exp[:n]
|
||||
}
|
||||
|
||||
return numberParts{
|
||||
neg: neg,
|
||||
intp: intp,
|
||||
frac: bytes.TrimRight(frac, "0"), // Remove unnecessary 0s to the right.
|
||||
exp: exp,
|
||||
}, true
|
||||
}
|
||||
|
||||
// normalizeToIntString returns an integer string in normal form without the
|
||||
// E-notation for given numberParts. It will return false if it is not an
|
||||
// integer or if the exponent exceeds than max/min int value.
|
||||
func normalizeToIntString(n numberParts) (string, bool) {
|
||||
intpSize := len(n.intp)
|
||||
fracSize := len(n.frac)
|
||||
|
||||
if intpSize == 0 && fracSize == 0 {
|
||||
return "0", true
|
||||
}
|
||||
|
||||
var exp int
|
||||
if len(n.exp) > 0 {
|
||||
i, err := strconv.ParseInt(string(n.exp), 10, 32)
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
exp = int(i)
|
||||
}
|
||||
|
||||
var num []byte
|
||||
if exp >= 0 {
|
||||
// For positive E, shift fraction digits into integer part and also pad
|
||||
// with zeroes as needed.
|
||||
|
||||
// If there are more digits in fraction than the E value, then the
|
||||
// number is not an integer.
|
||||
if fracSize > exp {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Make sure resulting digits are within max value limit to avoid
|
||||
// unnecessarily constructing a large byte slice that may simply fail
|
||||
// later on.
|
||||
const maxDigits = 20 // Max uint64 value has 20 decimal digits.
|
||||
if intpSize+exp > maxDigits {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Set cap to make a copy of integer part when appended.
|
||||
num = n.intp[:len(n.intp):len(n.intp)]
|
||||
num = append(num, n.frac...)
|
||||
for i := 0; i < exp-fracSize; i++ {
|
||||
num = append(num, '0')
|
||||
}
|
||||
} else {
|
||||
// For negative E, shift digits in integer part out.
|
||||
|
||||
// If there are fractions, then the number is not an integer.
|
||||
if fracSize > 0 {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// index is where the decimal point will be after adjusting for negative
|
||||
// exponent.
|
||||
index := intpSize + exp
|
||||
if index < 0 {
|
||||
return "", false
|
||||
}
|
||||
|
||||
num = n.intp
|
||||
// If any of the digits being shifted to the right of the decimal point
|
||||
// is non-zero, then the number is not an integer.
|
||||
for i := index; i < intpSize; i++ {
|
||||
if num[i] != '0' {
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
num = num[:index]
|
||||
}
|
||||
|
||||
if n.neg {
|
||||
return "-" + string(num), true
|
||||
}
|
||||
return string(num), true
|
||||
}
|
91
vendor/google.golang.org/protobuf/internal/encoding/json/decode_string.go
generated
vendored
Normal file
91
vendor/google.golang.org/protobuf/internal/encoding/json/decode_string.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright 2018 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 json
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"unicode"
|
||||
"unicode/utf16"
|
||||
"unicode/utf8"
|
||||
|
||||
"google.golang.org/protobuf/internal/strs"
|
||||
)
|
||||
|
||||
func (d *Decoder) parseString(in []byte) (string, int, error) {
|
||||
in0 := in
|
||||
if len(in) == 0 {
|
||||
return "", 0, ErrUnexpectedEOF
|
||||
}
|
||||
if in[0] != '"' {
|
||||
return "", 0, d.newSyntaxError(d.currPos(), "invalid character %q at start of string", in[0])
|
||||
}
|
||||
in = in[1:]
|
||||
i := indexNeedEscapeInBytes(in)
|
||||
in, out := in[i:], in[:i:i] // set cap to prevent mutations
|
||||
for len(in) > 0 {
|
||||
switch r, n := utf8.DecodeRune(in); {
|
||||
case r == utf8.RuneError && n == 1:
|
||||
return "", 0, d.newSyntaxError(d.currPos(), "invalid UTF-8 in string")
|
||||
case r < ' ':
|
||||
return "", 0, d.newSyntaxError(d.currPos(), "invalid character %q in string", r)
|
||||
case r == '"':
|
||||
in = in[1:]
|
||||
n := len(in0) - len(in)
|
||||
return string(out), n, nil
|
||||
case r == '\\':
|
||||
if len(in) < 2 {
|
||||
return "", 0, ErrUnexpectedEOF
|
||||
}
|
||||
switch r := in[1]; r {
|
||||
case '"', '\\', '/':
|
||||
in, out = in[2:], append(out, r)
|
||||
case 'b':
|
||||
in, out = in[2:], append(out, '\b')
|
||||
case 'f':
|
||||
in, out = in[2:], append(out, '\f')
|
||||
case 'n':
|
||||
in, out = in[2:], append(out, '\n')
|
||||
case 'r':
|
||||
in, out = in[2:], append(out, '\r')
|
||||
case 't':
|
||||
in, out = in[2:], append(out, '\t')
|
||||
case 'u':
|
||||
if len(in) < 6 {
|
||||
return "", 0, ErrUnexpectedEOF
|
||||
}
|
||||
v, err := strconv.ParseUint(string(in[2:6]), 16, 16)
|
||||
if err != nil {
|
||||
return "", 0, d.newSyntaxError(d.currPos(), "invalid escape code %q in string", in[:6])
|
||||
}
|
||||
in = in[6:]
|
||||
|
||||
r := rune(v)
|
||||
if utf16.IsSurrogate(r) {
|
||||
if len(in) < 6 {
|
||||
return "", 0, ErrUnexpectedEOF
|
||||
}
|
||||
v, err := strconv.ParseUint(string(in[2:6]), 16, 16)
|
||||
r = utf16.DecodeRune(r, rune(v))
|
||||
if in[0] != '\\' || in[1] != 'u' ||
|
||||
r == unicode.ReplacementChar || err != nil {
|
||||
return "", 0, d.newSyntaxError(d.currPos(), "invalid escape code %q in string", in[:6])
|
||||
}
|
||||
in = in[6:]
|
||||
}
|
||||
out = append(out, string(r)...)
|
||||
default:
|
||||
return "", 0, d.newSyntaxError(d.currPos(), "invalid escape code %q in string", in[:2])
|
||||
}
|
||||
default:
|
||||
i := indexNeedEscapeInBytes(in[n:])
|
||||
in, out = in[n+i:], append(out, in[:n+i]...)
|
||||
}
|
||||
}
|
||||
return "", 0, ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
// indexNeedEscapeInBytes returns the index of the character that needs
|
||||
// escaping. If no characters need escaping, this returns the input length.
|
||||
func indexNeedEscapeInBytes(b []byte) int { return indexNeedEscapeInString(strs.UnsafeString(b)) }
|
192
vendor/google.golang.org/protobuf/internal/encoding/json/decode_token.go
generated
vendored
Normal file
192
vendor/google.golang.org/protobuf/internal/encoding/json/decode_token.go
generated
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
// 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 json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Kind represents a token kind expressible in the JSON format.
|
||||
type Kind uint16
|
||||
|
||||
const (
|
||||
Invalid Kind = (1 << iota) / 2
|
||||
EOF
|
||||
Null
|
||||
Bool
|
||||
Number
|
||||
String
|
||||
Name
|
||||
ObjectOpen
|
||||
ObjectClose
|
||||
ArrayOpen
|
||||
ArrayClose
|
||||
|
||||
// comma is only for parsing in between tokens and
|
||||
// does not need to be exported.
|
||||
comma
|
||||
)
|
||||
|
||||
func (k Kind) String() string {
|
||||
switch k {
|
||||
case EOF:
|
||||
return "eof"
|
||||
case Null:
|
||||
return "null"
|
||||
case Bool:
|
||||
return "bool"
|
||||
case Number:
|
||||
return "number"
|
||||
case String:
|
||||
return "string"
|
||||
case ObjectOpen:
|
||||
return "{"
|
||||
case ObjectClose:
|
||||
return "}"
|
||||
case Name:
|
||||
return "name"
|
||||
case ArrayOpen:
|
||||
return "["
|
||||
case ArrayClose:
|
||||
return "]"
|
||||
case comma:
|
||||
return ","
|
||||
}
|
||||
return "<invalid>"
|
||||
}
|
||||
|
||||
// Token provides a parsed token kind and value.
|
||||
//
|
||||
// Values are provided by the difference accessor methods. The accessor methods
|
||||
// Name, Bool, and ParsedString will panic if called on the wrong kind. There
|
||||
// are different accessor methods for the Number kind for converting to the
|
||||
// appropriate Go numeric type and those methods have the ok return value.
|
||||
type Token struct {
|
||||
// Token kind.
|
||||
kind Kind
|
||||
// pos provides the position of the token in the original input.
|
||||
pos int
|
||||
// raw bytes of the serialized token.
|
||||
// This is a subslice into the original input.
|
||||
raw []byte
|
||||
// boo is parsed boolean value.
|
||||
boo bool
|
||||
// str is parsed string value.
|
||||
str string
|
||||
}
|
||||
|
||||
// Kind returns the token kind.
|
||||
func (t Token) Kind() Kind {
|
||||
return t.kind
|
||||
}
|
||||
|
||||
// RawString returns the read value in string.
|
||||
func (t Token) RawString() string {
|
||||
return string(t.raw)
|
||||
}
|
||||
|
||||
// Pos returns the token position from the input.
|
||||
func (t Token) Pos() int {
|
||||
return t.pos
|
||||
}
|
||||
|
||||
// Name returns the object name if token is Name, else it panics.
|
||||
func (t Token) Name() string {
|
||||
if t.kind == Name {
|
||||
return t.str
|
||||
}
|
||||
panic(fmt.Sprintf("Token is not a Name: %v", t.RawString()))
|
||||
}
|
||||
|
||||
// Bool returns the bool value if token kind is Bool, else it panics.
|
||||
func (t Token) Bool() bool {
|
||||
if t.kind == Bool {
|
||||
return t.boo
|
||||
}
|
||||
panic(fmt.Sprintf("Token is not a Bool: %v", t.RawString()))
|
||||
}
|
||||
|
||||
// ParsedString returns the string value for a JSON string token or the read
|
||||
// value in string if token is not a string.
|
||||
func (t Token) ParsedString() string {
|
||||
if t.kind == String {
|
||||
return t.str
|
||||
}
|
||||
panic(fmt.Sprintf("Token is not a String: %v", t.RawString()))
|
||||
}
|
||||
|
||||
// Float returns the floating-point number if token kind is Number.
|
||||
//
|
||||
// The floating-point precision is specified by the bitSize parameter: 32 for
|
||||
// float32 or 64 for float64. If bitSize=32, the result still has type float64,
|
||||
// but it will be convertible to float32 without changing its value. It will
|
||||
// return false if the number exceeds the floating point limits for given
|
||||
// bitSize.
|
||||
func (t Token) Float(bitSize int) (float64, bool) {
|
||||
if t.kind != Number {
|
||||
return 0, false
|
||||
}
|
||||
f, err := strconv.ParseFloat(t.RawString(), bitSize)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return f, true
|
||||
}
|
||||
|
||||
// Int returns the signed integer number if token is Number.
|
||||
//
|
||||
// The given bitSize specifies the integer type that the result must fit into.
|
||||
// It returns false if the number is not an integer value or if the result
|
||||
// exceeds the limits for given bitSize.
|
||||
func (t Token) Int(bitSize int) (int64, bool) {
|
||||
s, ok := t.getIntStr()
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
n, err := strconv.ParseInt(s, 10, bitSize)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return n, true
|
||||
}
|
||||
|
||||
// Uint returns the signed integer number if token is Number.
|
||||
//
|
||||
// The given bitSize specifies the unsigned integer type that the result must
|
||||
// fit into. It returns false if the number is not an unsigned integer value
|
||||
// or if the result exceeds the limits for given bitSize.
|
||||
func (t Token) Uint(bitSize int) (uint64, bool) {
|
||||
s, ok := t.getIntStr()
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
n, err := strconv.ParseUint(s, 10, bitSize)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return n, true
|
||||
}
|
||||
|
||||
func (t Token) getIntStr() (string, bool) {
|
||||
if t.kind != Number {
|
||||
return "", false
|
||||
}
|
||||
parts, ok := parseNumberParts(t.raw)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
return normalizeToIntString(parts)
|
||||
}
|
||||
|
||||
// TokenEquals returns true if given Tokens are equal, else false.
|
||||
func TokenEquals(x, y Token) bool {
|
||||
return x.kind == y.kind &&
|
||||
x.pos == y.pos &&
|
||||
bytes.Equal(x.raw, y.raw) &&
|
||||
x.boo == y.boo &&
|
||||
x.str == y.str
|
||||
}
|
276
vendor/google.golang.org/protobuf/internal/encoding/json/encode.go
generated
vendored
Normal file
276
vendor/google.golang.org/protobuf/internal/encoding/json/encode.go
generated
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
// Copyright 2018 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 json
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/bits"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"google.golang.org/protobuf/internal/detrand"
|
||||
"google.golang.org/protobuf/internal/errors"
|
||||
)
|
||||
|
||||
// kind represents an encoding type.
|
||||
type kind uint8
|
||||
|
||||
const (
|
||||
_ kind = (1 << iota) / 2
|
||||
name
|
||||
scalar
|
||||
objectOpen
|
||||
objectClose
|
||||
arrayOpen
|
||||
arrayClose
|
||||
)
|
||||
|
||||
// Encoder provides methods to write out JSON constructs and values. The user is
|
||||
// responsible for producing valid sequences of JSON constructs and values.
|
||||
type Encoder struct {
|
||||
indent string
|
||||
lastKind kind
|
||||
indents []byte
|
||||
out []byte
|
||||
}
|
||||
|
||||
// NewEncoder returns an Encoder.
|
||||
//
|
||||
// If indent is a non-empty string, it causes every entry for an Array or Object
|
||||
// to be preceded by the indent and trailed by a newline.
|
||||
func NewEncoder(indent string) (*Encoder, error) {
|
||||
e := &Encoder{}
|
||||
if len(indent) > 0 {
|
||||
if strings.Trim(indent, " \t") != "" {
|
||||
return nil, errors.New("indent may only be composed of space or tab characters")
|
||||
}
|
||||
e.indent = indent
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// Bytes returns the content of the written bytes.
|
||||
func (e *Encoder) Bytes() []byte {
|
||||
return e.out
|
||||
}
|
||||
|
||||
// WriteNull writes out the null value.
|
||||
func (e *Encoder) WriteNull() {
|
||||
e.prepareNext(scalar)
|
||||
e.out = append(e.out, "null"...)
|
||||
}
|
||||
|
||||
// WriteBool writes out the given boolean value.
|
||||
func (e *Encoder) WriteBool(b bool) {
|
||||
e.prepareNext(scalar)
|
||||
if b {
|
||||
e.out = append(e.out, "true"...)
|
||||
} else {
|
||||
e.out = append(e.out, "false"...)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteString writes out the given string in JSON string value. Returns error
|
||||
// if input string contains invalid UTF-8.
|
||||
func (e *Encoder) WriteString(s string) error {
|
||||
e.prepareNext(scalar)
|
||||
var err error
|
||||
if e.out, err = appendString(e.out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sentinel error used for indicating invalid UTF-8.
|
||||
var errInvalidUTF8 = errors.New("invalid UTF-8")
|
||||
|
||||
func appendString(out []byte, in string) ([]byte, error) {
|
||||
out = append(out, '"')
|
||||
i := indexNeedEscapeInString(in)
|
||||
in, out = in[i:], append(out, in[:i]...)
|
||||
for len(in) > 0 {
|
||||
switch r, n := utf8.DecodeRuneInString(in); {
|
||||
case r == utf8.RuneError && n == 1:
|
||||
return out, errInvalidUTF8
|
||||
case r < ' ' || r == '"' || r == '\\':
|
||||
out = append(out, '\\')
|
||||
switch r {
|
||||
case '"', '\\':
|
||||
out = append(out, byte(r))
|
||||
case '\b':
|
||||
out = append(out, 'b')
|
||||
case '\f':
|
||||
out = append(out, 'f')
|
||||
case '\n':
|
||||
out = append(out, 'n')
|
||||
case '\r':
|
||||
out = append(out, 'r')
|
||||
case '\t':
|
||||
out = append(out, 't')
|
||||
default:
|
||||
out = append(out, 'u')
|
||||
out = append(out, "0000"[1+(bits.Len32(uint32(r))-1)/4:]...)
|
||||
out = strconv.AppendUint(out, uint64(r), 16)
|
||||
}
|
||||
in = in[n:]
|
||||
default:
|
||||
i := indexNeedEscapeInString(in[n:])
|
||||
in, out = in[n+i:], append(out, in[:n+i]...)
|
||||
}
|
||||
}
|
||||
out = append(out, '"')
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// indexNeedEscapeInString returns the index of the character that needs
|
||||
// escaping. If no characters need escaping, this returns the input length.
|
||||
func indexNeedEscapeInString(s string) int {
|
||||
for i, r := range s {
|
||||
if r < ' ' || r == '\\' || r == '"' || r == utf8.RuneError {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return len(s)
|
||||
}
|
||||
|
||||
// WriteFloat writes out the given float and bitSize in JSON number value.
|
||||
func (e *Encoder) WriteFloat(n float64, bitSize int) {
|
||||
e.prepareNext(scalar)
|
||||
e.out = appendFloat(e.out, n, bitSize)
|
||||
}
|
||||
|
||||
// appendFloat formats given float in bitSize, and appends to the given []byte.
|
||||
func appendFloat(out []byte, n float64, bitSize int) []byte {
|
||||
switch {
|
||||
case math.IsNaN(n):
|
||||
return append(out, `"NaN"`...)
|
||||
case math.IsInf(n, +1):
|
||||
return append(out, `"Infinity"`...)
|
||||
case math.IsInf(n, -1):
|
||||
return append(out, `"-Infinity"`...)
|
||||
}
|
||||
|
||||
// JSON number formatting logic based on encoding/json.
|
||||
// See floatEncoder.encode for reference.
|
||||
fmt := byte('f')
|
||||
if abs := math.Abs(n); abs != 0 {
|
||||
if bitSize == 64 && (abs < 1e-6 || abs >= 1e21) ||
|
||||
bitSize == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
|
||||
fmt = 'e'
|
||||
}
|
||||
}
|
||||
out = strconv.AppendFloat(out, n, fmt, -1, bitSize)
|
||||
if fmt == 'e' {
|
||||
n := len(out)
|
||||
if n >= 4 && out[n-4] == 'e' && out[n-3] == '-' && out[n-2] == '0' {
|
||||
out[n-2] = out[n-1]
|
||||
out = out[:n-1]
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// WriteInt writes out the given signed integer in JSON number value.
|
||||
func (e *Encoder) WriteInt(n int64) {
|
||||
e.prepareNext(scalar)
|
||||
e.out = append(e.out, strconv.FormatInt(n, 10)...)
|
||||
}
|
||||
|
||||
// WriteUint writes out the given unsigned integer in JSON number value.
|
||||
func (e *Encoder) WriteUint(n uint64) {
|
||||
e.prepareNext(scalar)
|
||||
e.out = append(e.out, strconv.FormatUint(n, 10)...)
|
||||
}
|
||||
|
||||
// StartObject writes out the '{' symbol.
|
||||
func (e *Encoder) StartObject() {
|
||||
e.prepareNext(objectOpen)
|
||||
e.out = append(e.out, '{')
|
||||
}
|
||||
|
||||
// EndObject writes out the '}' symbol.
|
||||
func (e *Encoder) EndObject() {
|
||||
e.prepareNext(objectClose)
|
||||
e.out = append(e.out, '}')
|
||||
}
|
||||
|
||||
// WriteName writes out the given string in JSON string value and the name
|
||||
// separator ':'. Returns error if input string contains invalid UTF-8, which
|
||||
// should not be likely as protobuf field names should be valid.
|
||||
func (e *Encoder) WriteName(s string) error {
|
||||
e.prepareNext(name)
|
||||
var err error
|
||||
// Append to output regardless of error.
|
||||
e.out, err = appendString(e.out, s)
|
||||
e.out = append(e.out, ':')
|
||||
return err
|
||||
}
|
||||
|
||||
// StartArray writes out the '[' symbol.
|
||||
func (e *Encoder) StartArray() {
|
||||
e.prepareNext(arrayOpen)
|
||||
e.out = append(e.out, '[')
|
||||
}
|
||||
|
||||
// EndArray writes out the ']' symbol.
|
||||
func (e *Encoder) EndArray() {
|
||||
e.prepareNext(arrayClose)
|
||||
e.out = append(e.out, ']')
|
||||
}
|
||||
|
||||
// prepareNext adds possible comma and indentation for the next value based
|
||||
// on last type and indent option. It also updates lastKind to next.
|
||||
func (e *Encoder) prepareNext(next kind) {
|
||||
defer func() {
|
||||
// Set lastKind to next.
|
||||
e.lastKind = next
|
||||
}()
|
||||
|
||||
if len(e.indent) == 0 {
|
||||
// Need to add comma on the following condition.
|
||||
if e.lastKind&(scalar|objectClose|arrayClose) != 0 &&
|
||||
next&(name|scalar|objectOpen|arrayOpen) != 0 {
|
||||
e.out = append(e.out, ',')
|
||||
// For single-line output, add a random extra space after each
|
||||
// comma to make output unstable.
|
||||
if detrand.Bool() {
|
||||
e.out = append(e.out, ' ')
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
switch {
|
||||
case e.lastKind&(objectOpen|arrayOpen) != 0:
|
||||
// If next type is NOT closing, add indent and newline.
|
||||
if next&(objectClose|arrayClose) == 0 {
|
||||
e.indents = append(e.indents, e.indent...)
|
||||
e.out = append(e.out, '\n')
|
||||
e.out = append(e.out, e.indents...)
|
||||
}
|
||||
|
||||
case e.lastKind&(scalar|objectClose|arrayClose) != 0:
|
||||
switch {
|
||||
// If next type is either a value or name, add comma and newline.
|
||||
case next&(name|scalar|objectOpen|arrayOpen) != 0:
|
||||
e.out = append(e.out, ',', '\n')
|
||||
|
||||
// If next type is a closing object or array, adjust indentation.
|
||||
case next&(objectClose|arrayClose) != 0:
|
||||
e.indents = e.indents[:len(e.indents)-len(e.indent)]
|
||||
e.out = append(e.out, '\n')
|
||||
}
|
||||
e.out = append(e.out, e.indents...)
|
||||
|
||||
case e.lastKind&name != 0:
|
||||
e.out = append(e.out, ' ')
|
||||
// For multi-line output, add a random extra space after key: to make
|
||||
// output unstable.
|
||||
if detrand.Bool() {
|
||||
e.out = append(e.out, ' ')
|
||||
}
|
||||
}
|
||||
}
|
2
vendor/google.golang.org/protobuf/internal/encoding/text/decode.go
generated
vendored
2
vendor/google.golang.org/protobuf/internal/encoding/text/decode.go
generated
vendored
@@ -381,7 +381,7 @@ func (d *Decoder) currentOpenKind() (Kind, byte) {
|
||||
case '[':
|
||||
return ListOpen, ']'
|
||||
}
|
||||
panic(fmt.Sprintf("Decoder: openStack contains invalid byte %s", string(openCh)))
|
||||
panic(fmt.Sprintf("Decoder: openStack contains invalid byte %c", openCh))
|
||||
}
|
||||
|
||||
func (d *Decoder) pushOpenStack(ch byte) {
|
||||
|
1
vendor/google.golang.org/protobuf/internal/errors/is_go112.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/errors/is_go112.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !go1.13
|
||||
// +build !go1.13
|
||||
|
||||
package errors
|
||||
|
1
vendor/google.golang.org/protobuf/internal/errors/is_go113.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/errors/is_go113.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.13
|
||||
// +build go1.13
|
||||
|
||||
package errors
|
||||
|
1
vendor/google.golang.org/protobuf/internal/flags/proto_legacy_disable.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/flags/proto_legacy_disable.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !protolegacy
|
||||
// +build !protolegacy
|
||||
|
||||
package flags
|
||||
|
1
vendor/google.golang.org/protobuf/internal/flags/proto_legacy_enable.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/flags/proto_legacy_enable.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build protolegacy
|
||||
// +build protolegacy
|
||||
|
||||
package flags
|
||||
|
1
vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !go1.12
|
||||
// +build !go1.12
|
||||
|
||||
package impl
|
||||
|
1
vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.12
|
||||
// +build go1.12
|
||||
|
||||
package impl
|
||||
|
1
vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build purego || appengine
|
||||
// +build purego appengine
|
||||
|
||||
package impl
|
||||
|
1
vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !purego && !appengine
|
||||
// +build !purego,!appengine
|
||||
|
||||
package impl
|
||||
|
8
vendor/google.golang.org/protobuf/internal/impl/decode.go
generated
vendored
8
vendor/google.golang.org/protobuf/internal/impl/decode.go
generated
vendored
@@ -18,6 +18,7 @@ import (
|
||||
)
|
||||
|
||||
var errDecode = errors.New("cannot parse invalid wire-format data")
|
||||
var errRecursionDepth = errors.New("exceeded maximum recursion depth")
|
||||
|
||||
type unmarshalOptions struct {
|
||||
flags protoiface.UnmarshalInputFlags
|
||||
@@ -25,6 +26,7 @@ type unmarshalOptions struct {
|
||||
FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
|
||||
FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
|
||||
}
|
||||
depth int
|
||||
}
|
||||
|
||||
func (o unmarshalOptions) Options() proto.UnmarshalOptions {
|
||||
@@ -44,6 +46,7 @@ func (o unmarshalOptions) IsDefault() bool {
|
||||
|
||||
var lazyUnmarshalOptions = unmarshalOptions{
|
||||
resolver: preg.GlobalTypes,
|
||||
depth: protowire.DefaultRecursionLimit,
|
||||
}
|
||||
|
||||
type unmarshalOutput struct {
|
||||
@@ -62,6 +65,7 @@ func (mi *MessageInfo) unmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutp
|
||||
out, err := mi.unmarshalPointer(in.Buf, p, 0, unmarshalOptions{
|
||||
flags: in.Flags,
|
||||
resolver: in.Resolver,
|
||||
depth: in.Depth,
|
||||
})
|
||||
var flags piface.UnmarshalOutputFlags
|
||||
if out.initialized {
|
||||
@@ -82,6 +86,10 @@ var errUnknown = errors.New("unknown")
|
||||
|
||||
func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
mi.init()
|
||||
opts.depth--
|
||||
if opts.depth < 0 {
|
||||
return out, errRecursionDepth
|
||||
}
|
||||
if flags.ProtoLegacy && mi.isMessageSet {
|
||||
return unmarshalMessageSet(mi, b, p, opts)
|
||||
}
|
||||
|
1
vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build purego || appengine
|
||||
// +build purego appengine
|
||||
|
||||
package impl
|
||||
|
1
vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !purego && !appengine
|
||||
// +build !purego,!appengine
|
||||
|
||||
package impl
|
||||
|
1
vendor/google.golang.org/protobuf/internal/strs/strings_pure.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/strs/strings_pure.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build purego || appengine
|
||||
// +build purego appengine
|
||||
|
||||
package strs
|
||||
|
1
vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go
generated
vendored
1
vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !purego && !appengine
|
||||
// +build !purego,!appengine
|
||||
|
||||
package strs
|
||||
|
4
vendor/google.golang.org/protobuf/internal/version/version.go
generated
vendored
4
vendor/google.golang.org/protobuf/internal/version/version.go
generated
vendored
@@ -52,8 +52,8 @@ import (
|
||||
// 10. Send out the CL for review and submit it.
|
||||
const (
|
||||
Major = 1
|
||||
Minor = 27
|
||||
Patch = 1
|
||||
Minor = 28
|
||||
Patch = 0
|
||||
PreRelease = ""
|
||||
)
|
||||
|
||||
|
17
vendor/google.golang.org/protobuf/proto/decode.go
generated
vendored
17
vendor/google.golang.org/protobuf/proto/decode.go
generated
vendored
@@ -42,18 +42,25 @@ type UnmarshalOptions struct {
|
||||
FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
|
||||
FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
|
||||
}
|
||||
|
||||
// RecursionLimit limits how deeply messages may be nested.
|
||||
// If zero, a default limit is applied.
|
||||
RecursionLimit int
|
||||
}
|
||||
|
||||
// Unmarshal parses the wire-format message in b and places the result in m.
|
||||
// The provided message must be mutable (e.g., a non-nil pointer to a message).
|
||||
func Unmarshal(b []byte, m Message) error {
|
||||
_, err := UnmarshalOptions{}.unmarshal(b, m.ProtoReflect())
|
||||
_, err := UnmarshalOptions{RecursionLimit: protowire.DefaultRecursionLimit}.unmarshal(b, m.ProtoReflect())
|
||||
return err
|
||||
}
|
||||
|
||||
// Unmarshal parses the wire-format message in b and places the result in m.
|
||||
// The provided message must be mutable (e.g., a non-nil pointer to a message).
|
||||
func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error {
|
||||
if o.RecursionLimit == 0 {
|
||||
o.RecursionLimit = protowire.DefaultRecursionLimit
|
||||
}
|
||||
_, err := o.unmarshal(b, m.ProtoReflect())
|
||||
return err
|
||||
}
|
||||
@@ -63,6 +70,9 @@ func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error {
|
||||
// This method permits fine-grained control over the unmarshaler.
|
||||
// Most users should use Unmarshal instead.
|
||||
func (o UnmarshalOptions) UnmarshalState(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
|
||||
if o.RecursionLimit == 0 {
|
||||
o.RecursionLimit = protowire.DefaultRecursionLimit
|
||||
}
|
||||
return o.unmarshal(in.Buf, in.Message)
|
||||
}
|
||||
|
||||
@@ -86,12 +96,17 @@ func (o UnmarshalOptions) unmarshal(b []byte, m protoreflect.Message) (out proto
|
||||
Message: m,
|
||||
Buf: b,
|
||||
Resolver: o.Resolver,
|
||||
Depth: o.RecursionLimit,
|
||||
}
|
||||
if o.DiscardUnknown {
|
||||
in.Flags |= protoiface.UnmarshalDiscardUnknown
|
||||
}
|
||||
out, err = methods.Unmarshal(in)
|
||||
} else {
|
||||
o.RecursionLimit--
|
||||
if o.RecursionLimit < 0 {
|
||||
return out, errors.New("exceeded max recursion depth")
|
||||
}
|
||||
err = o.unmarshalMessageSlow(b, m)
|
||||
}
|
||||
if err != nil {
|
||||
|
1
vendor/google.golang.org/protobuf/proto/proto_methods.go
generated
vendored
1
vendor/google.golang.org/protobuf/proto/proto_methods.go
generated
vendored
@@ -3,6 +3,7 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// The protoreflect build tag disables use of fast-path methods.
|
||||
//go:build !protoreflect
|
||||
// +build !protoreflect
|
||||
|
||||
package proto
|
||||
|
1
vendor/google.golang.org/protobuf/proto/proto_reflect.go
generated
vendored
1
vendor/google.golang.org/protobuf/proto/proto_reflect.go
generated
vendored
@@ -3,6 +3,7 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// The protoreflect build tag disables use of fast-path methods.
|
||||
//go:build protoreflect
|
||||
// +build protoreflect
|
||||
|
||||
package proto
|
||||
|
1
vendor/google.golang.org/protobuf/reflect/protoreflect/methods.go
generated
vendored
1
vendor/google.golang.org/protobuf/reflect/protoreflect/methods.go
generated
vendored
@@ -53,6 +53,7 @@ type (
|
||||
FindExtensionByName(field FullName) (ExtensionType, error)
|
||||
FindExtensionByNumber(message FullName, field FieldNumber) (ExtensionType, error)
|
||||
}
|
||||
Depth int
|
||||
}
|
||||
unmarshalOutput = struct {
|
||||
pragma.NoUnkeyedLiterals
|
||||
|
1
vendor/google.golang.org/protobuf/reflect/protoreflect/value_pure.go
generated
vendored
1
vendor/google.golang.org/protobuf/reflect/protoreflect/value_pure.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build purego || appengine
|
||||
// +build purego appengine
|
||||
|
||||
package protoreflect
|
||||
|
25
vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go
generated
vendored
25
vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go
generated
vendored
@@ -41,6 +41,31 @@ import (
|
||||
// Converting to/from a Value and a concrete Go value panics on type mismatch.
|
||||
// For example, ValueOf("hello").Int() panics because this attempts to
|
||||
// retrieve an int64 from a string.
|
||||
//
|
||||
// List, Map, and Message Values are called "composite" values.
|
||||
//
|
||||
// A composite Value may alias (reference) memory at some location,
|
||||
// such that changes to the Value updates the that location.
|
||||
// A composite value acquired with a Mutable method, such as Message.Mutable,
|
||||
// always references the source object.
|
||||
//
|
||||
// For example:
|
||||
// // Append a 0 to a "repeated int32" field.
|
||||
// // Since the Value returned by Mutable is guaranteed to alias
|
||||
// // the source message, modifying the Value modifies the message.
|
||||
// message.Mutable(fieldDesc).(List).Append(protoreflect.ValueOfInt32(0))
|
||||
//
|
||||
// // Assign [0] to a "repeated int32" field by creating a new Value,
|
||||
// // modifying it, and assigning it.
|
||||
// list := message.NewField(fieldDesc).(List)
|
||||
// list.Append(protoreflect.ValueOfInt32(0))
|
||||
// message.Set(fieldDesc, list)
|
||||
// // ERROR: Since it is not defined whether Set aliases the source,
|
||||
// // appending to the List here may or may not modify the message.
|
||||
// list.Append(protoreflect.ValueOfInt32(0))
|
||||
//
|
||||
// Some operations, such as Message.Get, may return an "empty, read-only"
|
||||
// composite Value. Modifying an empty, read-only value panics.
|
||||
type Value value
|
||||
|
||||
// The protoreflect API uses a custom Value union type instead of interface{}
|
||||
|
1
vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go
generated
vendored
1
vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !purego && !appengine
|
||||
// +build !purego,!appengine
|
||||
|
||||
package protoreflect
|
||||
|
1
vendor/google.golang.org/protobuf/runtime/protoiface/methods.go
generated
vendored
1
vendor/google.golang.org/protobuf/runtime/protoiface/methods.go
generated
vendored
@@ -103,6 +103,7 @@ type UnmarshalInput = struct {
|
||||
FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
|
||||
FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
|
||||
}
|
||||
Depth int
|
||||
}
|
||||
|
||||
// UnmarshalOutput is output from the Unmarshal method.
|
||||
|
Reference in New Issue
Block a user