Source File
decode.go
Belonging Package
google.golang.org/protobuf/encoding/protojson
package protojson
import (
pref
)
type UnmarshalOptions struct {
pragma.NoUnkeyedLiterals
Resolver interface {
protoregistry.MessageTypeResolver
protoregistry.ExtensionTypeResolver
}
}
func ( UnmarshalOptions) ( []byte, proto.Message) error {
proto.Reset()
if .Resolver == nil {
.Resolver = protoregistry.GlobalTypes
}
:= decoder{json.NewDecoder(), }
if := .unmarshalMessage(.ProtoReflect(), false); != nil {
return
}
, := .Read()
if != nil {
return
}
if .Kind() != json.EOF {
return .unexpectedTokenError()
}
if .AllowPartial {
return nil
}
return proto.CheckInitialized()
}
type decoder struct {
*json.Decoder
opts UnmarshalOptions
}
func ( decoder) ( pref.Message, bool) error {
if := wellKnownTypeUnmarshaler(.Descriptor().FullName()); != nil {
return (, )
}
, := .Read()
if != nil {
return
}
if .Kind() != json.ObjectOpen {
return .unexpectedTokenError()
}
if := .unmarshalFields(, ); != nil {
return
}
return nil
}
func ( decoder) ( pref.Message, bool) error {
:= .Descriptor()
if !flags.ProtoLegacy && messageset.IsMessageSet() {
return errors.New("no support for proto1 MessageSets")
}
var set.Ints
var set.Ints
:= .Fields()
, := .Read()
if != nil {
return
}
switch .Kind() {
default:
return .unexpectedTokenError()
case json.ObjectClose:
return nil
}
if && == "@type" {
.Read()
continue
}
var pref.FieldDescriptor
:= pref.FullName([1 : len()-1])
, := .findExtension()
if != nil && != protoregistry.NotFound {
return .newError(.Pos(), "unable to resolve %s: %v", .RawString(), )
}
if != nil {
= .TypeDescriptor()
if !.ExtensionRanges().Has(.Number()) || .ContainingMessage().FullName() != .FullName() {
return .newError(.Pos(), "message %v cannot be extended by %v", .FullName(), .FullName())
}
}
= .ByJSONName()
if == nil {
= .ByName(pref.Name())
:= .ByName(pref.Name(strings.ToLower()))
if != nil && .Kind() == pref.GroupKind && .Message().Name() == pref.Name() {
=
}
} else if .Kind() == pref.GroupKind && .Message().Name() != pref.Name() {
= nil // reset since field name is actually the message name
}
}
}
if flags.ProtoLegacy {
if != nil && .IsWeak() && .Message().IsPlaceholder() {
= nil // reset since the weak reference is not linked in
}
}
if .opts.DiscardUnknown {
if := .skipJSONValue(); != nil {
return
}
continue
}
return .newError(.Pos(), "unknown field %v", .RawString())
}
if , := .Peek(); .Kind() == json.Null && !isKnownValue() && !isNullValue() {
.Read()
continue
}
switch {
case .IsList():
:= .Mutable().List()
if := .unmarshalList(, ); != nil {
return
}
case .IsMap():
:= .Mutable().Map()
if := .unmarshalMap(, ); != nil {
return
}
if := .unmarshalSingular(, ); != nil {
return
}
}
}
}
func ( decoder) ( pref.FullName) (pref.ExtensionType, error) {
, := .opts.Resolver.FindExtensionByName()
if == nil {
return , nil
}
return messageset.FindMessageSetExtension(.opts.Resolver, )
}
func ( pref.FieldDescriptor) bool {
:= .Message()
return != nil && .FullName() == genid.Value_message_fullname
}
func ( pref.FieldDescriptor) bool {
:= .Enum()
return != nil && .FullName() == genid.NullValue_enum_fullname
}
func ( decoder) ( pref.FieldDescriptor) (pref.Value, error) {
const int = 32
const int = 64
, := .Read()
if != nil {
return pref.Value{},
}
:= .Kind()
switch {
case pref.BoolKind:
if .Kind() == json.Bool {
return pref.ValueOfBool(.Bool()), nil
}
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
if , := unmarshalInt(, ); {
return , nil
}
case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
if , := unmarshalInt(, ); {
return , nil
}
case pref.Uint32Kind, pref.Fixed32Kind:
if , := unmarshalUint(, ); {
return , nil
}
case pref.Uint64Kind, pref.Fixed64Kind:
if , := unmarshalUint(, ); {
return , nil
}
case pref.FloatKind:
if , := unmarshalFloat(, ); {
return , nil
}
case pref.DoubleKind:
if , := unmarshalFloat(, ); {
return , nil
}
case pref.StringKind:
if .Kind() == json.String {
return pref.ValueOfString(.ParsedString()), nil
}
case pref.BytesKind:
if , := unmarshalBytes(); {
return , nil
}
case pref.EnumKind:
if , := unmarshalEnum(, ); {
return , nil
}
default:
panic(fmt.Sprintf("unmarshalScalar: invalid scalar kind %v", ))
}
return pref.Value{}, .newError(.Pos(), "invalid value for %v type: %v", , .RawString())
}
func ( json.Token, int) (pref.Value, bool) {
switch .Kind() {
case json.Number:
return getInt(, )
:= strings.TrimSpace(.ParsedString())
if len() != len(.ParsedString()) {
return pref.Value{}, false
}
:= json.NewDecoder([]byte())
, := .Read()
if != nil {
return pref.Value{}, false
}
return getInt(, )
}
return pref.Value{}, false
}
func ( json.Token, int) (pref.Value, bool) {
, := .Int()
if ! {
return pref.Value{}, false
}
if == 32 {
return pref.ValueOfInt32(int32()), true
}
return pref.ValueOfInt64(), true
}
func ( json.Token, int) (pref.Value, bool) {
switch .Kind() {
case json.Number:
return getUint(, )
:= strings.TrimSpace(.ParsedString())
if len() != len(.ParsedString()) {
return pref.Value{}, false
}
:= json.NewDecoder([]byte())
, := .Read()
if != nil {
return pref.Value{}, false
}
return getUint(, )
}
return pref.Value{}, false
}
func ( json.Token, int) (pref.Value, bool) {
, := .Uint()
if ! {
return pref.Value{}, false
}
if == 32 {
return pref.ValueOfUint32(uint32()), true
}
return pref.ValueOfUint64(), true
}
func ( json.Token, int) (pref.Value, bool) {
switch .Kind() {
case json.Number:
return getFloat(, )
case json.String:
:= .ParsedString()
switch {
case "NaN":
if == 32 {
return pref.ValueOfFloat32(float32(math.NaN())), true
}
return pref.ValueOfFloat64(math.NaN()), true
case "Infinity":
if == 32 {
return pref.ValueOfFloat32(float32(math.Inf(+1))), true
}
return pref.ValueOfFloat64(math.Inf(+1)), true
case "-Infinity":
if == 32 {
return pref.ValueOfFloat32(float32(math.Inf(-1))), true
}
return pref.ValueOfFloat64(math.Inf(-1)), true
}
if len() != len(strings.TrimSpace()) {
return pref.Value{}, false
}
:= json.NewDecoder([]byte())
, := .Read()
if != nil {
return pref.Value{}, false
}
return getFloat(, )
}
return pref.Value{}, false
}
func ( json.Token, int) (pref.Value, bool) {
, := .Float()
if ! {
return pref.Value{}, false
}
if == 32 {
return pref.ValueOfFloat32(float32()), true
}
return pref.ValueOfFloat64(), true
}
func ( json.Token) (pref.Value, bool) {
if .Kind() != json.String {
return pref.Value{}, false
}
:= .ParsedString()
:= base64.StdEncoding
if strings.ContainsAny(, "-_") {
= base64.URLEncoding
}
if len()%4 != 0 {
= .WithPadding(base64.NoPadding)
}
, := .DecodeString()
if != nil {
return pref.Value{}, false
}
return pref.ValueOfBytes(), true
}
func ( json.Token, pref.FieldDescriptor) (pref.Value, bool) {
switch .Kind() {
:= .ParsedString()
if := .Enum().Values().ByName(pref.Name()); != nil {
return pref.ValueOfEnum(.Number()), true
}
case json.Number:
if , := .Int(32); {
return pref.ValueOfEnum(pref.EnumNumber()), true
}
if isNullValue() {
return pref.ValueOfEnum(0), true
}
}
return pref.Value{}, false
}
func ( decoder) ( pref.List, pref.FieldDescriptor) error {
, := .Read()
if != nil {
return
}
if .Kind() != json.ArrayOpen {
return .unexpectedTokenError()
}
switch .Kind() {
case pref.MessageKind, pref.GroupKind:
for {
, := .Peek()
if != nil {
return
}
if .Kind() == json.ArrayClose {
.Read()
return nil
}
:= .NewElement()
if := .unmarshalMessage(.Message(), false); != nil {
return
}
.Append()
}
default:
for {
, := .Peek()
if != nil {
return
}
if .Kind() == json.ArrayClose {
.Read()
return nil
}
, := .unmarshalScalar()
if != nil {
return
}
.Append()
}
}
return nil
}
func ( decoder) ( pref.Map, pref.FieldDescriptor) error {
, := .Read()
if != nil {
return
}
if .Kind() != json.ObjectOpen {
return .unexpectedTokenError()
}
var func() (pref.Value, error)
switch .MapValue().Kind() {
case pref.MessageKind, pref.GroupKind:
= func() (pref.Value, error) {
:= .NewValue()
if := .unmarshalMessage(.Message(), false); != nil {
return pref.Value{},
}
return , nil
}
default:
= func() (pref.Value, error) {
return .unmarshalScalar(.MapValue())
}
}
:
, := .Read()
if != nil {
return
}
switch .Kind() {
default:
return .unexpectedTokenError()
case json.ObjectClose:
break
}
, := .unmarshalMapKey(, .MapKey())
if != nil {
return
}
func ( decoder) ( json.Token, pref.FieldDescriptor) (pref.MapKey, error) {
const = 32
const = 64
const = 10
:= .Name()
:= .Kind()
switch {
case pref.StringKind:
return pref.ValueOfString().MapKey(), nil
case pref.BoolKind:
switch {
case "true":
return pref.ValueOfBool(true).MapKey(), nil
case "false":
return pref.ValueOfBool(false).MapKey(), nil
}
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
if , := strconv.ParseInt(, , ); == nil {
return pref.ValueOfInt32(int32()).MapKey(), nil
}
case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
if , := strconv.ParseInt(, , ); == nil {
return pref.ValueOfInt64(int64()).MapKey(), nil
}
case pref.Uint32Kind, pref.Fixed32Kind:
if , := strconv.ParseUint(, , ); == nil {
return pref.ValueOfUint32(uint32()).MapKey(), nil
}
case pref.Uint64Kind, pref.Fixed64Kind:
if , := strconv.ParseUint(, , ); == nil {
return pref.ValueOfUint64(uint64()).MapKey(), nil
}
default:
panic(fmt.Sprintf("invalid kind for map key: %v", ))
}
return pref.MapKey{}, .newError(.Pos(), "invalid value for %v key: %s", , .RawString())
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |