package proto
import (
)
type UnmarshalOptions struct {
pragma.NoUnkeyedLiterals
Merge bool
AllowPartial bool
DiscardUnknown bool
Resolver interface {
FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
}
RecursionLimit int
}
func ( []byte, Message) error {
, := UnmarshalOptions{RecursionLimit: protowire.DefaultRecursionLimit}.unmarshal(, .ProtoReflect())
return
}
func ( UnmarshalOptions) ( []byte, Message) error {
if .RecursionLimit == 0 {
.RecursionLimit = protowire.DefaultRecursionLimit
}
, := .unmarshal(, .ProtoReflect())
return
}
func ( UnmarshalOptions) ( protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
if .RecursionLimit == 0 {
.RecursionLimit = protowire.DefaultRecursionLimit
}
return .unmarshal(.Buf, .Message)
}
func ( UnmarshalOptions) ( []byte, protoreflect.Message) ( protoiface.UnmarshalOutput, error) {
if .Resolver == nil {
.Resolver = protoregistry.GlobalTypes
}
if !.Merge {
Reset(.Interface())
}
:= .AllowPartial
.Merge = true
.AllowPartial = true
:= protoMethods()
if != nil && .Unmarshal != nil &&
!(.DiscardUnknown && .Flags&protoiface.SupportUnmarshalDiscardUnknown == 0) {
:= protoiface.UnmarshalInput{
Message: ,
Buf: ,
Resolver: .Resolver,
Depth: .RecursionLimit,
}
if .DiscardUnknown {
.Flags |= protoiface.UnmarshalDiscardUnknown
}
, = .Unmarshal()
} else {
.RecursionLimit--
if .RecursionLimit < 0 {
return , errors.New("exceeded max recursion depth")
}
= .unmarshalMessageSlow(, )
}
if != nil {
return ,
}
if || (.Flags&protoiface.UnmarshalInitialized != 0) {
return , nil
}
return , checkInitialized()
}
func ( UnmarshalOptions) ( []byte, protoreflect.Message) error {
, := .unmarshal(, )
return
}
func ( UnmarshalOptions) ( []byte, protoreflect.Message) error {
:= .Descriptor()
if messageset.IsMessageSet() {
return .unmarshalMessageSet(, )
}
:= .Fields()
for len() > 0 {
, , := protowire.ConsumeTag()
if < 0 {
return errDecode
}
if > protowire.MaxValidNumber {
return errDecode
}
:= .ByNumber()
if == nil && .ExtensionRanges().Has() {
, := .Resolver.FindExtensionByNumber(.FullName(), )
if != nil && != protoregistry.NotFound {
return errors.New("%v: unable to resolve extension %v: %v", .FullName(), , )
}
if != nil {
= .TypeDescriptor()
}
}
var error
if == nil {
= errUnknown
} else if flags.ProtoLegacy {
if .IsWeak() && .Message().IsPlaceholder() {
= errUnknown
}
}
var int
switch {
case != nil:
case .IsList():
, = .unmarshalList([:], , .Mutable().List(), )
case .IsMap():
, = .unmarshalMap([:], , .Mutable().Map(), )
default:
, = .unmarshalSingular([:], , , )
}
if != nil {
if != errUnknown {
return
}
= protowire.ConsumeFieldValue(, , [:])
if < 0 {
return errDecode
}
if !.DiscardUnknown {
.SetUnknown(append(.GetUnknown(), [:+]...))
}
}
= [+:]
}
return nil
}
func ( UnmarshalOptions) ( []byte, protowire.Type, protoreflect.Message, protoreflect.FieldDescriptor) ( int, error) {
, , := .unmarshalScalar(, , )
if != nil {
return 0,
}
switch .Kind() {
case protoreflect.GroupKind, protoreflect.MessageKind:
:= .Mutable().Message()
if := .unmarshalMessage(.Bytes(), ); != nil {
return ,
}
default:
.Set(, )
}
return , nil
}
func ( UnmarshalOptions) ( []byte, protowire.Type, protoreflect.Map, protoreflect.FieldDescriptor) ( int, error) {
if != protowire.BytesType {
return 0, errUnknown
}
, = protowire.ConsumeBytes()
if < 0 {
return 0, errDecode
}
var (
= .MapKey()
= .MapValue()
protoreflect.Value
protoreflect.Value
bool
bool
)
switch .Kind() {
case protoreflect.GroupKind, protoreflect.MessageKind:
= .NewValue()
}
for len() > 0 {
, , := protowire.ConsumeTag()
if < 0 {
return 0, errDecode
}
if > protowire.MaxValidNumber {
return 0, errDecode
}
= [:]
= errUnknown
switch {
case genid.MapEntry_Key_field_number:
, , = .unmarshalScalar(, , )
if != nil {
break
}
= true
case genid.MapEntry_Value_field_number:
var protoreflect.Value
, , = .unmarshalScalar(, , )
if != nil {
break
}
switch .Kind() {
case protoreflect.GroupKind, protoreflect.MessageKind:
if := .unmarshalMessage(.Bytes(), .Message()); != nil {
return 0,
}
default:
=
}
= true
}
if == errUnknown {
= protowire.ConsumeFieldValue(, , )
if < 0 {
return 0, errDecode
}
} else if != nil {
return 0,
}
= [:]
}
if ! {
= .Default()
}
if ! {
switch .Kind() {
case protoreflect.GroupKind, protoreflect.MessageKind:
default:
= .Default()
}
}
.Set(.MapKey(), )
return , nil
}
var errUnknown = errors.New("BUG: internal error (unknown)")
var errDecode = errors.New("cannot parse invalid wire-format data")