// Copyright 2018 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 fileinit

import (
	"bytes"
	"fmt"
	"reflect"

	defval "github.com/golang/protobuf/v2/internal/encoding/defval"
	wire "github.com/golang/protobuf/v2/internal/encoding/wire"
	fieldnum "github.com/golang/protobuf/v2/internal/fieldnum"
	pimpl "github.com/golang/protobuf/v2/internal/impl"
	ptype "github.com/golang/protobuf/v2/internal/prototype"
	pvalue "github.com/golang/protobuf/v2/internal/value"
	pref "github.com/golang/protobuf/v2/reflect/protoreflect"
)

func (file *fileDesc) lazyInit() *fileLazy {
	file.once.Do(func() {
		file.unmarshalFull(file.RawDescriptor)
		file.resolveImports()
		file.resolveEnums()
		file.resolveMessages()
		file.resolveExtensions()
		file.resolveServices()
		file.finishInit()
	})
	return file.lazy
}

func (file *fileDesc) resolveImports() {
	// TODO: Resolve file dependencies.
}

func (file *fileDesc) resolveEnums() {
	enumDecls := file.GoTypes[:len(file.allEnums)]
	for i := range file.allEnums {
		ed := &file.allEnums[i]

		// Associate the EnumType with a concrete Go type.
		enumCache := map[pref.EnumNumber]pref.Enum{}
		ed.lazy.typ = reflect.TypeOf(enumDecls[i])
		ed.lazy.new = func(n pref.EnumNumber) pref.Enum {
			if v, ok := enumCache[n]; ok {
				return v
			}
			v := reflect.New(ed.lazy.typ).Elem()
			v.SetInt(int64(n))
			return v.Interface().(pref.Enum)
		}
		for i := range ed.lazy.values.list {
			n := ed.lazy.values.list[i].number
			enumCache[n] = ed.lazy.new(n)
		}
	}
}

func (file *fileDesc) resolveMessages() {
	messageDecls := file.GoTypes[len(file.allEnums):]
	for i := range file.allMessages {
		md := &file.allMessages[i]

		// Associate the MessageType with a concrete Go type.
		if !md.isMapEntry {
			md.lazy.typ = reflect.TypeOf(messageDecls[i])
			md.lazy.new = func() pref.Message {
				t := md.lazy.typ.Elem()
				return reflect.New(t).Interface().(pref.ProtoMessage).ProtoReflect()
			}
		}

		// Resolve message field dependencies.
		for j := range md.lazy.fields.list {
			fd := &md.lazy.fields.list[j]
			if fd.isWeak {
				continue
			}

			switch fd.kind {
			case pref.EnumKind:
				fd.enumType = file.popEnumDependency()
			case pref.MessageKind, pref.GroupKind:
				fd.messageType = file.popMessageDependency()
			}
			fd.isMap = file.isMapEntry(fd.messageType)
			if !fd.hasPacked && file.lazy.syntax != pref.Proto2 && fd.cardinality == pref.Repeated {
				switch fd.kind {
				case pref.StringKind, pref.BytesKind, pref.MessageKind, pref.GroupKind:
					fd.isPacked = false
				default:
					fd.isPacked = true
				}
			}
			fd.defVal.lazyInit(fd.kind, file.enumValuesOf(fd.enumType))
		}
	}
}

func (file *fileDesc) resolveExtensions() {
	for i := range file.allExtensions {
		xd := &file.allExtensions[i]

		// Associate the ExtensionType with a concrete Go type.
		var typ reflect.Type
		switch xd.lazy.kind {
		case pref.EnumKind, pref.MessageKind, pref.GroupKind:
			typ = reflect.TypeOf(file.GoTypes[file.DependencyIndexes[0]])
		default:
			typ = goTypeForPBKind[xd.lazy.kind]
		}
		switch xd.lazy.cardinality {
		case pref.Optional:
			switch xd.lazy.kind {
			case pref.EnumKind:
				xd.lazy.typ = typ
				xd.lazy.new = func() pref.Value {
					return xd.lazy.defVal.get()
				}
				xd.lazy.valueOf = func(v interface{}) pref.Value {
					ev := v.(pref.Enum)
					return pref.ValueOf(ev.Number())
				}
				xd.lazy.interfaceOf = func(pv pref.Value) interface{} {
					return xd.lazy.enumType.New(pv.Enum())
				}
			case pref.MessageKind, pref.GroupKind:
				xd.lazy.typ = typ
				xd.lazy.new = func() pref.Value {
					return pref.ValueOf(xd.lazy.messageType.New())
				}
				xd.lazy.valueOf = func(v interface{}) pref.Value {
					mv := v.(pref.ProtoMessage).ProtoReflect()
					return pref.ValueOf(mv)
				}
				xd.lazy.interfaceOf = func(pv pref.Value) interface{} {
					return pv.Message().Interface()
				}
			default:
				xd.lazy.typ = goTypeForPBKind[xd.lazy.kind]
				xd.lazy.new = func() pref.Value {
					return xd.lazy.defVal.get()
				}
				xd.lazy.valueOf = func(v interface{}) pref.Value {
					return pref.ValueOf(v)
				}
				xd.lazy.interfaceOf = func(pv pref.Value) interface{} {
					return pv.Interface()
				}
			}
		case pref.Repeated:
			c := pvalue.NewConverter(typ, xd.lazy.kind)
			xd.lazy.typ = reflect.PtrTo(reflect.SliceOf(typ))
			xd.lazy.new = func() pref.Value {
				v := reflect.New(xd.lazy.typ.Elem()).Interface()
				return pref.ValueOf(pvalue.ListOf(v, c))
			}
			xd.lazy.valueOf = func(v interface{}) pref.Value {
				return pref.ValueOf(pvalue.ListOf(v, c))
			}
			xd.lazy.interfaceOf = func(pv pref.Value) interface{} {
				return pv.List().(pvalue.Unwrapper).ProtoUnwrap()
			}
		default:
			panic(fmt.Sprintf("invalid cardinality: %v", xd.lazy.cardinality))
		}

		// Resolve extension field dependency.
		switch xd.lazy.kind {
		case pref.EnumKind:
			xd.lazy.enumType = file.popEnumDependency().(pref.EnumType)
		case pref.MessageKind, pref.GroupKind:
			xd.lazy.messageType = file.popMessageDependency().(pref.MessageType)
		}
		xd.lazy.defVal.lazyInit(xd.lazy.kind, file.enumValuesOf(xd.lazy.enumType))
	}
}

var goTypeForPBKind = map[pref.Kind]reflect.Type{
	pref.BoolKind:     reflect.TypeOf(bool(false)),
	pref.Int32Kind:    reflect.TypeOf(int32(0)),
	pref.Sint32Kind:   reflect.TypeOf(int32(0)),
	pref.Sfixed32Kind: reflect.TypeOf(int32(0)),
	pref.Int64Kind:    reflect.TypeOf(int64(0)),
	pref.Sint64Kind:   reflect.TypeOf(int64(0)),
	pref.Sfixed64Kind: reflect.TypeOf(int64(0)),
	pref.Uint32Kind:   reflect.TypeOf(uint32(0)),
	pref.Fixed32Kind:  reflect.TypeOf(uint32(0)),
	pref.Uint64Kind:   reflect.TypeOf(uint64(0)),
	pref.Fixed64Kind:  reflect.TypeOf(uint64(0)),
	pref.FloatKind:    reflect.TypeOf(float32(0)),
	pref.DoubleKind:   reflect.TypeOf(float64(0)),
	pref.StringKind:   reflect.TypeOf(string("")),
	pref.BytesKind:    reflect.TypeOf([]byte(nil)),
}

func (file *fileDesc) resolveServices() {
	for i := range file.services.list {
		sd := &file.services.list[i]

		// Resolve method dependencies.
		for j := range sd.lazy.methods.list {
			md := &sd.lazy.methods.list[j]
			md.inputType = file.popMessageDependency()
			md.outputType = file.popMessageDependency()
		}
	}
}

// isMapEntry reports whether the message is a map entry, being careful to
// avoid calling the IsMapEntry method if the message is declared
// within the same file (which would cause a recursive init deadlock).
func (fd *fileDesc) isMapEntry(md pref.MessageDescriptor) bool {
	if md == nil {
		return false
	}
	if md, ok := md.(*messageDescriptor); ok && md.parentFile == fd {
		return md.isMapEntry
	}
	return md.IsMapEntry()
}

// enumValuesOf retrieves the list of enum values for the given enum,
// being careful to avoid calling the Values method if the enum is declared
// within the same file (which would cause a recursive init deadlock).
func (fd *fileDesc) enumValuesOf(ed pref.EnumDescriptor) pref.EnumValueDescriptors {
	if ed == nil {
		return nil
	}
	if ed, ok := ed.(*enumDesc); ok && ed.parentFile == fd {
		return &ed.lazy.values
	}
	return ed.Values()
}

func (fd *fileDesc) popEnumDependency() pref.EnumDescriptor {
	depIdx := fd.popDependencyIndex()
	if depIdx < len(fd.allEnums)+len(fd.allMessages) {
		return &fd.allEnums[depIdx]
	} else {
		return pimpl.Export{}.EnumTypeOf(fd.GoTypes[depIdx])
	}
}

func (fd *fileDesc) popMessageDependency() pref.MessageDescriptor {
	depIdx := fd.popDependencyIndex()
	if depIdx < len(fd.allEnums)+len(fd.allMessages) {
		return fd.allMessages[depIdx-len(fd.allEnums)].asDesc()
	} else {
		return pimpl.Export{}.MessageTypeOf(fd.GoTypes[depIdx])
	}
}

func (fi *fileInit) popDependencyIndex() int {
	depIdx := fi.DependencyIndexes[0]
	fi.DependencyIndexes = fi.DependencyIndexes[1:]
	return int(depIdx)
}

func (fi *fileInit) finishInit() {
	if len(fi.DependencyIndexes) > 0 {
		panic("unused dependencies")
	}
	*fi = fileInit{} // clear fileInit for GC to reclaim resources
}

type defaultValue struct {
	has   bool
	val   pref.Value
	enum  pref.EnumValueDescriptor
	check func() // only set for non-empty bytes
}

func (dv *defaultValue) get() pref.Value {
	if dv.check != nil {
		dv.check()
	}
	return dv.val
}

func (dv *defaultValue) lazyInit(k pref.Kind, eds pref.EnumValueDescriptors) {
	if dv.has {
		switch k {
		case pref.EnumKind:
			// File descriptors always store default enums by name.
			dv.enum = eds.ByName(pref.Name(dv.val.String()))
			dv.val = pref.ValueOf(dv.enum.Number())
		case pref.BytesKind:
			// Store a copy of the default bytes, so that we can detect
			// accidental mutations of the original value.
			b := append([]byte(nil), dv.val.Bytes()...)
			dv.check = func() {
				if !bytes.Equal(b, dv.val.Bytes()) {
					// TODO: Avoid panic if we're running with the race detector
					// and instead spawn a goroutine that periodically resets
					// this value back to the original to induce a race.
					panic("detected mutation on the default bytes")
				}
			}
		}
	} else {
		switch k {
		case pref.BoolKind:
			dv.val = pref.ValueOf(false)
		case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
			dv.val = pref.ValueOf(int32(0))
		case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
			dv.val = pref.ValueOf(int64(0))
		case pref.Uint32Kind, pref.Fixed32Kind:
			dv.val = pref.ValueOf(uint32(0))
		case pref.Uint64Kind, pref.Fixed64Kind:
			dv.val = pref.ValueOf(uint64(0))
		case pref.FloatKind:
			dv.val = pref.ValueOf(float32(0))
		case pref.DoubleKind:
			dv.val = pref.ValueOf(float64(0))
		case pref.StringKind:
			dv.val = pref.ValueOf(string(""))
		case pref.BytesKind:
			dv.val = pref.ValueOf([]byte(nil))
		case pref.EnumKind:
			dv.enum = eds.Get(0)
			dv.val = pref.ValueOf(dv.enum.Number())
		}
	}
}

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

	var hasSyntax bool
	var enumIdx, messageIdx, extensionIdx, serviceIdx int
	fd.lazy = &fileLazy{byName: make(map[pref.FullName]pref.Descriptor)}
	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.lazy.imports[v].IsPublic = true
			case fieldnum.FileDescriptorProto_WeakDependency:
				fd.lazy.imports[v].IsWeak = true
			}
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.FileDescriptorProto_Syntax:
				hasSyntax = true
				switch string(v) {
				case "proto2":
					fd.lazy.syntax = pref.Proto2
				case "proto3":
					fd.lazy.syntax = pref.Proto3
				default:
					panic("invalid syntax")
				}
			case fieldnum.FileDescriptorProto_Dependency:
				fd.lazy.imports = append(fd.lazy.imports, pref.FileImport{
					FileDescriptor: ptype.PlaceholderFile(nb.MakeString(v), ""),
				})
			case fieldnum.FileDescriptorProto_EnumType:
				fd.enums.list[enumIdx].unmarshalFull(v, nb)
				enumIdx++
			case fieldnum.FileDescriptorProto_MessageType:
				fd.messages.list[messageIdx].unmarshalFull(v, nb)
				messageIdx++
			case fieldnum.FileDescriptorProto_Extension:
				fd.extensions.list[extensionIdx].unmarshalFull(v, nb)
				extensionIdx++
			case fieldnum.FileDescriptorProto_Service:
				fd.services.list[serviceIdx].unmarshalFull(v, nb)
				serviceIdx++
			case fieldnum.FileDescriptorProto_Options:
				fd.lazy.options = append(fd.lazy.options, v...)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}

	// If syntax is missing, it is assumed to be proto2.
	if !hasSyntax {
		fd.lazy.syntax = pref.Proto2
	}
}

func (ed *enumDesc) unmarshalFull(b []byte, nb *nameBuilder) {
	var rawValues [][]byte
	ed.lazy = new(enumLazy)
	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.lazy.resvNames.list = append(ed.lazy.resvNames.list, pref.Name(nb.MakeString(v)))
			case fieldnum.EnumDescriptorProto_ReservedRange:
				ed.lazy.resvRanges.list = append(ed.lazy.resvRanges.list, unmarshalEnumReservedRange(v))
			case fieldnum.EnumDescriptorProto_Options:
				ed.lazy.options = append(ed.lazy.options, v...)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}

	if len(rawValues) > 0 {
		ed.lazy.values.list = make([]enumValueDesc, len(rawValues))
		for i, b := range rawValues {
			ed.lazy.values.list[i].unmarshalFull(b, nb, ed.parentFile, ed, i)
		}
	}

	ed.parentFile.lazy.byName[ed.FullName()] = ed
}

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 *enumValueDesc) unmarshalFull(b []byte, nb *nameBuilder, pf *fileDesc, pd pref.Descriptor, i int) {
	vd.parentFile = pf
	vd.parent = pd
	vd.index = i

	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.number = pref.EnumNumber(v)
			}
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.EnumValueDescriptorProto_Name:
				vd.fullName = nb.AppendFullName(pd.FullName(), v)
			case fieldnum.EnumValueDescriptorProto_Options:
				vd.options = append(vd.options, v...)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}

	vd.parentFile.lazy.byName[vd.FullName()] = vd
}

func (md *messageDesc) unmarshalFull(b []byte, nb *nameBuilder) {
	var rawFields, rawOneofs [][]byte
	var enumIdx, messageIdx, extensionIdx int
	var isMapEntry bool
	md.lazy = new(messageLazy)
	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.lazy.resvNames.list = append(md.lazy.resvNames.list, pref.Name(nb.MakeString(v)))
			case fieldnum.DescriptorProto_ReservedRange:
				md.lazy.resvRanges.list = append(md.lazy.resvRanges.list, unmarshalMessageReservedRange(v))
			case fieldnum.DescriptorProto_ExtensionRange:
				r, opts := unmarshalMessageExtensionRange(v)
				md.lazy.extRanges.list = append(md.lazy.extRanges.list, r)
				md.lazy.extRangeOptions = append(md.lazy.extRangeOptions, opts)
			case fieldnum.DescriptorProto_EnumType:
				md.enums.list[enumIdx].unmarshalFull(v, nb)
				enumIdx++
			case fieldnum.DescriptorProto_NestedType:
				md.messages.list[messageIdx].unmarshalFull(v, nb)
				messageIdx++
			case fieldnum.DescriptorProto_Extension:
				md.extensions.list[extensionIdx].unmarshalFull(v, nb)
				extensionIdx++
			case fieldnum.DescriptorProto_Options:
				md.unmarshalOptions(v, &isMapEntry)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}

	if len(rawFields) > 0 || len(rawOneofs) > 0 {
		md.lazy.fields.list = make([]fieldDesc, len(rawFields))
		md.lazy.oneofs.list = make([]oneofDesc, len(rawOneofs))
		for i, b := range rawFields {
			fd := &md.lazy.fields.list[i]
			fd.unmarshalFull(b, nb, md.parentFile, md.asDesc(), i)
			if fd.cardinality == pref.Required {
				md.lazy.reqNumbers.list = append(md.lazy.reqNumbers.list, fd.number)
			}
		}
		for i, b := range rawOneofs {
			od := &md.lazy.oneofs.list[i]
			od.unmarshalFull(b, nb, md.parentFile, md.asDesc(), i)
		}
	}

	if isMapEntry != md.isMapEntry {
		panic("mismatching map entry property")
	}

	md.parentFile.lazy.byName[md.FullName()] = md.asDesc()
}

func (md *messageDesc) unmarshalOptions(b []byte, isMapEntry *bool) {
	md.lazy.options = append(md.lazy.options, b...)
	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:
				*isMapEntry = wire.DecodeBool(v)
			case fieldnum.MessageOptions_MessageSetWireFormat:
				md.lazy.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, opts []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:
				opts = append(opts, v...)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
	return r, opts
}

func (fd *fieldDesc) unmarshalFull(b []byte, nb *nameBuilder, pf *fileDesc, pd pref.Descriptor, i int) {
	fd.parentFile = pf
	fd.parent = pd
	fd.index = i

	var rawDefVal []byte
	var rawTypeName []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.number = pref.FieldNumber(v)
			case fieldnum.FieldDescriptorProto_Label:
				fd.cardinality = pref.Cardinality(v)
			case fieldnum.FieldDescriptorProto_Type:
				fd.kind = pref.Kind(v)
			case fieldnum.FieldDescriptorProto_OneofIndex:
				// In messageDesc.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.(messageType).lazy.oneofs.list[v]
				od.fields.list = append(od.fields.list, fd)
				if fd.oneofType != nil {
					panic("oneof type already set")
				}
				fd.oneofType = od
			}
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldDescriptorProto_Name:
				fd.fullName = nb.AppendFullName(pd.FullName(), v)
			case fieldnum.FieldDescriptorProto_JsonName:
				fd.hasJSONName = true
				fd.jsonName = nb.MakeString(v)
			case fieldnum.FieldDescriptorProto_DefaultValue:
				fd.defVal.has = true
				rawDefVal = v
			case fieldnum.FieldDescriptorProto_TypeName:
				rawTypeName = v
			case fieldnum.FieldDescriptorProto_Options:
				fd.unmarshalOptions(v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}

	if !fd.hasJSONName {
		fd.jsonName = nb.MakeJSONName(fd.Name())
	}
	if rawDefVal != nil {
		var err error
		fd.defVal.val, err = defval.Unmarshal(string(rawDefVal), fd.kind, defval.Descriptor)
		if err != nil {
			panic(err)
		}
	}
	if fd.isWeak {
		if len(rawTypeName) == 0 || rawTypeName[0] != '.' {
			panic("weak target name must be fully qualified")
		}
		fd.messageType = ptype.PlaceholderMessage(pref.FullName(rawTypeName[1:]))
	}

	fd.parentFile.lazy.byName[fd.FullName()] = fd
}

func (fd *fieldDesc) unmarshalOptions(b []byte) {
	fd.options = append(fd.options, b...)
	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.hasPacked = true
				fd.isPacked = wire.DecodeBool(v)
			case fieldnum.FieldOptions_Weak:
				fd.isWeak = wire.DecodeBool(v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
}

func (od *oneofDesc) unmarshalFull(b []byte, nb *nameBuilder, pf *fileDesc, pd pref.Descriptor, i int) {
	od.parentFile = pf
	od.parent = pd
	od.index = i

	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.fullName = nb.AppendFullName(pd.FullName(), v)
			case fieldnum.OneofDescriptorProto_Options:
				od.options = append(od.options, v...)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}

	od.parentFile.lazy.byName[od.FullName()] = od
}

func (xd *extensionDesc) unmarshalFull(b []byte, nb *nameBuilder) {
	var rawDefVal []byte
	xd.lazy = new(extensionLazy)
	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.lazy.cardinality = pref.Cardinality(v)
			case fieldnum.FieldDescriptorProto_Type:
				xd.lazy.kind = pref.Kind(v)
			}
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.FieldDescriptorProto_JsonName:
				xd.lazy.hasJSONName = true
				xd.lazy.jsonName = nb.MakeString(v)
			case fieldnum.FieldDescriptorProto_DefaultValue:
				xd.lazy.defVal.has = true
				rawDefVal = v
			case fieldnum.FieldDescriptorProto_Options:
				xd.unmarshalOptions(v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}

	if rawDefVal != nil {
		var err error
		xd.lazy.defVal.val, err = defval.Unmarshal(string(rawDefVal), xd.lazy.kind, defval.Descriptor)
		if err != nil {
			panic(err)
		}
	}

	xd.parentFile.lazy.byName[xd.FullName()] = xd
}

func (xd *extensionDesc) unmarshalOptions(b []byte) {
	xd.lazy.options = append(xd.lazy.options, b...)
	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.lazy.isPacked = wire.DecodeBool(v)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}
}

func (sd *serviceDesc) unmarshalFull(b []byte, nb *nameBuilder) {
	var rawMethods [][]byte
	sd.lazy = new(serviceLazy)
	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:
				sd.lazy.options = append(sd.lazy.options, v...)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}

	if len(rawMethods) > 0 {
		sd.lazy.methods.list = make([]methodDesc, len(rawMethods))
		for i, b := range rawMethods {
			sd.lazy.methods.list[i].unmarshalFull(b, nb, sd.parentFile, sd, i)
		}
	}

	sd.parentFile.lazy.byName[sd.FullName()] = sd
}

func (md *methodDesc) unmarshalFull(b []byte, nb *nameBuilder, pf *fileDesc, pd pref.Descriptor, i int) {
	md.parentFile = pf
	md.parent = pd
	md.index = i

	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.isStreamingClient = wire.DecodeBool(v)
			case fieldnum.MethodDescriptorProto_ServerStreaming:
				md.isStreamingServer = wire.DecodeBool(v)
			}
		case wire.BytesType:
			v, m := wire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case fieldnum.MethodDescriptorProto_Name:
				md.fullName = nb.AppendFullName(pd.FullName(), v)
			case fieldnum.MethodDescriptorProto_Options:
				md.options = append(md.options, v...)
			}
		default:
			m := wire.ConsumeFieldValue(num, typ, b)
			b = b[m:]
		}
	}

	md.parentFile.lazy.byName[md.FullName()] = md
}
