// 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/encoding/protowire"
	"google.golang.org/protobuf/internal/descopts"
	"google.golang.org/protobuf/internal/fieldnum"
	"google.golang.org/protobuf/internal/strs"
	"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 resolved upon actual use.
			if fd.L1.IsWeak {
				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) {
	sb := getBuilder()
	defer putBuilder(sb)

	var enumIdx, messageIdx, extensionIdx, serviceIdx int
	var rawOptions []byte
	fd.L2 = new(FileL2)
	for len(b) > 0 {
		num, typ, n := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.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 protowire.BytesType:
			v, m := protowire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.FileDescriptorProto_Dependency:
				path := sb.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, sb)
				enumIdx++
			case fieldnum.FileDescriptorProto_MessageType:
				fd.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
				messageIdx++
			case fieldnum.FileDescriptorProto_Extension:
				fd.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
				extensionIdx++
			case fieldnum.FileDescriptorProto_Service:
				fd.L1.Services.List[serviceIdx].unmarshalFull(v, sb)
				serviceIdx++
			case fieldnum.FileDescriptorProto_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := protowire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	fd.L2.Options = fd.builder.optionsUnmarshaler(&descopts.File, rawOptions)
}

func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) {
	var rawValues [][]byte
	var rawOptions []byte
	if !ed.L1.eagerValues {
		ed.L2 = new(EnumL2)
	}
	for len(b) > 0 {
		num, typ, n := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.BytesType:
			v, m := protowire.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(sb.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 := protowire.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, sb, 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 := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.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 := protowire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	return r
}

func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, 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 := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.EnumValueDescriptorProto_Number:
				vd.L1.Number = pref.EnumNumber(v)
			}
		case protowire.BytesType:
			v, m := protowire.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 = appendFullName(sb, pd.Parent().FullName(), v)
			case fieldnum.EnumValueDescriptorProto_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := protowire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	vd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.EnumValue, rawOptions)
}

func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) {
	var rawFields, rawOneofs [][]byte
	var enumIdx, messageIdx, extensionIdx int
	var rawOptions []byte
	md.L2 = new(MessageL2)
	for len(b) > 0 {
		num, typ, n := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.BytesType:
			v, m := protowire.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(sb.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, sb)
				enumIdx++
			case fieldnum.DescriptorProto_NestedType:
				md.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
				messageIdx++
			case fieldnum.DescriptorProto_Extension:
				md.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
				extensionIdx++
			case fieldnum.DescriptorProto_Options:
				md.unmarshalOptions(v)
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := protowire.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, sb, 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, sb, 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 := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.MessageOptions_MapEntry:
				md.L1.IsMapEntry = protowire.DecodeBool(v)
			case fieldnum.MessageOptions_MessageSetWireFormat:
				md.L1.IsMessageSet = protowire.DecodeBool(v)
			}
		default:
			m := protowire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
}

func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) {
	for len(b) > 0 {
		num, typ, n := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.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 := protowire.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 := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.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 protowire.BytesType:
			v, m := protowire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.DescriptorProto_ExtensionRange_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := protowire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	return r, rawOptions
}

func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, 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 := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.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 protowire.BytesType:
			v, m := protowire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldDescriptorProto_Name:
				fd.L0.FullName = appendFullName(sb, pd.FullName(), v)
			case fieldnum.FieldDescriptorProto_JsonName:
				fd.L1.JSONName.Init(sb.MakeString(v))
			case fieldnum.FieldDescriptorProto_DefaultValue:
				fd.L1.Default.val = pref.ValueOfBytes(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 := protowire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	if rawTypeName != nil {
		name := makeFullName(sb, 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) {
	const FieldOptions_EnforceUTF8 = 13

	for len(b) > 0 {
		num, typ, n := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldOptions_Packed:
				fd.L1.HasPacked = true
				fd.L1.IsPacked = protowire.DecodeBool(v)
			case fieldnum.FieldOptions_Weak:
				fd.L1.IsWeak = protowire.DecodeBool(v)
			case FieldOptions_EnforceUTF8:
				fd.L1.HasEnforceUTF8 = true
				fd.L1.EnforceUTF8 = protowire.DecodeBool(v)
			}
		default:
			m := protowire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
}

func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, 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 := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.BytesType:
			v, m := protowire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.OneofDescriptorProto_Name:
				od.L0.FullName = appendFullName(sb, pd.FullName(), v)
			case fieldnum.OneofDescriptorProto_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := protowire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	od.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Oneof, rawOptions)
}

func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
	var rawTypeName []byte
	var rawOptions []byte
	xd.L2 = new(ExtensionL2)
	for len(b) > 0 {
		num, typ, n := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.BytesType:
			v, m := protowire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldDescriptorProto_JsonName:
				xd.L2.JSONName.Init(sb.MakeString(v))
			case fieldnum.FieldDescriptorProto_DefaultValue:
				xd.L2.Default.val = pref.ValueOfBytes(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 := protowire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	if rawTypeName != nil {
		name := makeFullName(sb, 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 := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldOptions_Packed:
				xd.L2.IsPacked = protowire.DecodeBool(v)
			}
		default:
			m := protowire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
}

func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) {
	var rawMethods [][]byte
	var rawOptions []byte
	sd.L2 = new(ServiceL2)
	for len(b) > 0 {
		num, typ, n := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.BytesType:
			v, m := protowire.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 := protowire.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, sb, sd.L0.ParentFile, sd, i)
		}
	}
	sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Service, rawOptions)
}

func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, 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 := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case fieldnum.MethodDescriptorProto_ClientStreaming:
				md.L1.IsStreamingClient = protowire.DecodeBool(v)
			case fieldnum.MethodDescriptorProto_ServerStreaming:
				md.L1.IsStreamingServer = protowire.DecodeBool(v)
			}
		case protowire.BytesType:
			v, m := protowire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.MethodDescriptorProto_Name:
				md.L0.FullName = appendFullName(sb, pd.FullName(), v)
			case fieldnum.MethodDescriptorProto_InputType:
				md.L1.Input = PlaceholderMessage(makeFullName(sb, v))
			case fieldnum.MethodDescriptorProto_OutputType:
				md.L1.Output = PlaceholderMessage(makeFullName(sb, v))
			case fieldnum.MethodDescriptorProto_Options:
				rawOptions = appendOptions(rawOptions, v)
			}
		default:
			m := protowire.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...)
}

// optionsUnmarshaler constructs a lazy unmarshal function for an options message.
//
// The type of message to unmarshal to is passed as a pointer since the
// vars in descopts may not yet be populated at the time this function is called.
func (db *Builder) 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() {
			if *p == nil {
				panic("Descriptor.Options called without importing the descriptor package")
			}
			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
	}
}
