package prototext
import (
)
func ( []byte, proto.Message) error {
return UnmarshalOptions{}.Unmarshal(, )
}
type UnmarshalOptions struct {
pragma.NoUnkeyedLiterals
AllowPartial bool
DiscardUnknown bool
Resolver interface {
protoregistry.MessageTypeResolver
protoregistry.ExtensionTypeResolver
}
}
func ( UnmarshalOptions) ( []byte, proto.Message) error {
return .unmarshal(, )
}
func ( UnmarshalOptions) ( []byte, proto.Message) error {
proto.Reset()
if .Resolver == nil {
.Resolver = protoregistry.GlobalTypes
}
:= decoder{text.NewDecoder(), }
if := .unmarshalMessage(.ProtoReflect(), false); != nil {
return
}
if .AllowPartial {
return nil
}
return proto.CheckInitialized()
}
type decoder struct {
*text.Decoder
opts UnmarshalOptions
}
func ( decoder) ( int, string, ...interface{}) error {
, := .Position()
:= fmt.Sprintf("(line %d:%d): ", , )
return errors.New(+, ...)
}
func ( decoder) ( text.Token) error {
return .syntaxError(.Pos(), "unexpected token: %s", .RawString())
}
func ( decoder) ( int, string, ...interface{}) error {
, := .Position()
:= fmt.Sprintf("syntax error (line %d:%d): ", , )
return errors.New(+, ...)
}
func ( decoder) ( protoreflect.Message, bool) error {
:= .Descriptor()
if !flags.ProtoLegacy && messageset.IsMessageSet() {
return errors.New("no support for proto1 MessageSets")
}
if .FullName() == genid.Any_message_fullname {
return .unmarshalAny(, )
}
if {
, := .Read()
if != nil {
return
}
if .Kind() != text.MessageOpen {
return .unexpectedTokenError()
}
}
var set.Ints
var set.Ints
:= .Fields()
for {
, := .Read()
if != nil {
return
}
switch := .Kind(); {
case text.Name:
case text.EOF:
if {
return text.ErrUnexpectedEOF
}
return nil
default:
if && == text.MessageClose {
return nil
}
return .unexpectedTokenError()
}
var protoreflect.Name
var protoreflect.FieldDescriptor
var protoreflect.ExtensionType
var error
var bool
switch .NameKind() {
case text.IdentName:
= protoreflect.Name(.IdentName())
= .ByTextName(string())
case text.TypeName:
, = .opts.Resolver.FindExtensionByName(protoreflect.FullName(.TypeName()))
case text.FieldNumber:
= true
:= protoreflect.FieldNumber(.FieldNumber())
if !.IsValid() {
return .newError(.Pos(), "invalid field number: %d", )
}
= .ByNumber()
if == nil {
, = .opts.Resolver.FindExtensionByNumber(.FullName(), )
}
}
if != nil {
= .TypeDescriptor()
if !.ExtensionRanges().Has(.Number()) || .ContainingMessage().FullName() != .FullName() {
return .newError(.Pos(), "message %v cannot be extended by %v", .FullName(), .FullName())
}
} else if != nil && != protoregistry.NotFound {
return .newError(.Pos(), "unable to resolve [%s]: %v", .RawString(), )
}
if flags.ProtoLegacy {
if != nil && .IsWeak() && .Message().IsPlaceholder() {
= nil
}
}
if == nil {
if .opts.DiscardUnknown || .ReservedNames().Has() {
.skipValue()
continue
}
return .newError(.Pos(), "unknown field: %v", .RawString())
}
if {
return .newError(.Pos(), "cannot specify field by number: %v", .RawString())
}
switch {
case .IsList():
:= .Kind()
if != protoreflect.MessageKind && != protoreflect.GroupKind && !.HasSeparator() {
return .syntaxError(.Pos(), "missing field separator :")
}
:= .Mutable().List()
if := .unmarshalList(, ); != nil {
return
}
case .IsMap():
:= .Mutable().Map()
if := .unmarshalMap(, ); != nil {
return
}
default:
:= .Kind()
if != protoreflect.MessageKind && != protoreflect.GroupKind && !.HasSeparator() {
return .syntaxError(.Pos(), "missing field separator :")
}
if := .ContainingOneof(); != nil {
:= uint64(.Index())
if .Has() {
return .newError(.Pos(), "error parsing %q, oneof %v is already set", .RawString(), .FullName())
}
.Set()
}
:= uint64(.Number())
if .Has() {
return .newError(.Pos(), "non-repeated field %q is repeated", .RawString())
}
if := .unmarshalSingular(, ); != nil {
return
}
.Set()
}
}
return nil
}
func ( decoder) ( protoreflect.FieldDescriptor, protoreflect.Message) error {
var protoreflect.Value
var error
switch .Kind() {
case protoreflect.MessageKind, protoreflect.GroupKind:
= .NewField()
= .unmarshalMessage(.Message(), true)
default:
, = .unmarshalScalar()
}
if == nil {
.Set(, )
}
return
}
func ( decoder) ( protoreflect.FieldDescriptor) (protoreflect.Value, error) {
, := .Read()
if != nil {
return protoreflect.Value{},
}
if .Kind() != text.Scalar {
return protoreflect.Value{}, .unexpectedTokenError()
}
:= .Kind()
switch {
case protoreflect.BoolKind:
if , := .Bool(); {
return protoreflect.ValueOfBool(), nil
}
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
if , := .Int32(); {
return protoreflect.ValueOfInt32(), nil
}
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
if , := .Int64(); {
return protoreflect.ValueOfInt64(), nil
}
case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
if , := .Uint32(); {
return protoreflect.ValueOfUint32(), nil
}
case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
if , := .Uint64(); {
return protoreflect.ValueOfUint64(), nil
}
case protoreflect.FloatKind:
if , := .Float32(); {
return protoreflect.ValueOfFloat32(), nil
}
case protoreflect.DoubleKind:
if , := .Float64(); {
return protoreflect.ValueOfFloat64(), nil
}
case protoreflect.StringKind:
if , := .String(); {
if strs.EnforceUTF8() && !utf8.ValidString() {
return protoreflect.Value{}, .newError(.Pos(), "contains invalid UTF-8")
}
return protoreflect.ValueOfString(), nil
}
case protoreflect.BytesKind:
if , := .String(); {
return protoreflect.ValueOfBytes([]byte()), nil
}
case protoreflect.EnumKind:
if , := .Enum(); {
if := .Enum().Values().ByName(protoreflect.Name()); != nil {
return protoreflect.ValueOfEnum(.Number()), nil
}
}
if , := .Int32(); {
return protoreflect.ValueOfEnum(protoreflect.EnumNumber()), nil
}
default:
panic(fmt.Sprintf("invalid scalar kind %v", ))
}
return protoreflect.Value{}, .newError(.Pos(), "invalid value for %v type: %v", , .RawString())
}
func ( decoder) ( protoreflect.FieldDescriptor, protoreflect.List) error {
, := .Peek()
if != nil {
return
}
switch .Kind() {
case protoreflect.MessageKind, protoreflect.GroupKind:
switch .Kind() {
case text.ListOpen:
.Read()
for {
, := .Peek()
if != nil {
return
}
switch .Kind() {
case text.ListClose:
.Read()
return nil
case text.MessageOpen:
:= .NewElement()
if := .unmarshalMessage(.Message(), true); != nil {
return
}
.Append()
default:
return .unexpectedTokenError()
}
}
case text.MessageOpen:
:= .NewElement()
if := .unmarshalMessage(.Message(), true); != nil {
return
}
.Append()
return nil
}
default:
switch .Kind() {
case text.ListOpen:
.Read()
for {
, := .Peek()
if != nil {
return
}
switch .Kind() {
case text.ListClose:
.Read()
return nil
case text.Scalar:
, := .unmarshalScalar()
if != nil {
return
}
.Append()
default:
return .unexpectedTokenError()
}
}
case text.Scalar:
, := .unmarshalScalar()
if != nil {
return
}
.Append()
return nil
}
}
return .unexpectedTokenError()
}
func ( decoder) ( protoreflect.FieldDescriptor, protoreflect.Map) error {
var func() (protoreflect.Value, error)
switch .MapValue().Kind() {
case protoreflect.MessageKind, protoreflect.GroupKind:
= func() (protoreflect.Value, error) {
:= .NewValue()
if := .unmarshalMessage(.Message(), true); != nil {
return protoreflect.Value{},
}
return , nil
}
default:
= func() (protoreflect.Value, error) {
return .unmarshalScalar(.MapValue())
}
}
, := .Read()
if != nil {
return
}
switch .Kind() {
case text.MessageOpen:
return .unmarshalMapEntry(, , )
case text.ListOpen:
for {
, := .Read()
if != nil {
return
}
switch .Kind() {
case text.ListClose:
return nil
case text.MessageOpen:
if := .unmarshalMapEntry(, , ); != nil {
return
}
default:
return .unexpectedTokenError()
}
}
default:
return .unexpectedTokenError()
}
}
func ( decoder) ( protoreflect.FieldDescriptor, protoreflect.Map, func() (protoreflect.Value, error)) error {
var protoreflect.MapKey
var protoreflect.Value
:
for {
, := .Read()
if != nil {
return
}
switch .Kind() {
case text.Name:
if .NameKind() != text.IdentName {
if !.opts.DiscardUnknown {
return .newError(.Pos(), "unknown map entry field %q", .RawString())
}
.skipValue()
continue
}
case text.MessageClose:
break
default:
return .unexpectedTokenError()
}
switch := protoreflect.Name(.IdentName()); {
case genid.MapEntry_Key_field_name:
if !.HasSeparator() {
return .syntaxError(.Pos(), "missing field separator :")
}
if .IsValid() {
return .newError(.Pos(), "map entry %q cannot be repeated", )
}
, := .unmarshalScalar(.MapKey())
if != nil {
return
}
= .MapKey()
case genid.MapEntry_Value_field_name:
if := .MapValue().Kind(); ( != protoreflect.MessageKind) && ( != protoreflect.GroupKind) {
if !.HasSeparator() {
return .syntaxError(.Pos(), "missing field separator :")
}
}
if .IsValid() {
return .newError(.Pos(), "map entry %q cannot be repeated", )
}
, = ()
if != nil {
return
}
default:
if !.opts.DiscardUnknown {
return .newError(.Pos(), "unknown map entry field %q", )
}
.skipValue()
}
}
if !.IsValid() {
= .MapKey().Default().MapKey()
}
if !.IsValid() {
switch .MapValue().Kind() {
case protoreflect.MessageKind, protoreflect.GroupKind:
= .NewValue()
default:
= .MapValue().Default()
}
}
.Set(, )
return nil
}
func ( decoder) ( protoreflect.Message, bool) error {
var string
var []byte
var bool
var bool
var bool
if {
, := .Read()
if != nil {
return
}
if .Kind() != text.MessageOpen {
return .unexpectedTokenError()
}
}
:
for {
, := .Read()
if != nil {
return
}
if := .Kind(); != text.Name {
if {
if == text.MessageClose {
break
}
} else if == text.EOF {
break
}
return .unexpectedTokenError()
}
switch .NameKind() {
case text.IdentName:
if !.HasSeparator() {
return .syntaxError(.Pos(), "missing field separator :")
}
switch := protoreflect.Name(.IdentName()); {
case genid.Any_TypeUrl_field_name:
if {
return .newError(.Pos(), "duplicate %v field", genid.Any_TypeUrl_field_fullname)
}
if {
return .newError(.Pos(), "conflict with [%s] field", )
}
, := .Read()
if != nil {
return
}
var bool
, = .String()
if ! {
return .newError(.Pos(), "invalid %v field value: %v", genid.Any_TypeUrl_field_fullname, .RawString())
}
= true
case genid.Any_Value_field_name:
if {
return .newError(.Pos(), "duplicate %v field", genid.Any_Value_field_fullname)
}
if {
return .newError(.Pos(), "conflict with [%s] field", )
}
, := .Read()
if != nil {
return
}
, := .String()
if ! {
return .newError(.Pos(), "invalid %v field value: %v", genid.Any_Value_field_fullname, .RawString())
}
= []byte()
= true
default:
if !.opts.DiscardUnknown {
return .newError(.Pos(), "invalid field name %q in %v message", .RawString(), genid.Any_message_fullname)
}
}
case text.TypeName:
if {
return .newError(.Pos(), "cannot have more than one type")
}
if {
return .newError(.Pos(), "conflict with type_url field")
}
= .TypeName()
var error
, = .unmarshalExpandedAny(, .Pos())
if != nil {
return
}
= true
default:
if !.opts.DiscardUnknown {
return .newError(.Pos(), "invalid field name %q in %v message", .RawString(), genid.Any_message_fullname)
}
}
}
:= .Descriptor().Fields()
if len() > 0 {
.Set(.ByNumber(genid.Any_TypeUrl_field_number), protoreflect.ValueOfString())
}
if len() > 0 {
.Set(.ByNumber(genid.Any_Value_field_number), protoreflect.ValueOfBytes())
}
return nil
}
func ( decoder) ( string, int) ([]byte, error) {
, := .opts.Resolver.FindMessageByURL()
if != nil {
return nil, .newError(, "unable to resolve message [%v]: %v", , )
}
:= .New()
if := .unmarshalMessage(, true); != nil {
return nil,
}
, := proto.MarshalOptions{
AllowPartial: true,
Deterministic: true,
}.Marshal(.Interface())
if != nil {
return nil, .newError(, "error in marshaling message into Any.value: %v", )
}
return , nil
}
func ( decoder) () error {
, := .Read()
if != nil {
return
}
switch .Kind() {
case text.MessageOpen:
return .skipMessageValue()
case text.ListOpen:
for {
, := .Read()
if != nil {
return
}
switch .Kind() {
case text.ListClose:
return nil
case text.MessageOpen:
return .skipMessageValue()
default:
}
}
}
return nil
}
func ( decoder) () error {
for {
, := .Read()
if != nil {
return
}
switch .Kind() {
case text.MessageClose:
return nil
case text.Name:
if := .skipValue(); != nil {
return
}
}
}
}