// 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 filedesc

import (
	"reflect"
	"sync"

	"google.golang.org/protobuf/internal/descopts"
	"google.golang.org/protobuf/internal/encoding/wire"
	"google.golang.org/protobuf/internal/fieldnum"
	"google.golang.org/protobuf/proto"
	pref "google.golang.org/protobuf/reflect/protoreflect"
)

func (fd *File) lazyRawInit() {
	fd.unmarshalFull(fd.builder.RawDescriptor)
	fd.resolveMessages()
	fd.resolveExtensions()
	fd.resolveServices()
}

func (file *File) resolveMessages() {
	var depIdx int32
	for i := range file.allMessages {
		md := &file.allMessages[i]

		// Resolve message field dependencies.
		for j := range md.L2.Fields.List {
			fd := &md.L2.Fields.List[j]

			// Weak fields are only resolved by name.
			if fd.L1.IsWeak {
				r := file.builder.FileRegistry
				if d, _ := r.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
					fd.L1.Message = d.(pref.MessageDescriptor)
				}
				continue
			}

			// Resolve message field dependency.
			switch fd.L1.Kind {
			case pref.EnumKind:
				fd.L1.Enum = file.resolveEnumDependency(fd.L1.Enum, listFieldDeps, depIdx)
				depIdx++
			case pref.MessageKind, pref.GroupKind:
				fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx)
				depIdx++
			}

			// Default is resolved here since it depends on Enum being resolved.
			if v := fd.L1.Default.val; v.IsValid() {
				fd.L1.Default = unmarshalDefault(v.Bytes(), fd.L1.Kind, file, fd.L1.Enum)
			}
		}
	}
}

func (file *File) resolveExtensions() {
	var depIdx int32
	for i := range file.allExtensions {
		xd := &file.allExtensions[i]

		// Resolve extension field dependency.
		switch xd.L1.Kind {
		case pref.EnumKind:
			xd.L2.Enum = file.resolveEnumDependency(xd.L2.Enum, listExtDeps, depIdx)
			depIdx++
		case pref.MessageKind, pref.GroupKind:
			xd.L2.Message = file.resolveMessageDependency(xd.L2.Message, listExtDeps, depIdx)
			depIdx++
		}

		// Default is resolved here since it depends on Enum being resolved.
		if v := xd.L2.Default.val; v.IsValid() {
			xd.L2.Default = unmarshalDefault(v.Bytes(), xd.L1.Kind, file, xd.L2.Enum)
		}
	}
}

func (file *File) resolveServices() {
	var depIdx int32
	for i := range file.allServices {
		sd := &file.allServices[i]

		// Resolve method dependencies.
		for j := range sd.L2.Methods.List {
			md := &sd.L2.Methods.List[j]
			md.L1.Input = file.resolveMessageDependency(md.L1.Input, listMethInDeps, depIdx)
			md.L1.Output = file.resolveMessageDependency(md.L1.Output, listMethOutDeps, depIdx)
			depIdx++
		}
	}
}

func (file *File) resolveEnumDependency(ed pref.EnumDescriptor, i, j int32) pref.EnumDescriptor {
	r := file.builder.FileRegistry
	if r, ok := r.(resolverByIndex); ok {
		if ed2 := r.FindEnumByIndex(i, j, file.allEnums, file.allMessages); ed2 != nil {
			return ed2
		}
	}
	for i := range file.allEnums {
		if ed2 := &file.allEnums[i]; ed2.L0.FullName == ed.FullName() {
			return ed2
		}
	}
	if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil {
		return d.(pref.EnumDescriptor)
	}
	return ed
}

func (file *File) resolveMessageDependency(md pref.MessageDescriptor, i, j int32) pref.MessageDescriptor {
	r := file.builder.FileRegistry
	if r, ok := r.(resolverByIndex); ok {
		if md2 := r.FindMessageByIndex(i, j, file.allEnums, file.allMessages); md2 != nil {
			return md2
		}
	}
	for i := range file.allMessages {
		if md2 := &file.allMessages[i]; md2.L0.FullName == md.FullName() {
			return md2
		}
	}
	if d, _ := r.FindDescriptorByName(md.FullName()); d != nil {
		return d.(pref.MessageDescriptor)
	}
	return md
}

func (fd *File) unmarshalFull(b []byte) {
	nb := getNameBuilder()
	defer putNameBuilder(nb)

	var enumIdx, messageIdx, extensionIdx, serviceIdx int
	var rawOptions []byte
	fd.L2 = new(FileL2)
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.VarintType:
			v, m := wire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.FileDescriptorProto_PublicDependency:
				fd.L2.Imports[v].IsPublic = true
			case fieldnum.FileDescriptorProto_WeakDependency:
				fd.L2.Imports[v].IsWeak = true
			}
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.FileDescriptorProto_Dependency:
				path := nb.MakeString(v)
				imp, _ := fd.builder.FileRegistry.FindFileByPath(path)
				if imp == nil {
					imp = PlaceholderFile(path)
				}
				fd.L2.Imports = append(fd.L2.Imports, pref.FileImport{FileDescriptor: imp})
			case fieldnum.FileDescriptorProto_EnumType:
				fd.L1.Enums.List[enumIdx].unmarshalFull(v, nb)
				enumIdx++
			case fieldnum.FileDescriptorProto_MessageType:
				fd.L1.Messages.List[messageIdx].unmarshalFull(v, nb)
				messageIdx++
			case fieldnum.FileDescriptorProto_Extension:
				fd.L1.Extensions.List[extensionIdx].unmarshalFull(v, nb)
				extensionIdx++
			case fieldnum.FileDescriptorProto_Service:
				fd.L1.Services.List[serviceIdx].unmarshalFull(v, nb)
				serviceIdx++
			case fieldnum.FileDescriptorProto_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	fd.L2.Options = fd.builder.optionsUnmarshaler(descopts.File, rawOptions)
}

func (ed *Enum) unmarshalFull(b []byte, nb *nameBuilder) {
	var rawValues [][]byte
	var rawOptions []byte
	if !ed.L1.eagerValues {
		ed.L2 = new(EnumL2)
	}
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.EnumDescriptorProto_Value:
				rawValues = append(rawValues, v)
			case fieldnum.EnumDescriptorProto_ReservedName:
				ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, pref.Name(nb.MakeString(v)))
			case fieldnum.EnumDescriptorProto_ReservedRange:
				ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v))
			case fieldnum.EnumDescriptorProto_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	if !ed.L1.eagerValues && len(rawValues) > 0 {
		ed.L2.Values.List = make([]EnumValue, len(rawValues))
		for i, b := range rawValues {
			ed.L2.Values.List[i].unmarshalFull(b, nb, ed.L0.ParentFile, ed, i)
		}
	}
	ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(descopts.Enum, rawOptions)
}

func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) {
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.VarintType:
			v, m := wire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.EnumDescriptorProto_EnumReservedRange_Start:
				r[0] = pref.EnumNumber(v)
			case fieldnum.EnumDescriptorProto_EnumReservedRange_End:
				r[1] = pref.EnumNumber(v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	return r
}

func (vd *EnumValue) unmarshalFull(b []byte, nb *nameBuilder, pf *File, pd pref.Descriptor, i int) {
	vd.L0.ParentFile = pf
	vd.L0.Parent = pd
	vd.L0.Index = i

	var rawOptions []byte
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.VarintType:
			v, m := wire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.EnumValueDescriptorProto_Number:
				vd.L1.Number = pref.EnumNumber(v)
			}
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.EnumValueDescriptorProto_Name:
				// NOTE: Enum values are in the same scope as the enum parent.
				vd.L0.FullName = nb.AppendFullName(pd.Parent().FullName(), v)
			case fieldnum.EnumValueDescriptorProto_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	vd.L1.Options = pf.builder.optionsUnmarshaler(descopts.EnumValue, rawOptions)
}

func (md *Message) unmarshalFull(b []byte, nb *nameBuilder) {
	var rawFields, rawOneofs [][]byte
	var enumIdx, messageIdx, extensionIdx int
	var rawOptions []byte
	md.L2 = new(MessageL2)
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.DescriptorProto_Field:
				rawFields = append(rawFields, v)
			case fieldnum.DescriptorProto_OneofDecl:
				rawOneofs = append(rawOneofs, v)
			case fieldnum.DescriptorProto_ReservedName:
				md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, pref.Name(nb.MakeString(v)))
			case fieldnum.DescriptorProto_ReservedRange:
				md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v))
			case fieldnum.DescriptorProto_ExtensionRange:
				r, rawOptions := unmarshalMessageExtensionRange(v)
				opts := md.L0.ParentFile.builder.optionsUnmarshaler(descopts.ExtensionRange, rawOptions)
				md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, r)
				md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, opts)
			case fieldnum.DescriptorProto_EnumType:
				md.L1.Enums.List[enumIdx].unmarshalFull(v, nb)
				enumIdx++
			case fieldnum.DescriptorProto_NestedType:
				md.L1.Messages.List[messageIdx].unmarshalFull(v, nb)
				messageIdx++
			case fieldnum.DescriptorProto_Extension:
				md.L1.Extensions.List[extensionIdx].unmarshalFull(v, nb)
				extensionIdx++
			case fieldnum.DescriptorProto_Options:
				md.unmarshalOptions(v)
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	if len(rawFields) > 0 || len(rawOneofs) > 0 {
		md.L2.Fields.List = make([]Field, len(rawFields))
		md.L2.Oneofs.List = make([]Oneof, len(rawOneofs))
		for i, b := range rawFields {
			fd := &md.L2.Fields.List[i]
			fd.unmarshalFull(b, nb, md.L0.ParentFile, md, i)
			if fd.L1.Cardinality == pref.Required {
				md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number)
			}
		}
		for i, b := range rawOneofs {
			od := &md.L2.Oneofs.List[i]
			od.unmarshalFull(b, nb, md.L0.ParentFile, md, i)
		}
	}
	md.L2.Options = md.L0.ParentFile.builder.optionsUnmarshaler(descopts.Message, rawOptions)
}

func (md *Message) unmarshalOptions(b []byte) {
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.VarintType:
			v, m := wire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.MessageOptions_MapEntry:
				md.L2.IsMapEntry = wire.DecodeBool(v)
			case fieldnum.MessageOptions_MessageSetWireFormat:
				md.L2.IsMessageSet = wire.DecodeBool(v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
}

func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) {
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.VarintType:
			v, m := wire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.DescriptorProto_ReservedRange_Start:
				r[0] = pref.FieldNumber(v)
			case fieldnum.DescriptorProto_ReservedRange_End:
				r[1] = pref.FieldNumber(v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	return r
}

func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions []byte) {
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.VarintType:
			v, m := wire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.DescriptorProto_ExtensionRange_Start:
				r[0] = pref.FieldNumber(v)
			case fieldnum.DescriptorProto_ExtensionRange_End:
				r[1] = pref.FieldNumber(v)
			}
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.DescriptorProto_ExtensionRange_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	return r, rawOptions
}

func (fd *Field) unmarshalFull(b []byte, nb *nameBuilder, pf *File, pd pref.Descriptor, i int) {
	fd.L0.ParentFile = pf
	fd.L0.Parent = pd
	fd.L0.Index = i

	var rawTypeName []byte
	var rawOptions []byte
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.VarintType:
			v, m := wire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldDescriptorProto_Number:
				fd.L1.Number = pref.FieldNumber(v)
			case fieldnum.FieldDescriptorProto_Label:
				fd.L1.Cardinality = pref.Cardinality(v)
			case fieldnum.FieldDescriptorProto_Type:
				fd.L1.Kind = pref.Kind(v)
			case fieldnum.FieldDescriptorProto_OneofIndex:
				// In Message.unmarshalFull, we allocate slices for both
				// the field and oneof descriptors before unmarshaling either
				// of them. This ensures pointers to slice elements are stable.
				od := &pd.(*Message).L2.Oneofs.List[v]
				od.L1.Fields.List = append(od.L1.Fields.List, fd)
				if fd.L1.ContainingOneof != nil {
					panic("oneof type already set")
				}
				fd.L1.ContainingOneof = od
			}
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldDescriptorProto_Name:
				fd.L0.FullName = nb.AppendFullName(pd.FullName(), v)
			case fieldnum.FieldDescriptorProto_JsonName:
				fd.L1.JSONName = JSONName(nb.MakeString(v))
			case fieldnum.FieldDescriptorProto_DefaultValue:
				fd.L1.Default.val = pref.ValueOf(v) // temporarily store as bytes; later resolved in resolveMessages
			case fieldnum.FieldDescriptorProto_TypeName:
				rawTypeName = v
			case fieldnum.FieldDescriptorProto_Options:
				fd.unmarshalOptions(v)
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	if rawTypeName != nil {
		name := nb.MakeFullName(rawTypeName)
		switch fd.L1.Kind {
		case pref.EnumKind:
			fd.L1.Enum = PlaceholderEnum(name)
		case pref.MessageKind, pref.GroupKind:
			fd.L1.Message = PlaceholderMessage(name)
		}
	}
	fd.L1.Options = pf.builder.optionsUnmarshaler(descopts.Field, rawOptions)
}

func (fd *Field) unmarshalOptions(b []byte) {
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.VarintType:
			v, m := wire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldOptions_Packed:
				fd.L1.HasPacked = true
				fd.L1.IsPacked = wire.DecodeBool(v)
			case fieldnum.FieldOptions_Weak:
				fd.L1.IsWeak = wire.DecodeBool(v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
}

func (od *Oneof) unmarshalFull(b []byte, nb *nameBuilder, pf *File, pd pref.Descriptor, i int) {
	od.L0.ParentFile = pf
	od.L0.Parent = pd
	od.L0.Index = i

	var rawOptions []byte
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.OneofDescriptorProto_Name:
				od.L0.FullName = nb.AppendFullName(pd.FullName(), v)
			case fieldnum.OneofDescriptorProto_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	od.L1.Options = pf.builder.optionsUnmarshaler(descopts.Oneof, rawOptions)
}

func (xd *Extension) unmarshalFull(b []byte, nb *nameBuilder) {
	var rawTypeName []byte
	var rawOptions []byte
	xd.L2 = new(ExtensionL2)
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.VarintType:
			v, m := wire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldDescriptorProto_Label:
				xd.L2.Cardinality = pref.Cardinality(v)
			}
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldDescriptorProto_JsonName:
				xd.L2.JSONName = JSONName(nb.MakeString(v))
			case fieldnum.FieldDescriptorProto_DefaultValue:
				xd.L2.Default.val = pref.ValueOf(v) // temporarily store as bytes; later resolved in resolveExtensions
			case fieldnum.FieldDescriptorProto_TypeName:
				rawTypeName = v
			case fieldnum.FieldDescriptorProto_Options:
				xd.unmarshalOptions(v)
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	if rawTypeName != nil {
		name := nb.MakeFullName(rawTypeName)
		switch xd.L1.Kind {
		case pref.EnumKind:
			xd.L2.Enum = PlaceholderEnum(name)
		case pref.MessageKind, pref.GroupKind:
			xd.L2.Message = PlaceholderMessage(name)
		}
	}
	xd.L2.Options = xd.L0.ParentFile.builder.optionsUnmarshaler(descopts.Field, rawOptions)
}

func (xd *Extension) unmarshalOptions(b []byte) {
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.VarintType:
			v, m := wire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldOptions_Packed:
				xd.L2.IsPacked = wire.DecodeBool(v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
}

func (sd *Service) unmarshalFull(b []byte, nb *nameBuilder) {
	var rawMethods [][]byte
	var rawOptions []byte
	sd.L2 = new(ServiceL2)
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.ServiceDescriptorProto_Method:
				rawMethods = append(rawMethods, v)
			case fieldnum.ServiceDescriptorProto_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	if len(rawMethods) > 0 {
		sd.L2.Methods.List = make([]Method, len(rawMethods))
		for i, b := range rawMethods {
			sd.L2.Methods.List[i].unmarshalFull(b, nb, sd.L0.ParentFile, sd, i)
		}
	}
	sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(descopts.Service, rawOptions)
}

func (md *Method) unmarshalFull(b []byte, nb *nameBuilder, pf *File, pd pref.Descriptor, i int) {
	md.L0.ParentFile = pf
	md.L0.Parent = pd
	md.L0.Index = i

	var rawOptions []byte
	for len(b) > 0 {
		num, typ, n := wire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case wire.VarintType:
			v, m := wire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.MethodDescriptorProto_ClientStreaming:
				md.L1.IsStreamingClient = wire.DecodeBool(v)
			case fieldnum.MethodDescriptorProto_ServerStreaming:
				md.L1.IsStreamingServer = wire.DecodeBool(v)
			}
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.MethodDescriptorProto_Name:
				md.L0.FullName = nb.AppendFullName(pd.FullName(), v)
			case fieldnum.MethodDescriptorProto_InputType:
				md.L1.Input = PlaceholderMessage(nb.MakeFullName(v))
			case fieldnum.MethodDescriptorProto_OutputType:
				md.L1.Output = PlaceholderMessage(nb.MakeFullName(v))
			case fieldnum.MethodDescriptorProto_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	md.L1.Options = pf.builder.optionsUnmarshaler(descopts.Method, rawOptions)
}

// appendOptions appends src to dst, where the returned slice is never nil.
// This is necessary to distinguish between empty and unpopulated options.
func appendOptions(dst, src []byte) []byte {
	if dst == nil {
		dst = []byte{}
	}
	return append(dst, src...)
}

func (db *DescBuilder) optionsUnmarshaler(p pref.ProtoMessage, b []byte) func() pref.ProtoMessage {
	if b == nil {
		return nil
	}
	var opts pref.ProtoMessage
	var once sync.Once
	return func() pref.ProtoMessage {
		once.Do(func() {
			opts = reflect.New(reflect.TypeOf(p).Elem()).Interface().(pref.ProtoMessage)
			if err := (proto.UnmarshalOptions{
				AllowPartial: true,
				Resolver:     db.TypeResolver,
			}).Unmarshal(b, opts); err != nil {
				panic(err)
			}
		})
		return opts
	}
}
