xref: /aosp_15_r20/external/golang-protobuf/internal/filedesc/desc_lazy.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
1*1c12ee1eSDan Willemsen// Copyright 2019 The Go Authors. All rights reserved.
2*1c12ee1eSDan Willemsen// Use of this source code is governed by a BSD-style
3*1c12ee1eSDan Willemsen// license that can be found in the LICENSE file.
4*1c12ee1eSDan Willemsen
5*1c12ee1eSDan Willemsenpackage filedesc
6*1c12ee1eSDan Willemsen
7*1c12ee1eSDan Willemsenimport (
8*1c12ee1eSDan Willemsen	"reflect"
9*1c12ee1eSDan Willemsen	"sync"
10*1c12ee1eSDan Willemsen
11*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/encoding/protowire"
12*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/descopts"
13*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/genid"
14*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/strs"
15*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/proto"
16*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/reflect/protoreflect"
17*1c12ee1eSDan Willemsen)
18*1c12ee1eSDan Willemsen
19*1c12ee1eSDan Willemsenfunc (fd *File) lazyRawInit() {
20*1c12ee1eSDan Willemsen	fd.unmarshalFull(fd.builder.RawDescriptor)
21*1c12ee1eSDan Willemsen	fd.resolveMessages()
22*1c12ee1eSDan Willemsen	fd.resolveExtensions()
23*1c12ee1eSDan Willemsen	fd.resolveServices()
24*1c12ee1eSDan Willemsen}
25*1c12ee1eSDan Willemsen
26*1c12ee1eSDan Willemsenfunc (file *File) resolveMessages() {
27*1c12ee1eSDan Willemsen	var depIdx int32
28*1c12ee1eSDan Willemsen	for i := range file.allMessages {
29*1c12ee1eSDan Willemsen		md := &file.allMessages[i]
30*1c12ee1eSDan Willemsen
31*1c12ee1eSDan Willemsen		// Resolve message field dependencies.
32*1c12ee1eSDan Willemsen		for j := range md.L2.Fields.List {
33*1c12ee1eSDan Willemsen			fd := &md.L2.Fields.List[j]
34*1c12ee1eSDan Willemsen
35*1c12ee1eSDan Willemsen			// Weak fields are resolved upon actual use.
36*1c12ee1eSDan Willemsen			if fd.L1.IsWeak {
37*1c12ee1eSDan Willemsen				continue
38*1c12ee1eSDan Willemsen			}
39*1c12ee1eSDan Willemsen
40*1c12ee1eSDan Willemsen			// Resolve message field dependency.
41*1c12ee1eSDan Willemsen			switch fd.L1.Kind {
42*1c12ee1eSDan Willemsen			case protoreflect.EnumKind:
43*1c12ee1eSDan Willemsen				fd.L1.Enum = file.resolveEnumDependency(fd.L1.Enum, listFieldDeps, depIdx)
44*1c12ee1eSDan Willemsen				depIdx++
45*1c12ee1eSDan Willemsen			case protoreflect.MessageKind, protoreflect.GroupKind:
46*1c12ee1eSDan Willemsen				fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx)
47*1c12ee1eSDan Willemsen				depIdx++
48*1c12ee1eSDan Willemsen			}
49*1c12ee1eSDan Willemsen
50*1c12ee1eSDan Willemsen			// Default is resolved here since it depends on Enum being resolved.
51*1c12ee1eSDan Willemsen			if v := fd.L1.Default.val; v.IsValid() {
52*1c12ee1eSDan Willemsen				fd.L1.Default = unmarshalDefault(v.Bytes(), fd.L1.Kind, file, fd.L1.Enum)
53*1c12ee1eSDan Willemsen			}
54*1c12ee1eSDan Willemsen		}
55*1c12ee1eSDan Willemsen	}
56*1c12ee1eSDan Willemsen}
57*1c12ee1eSDan Willemsen
58*1c12ee1eSDan Willemsenfunc (file *File) resolveExtensions() {
59*1c12ee1eSDan Willemsen	var depIdx int32
60*1c12ee1eSDan Willemsen	for i := range file.allExtensions {
61*1c12ee1eSDan Willemsen		xd := &file.allExtensions[i]
62*1c12ee1eSDan Willemsen
63*1c12ee1eSDan Willemsen		// Resolve extension field dependency.
64*1c12ee1eSDan Willemsen		switch xd.L1.Kind {
65*1c12ee1eSDan Willemsen		case protoreflect.EnumKind:
66*1c12ee1eSDan Willemsen			xd.L2.Enum = file.resolveEnumDependency(xd.L2.Enum, listExtDeps, depIdx)
67*1c12ee1eSDan Willemsen			depIdx++
68*1c12ee1eSDan Willemsen		case protoreflect.MessageKind, protoreflect.GroupKind:
69*1c12ee1eSDan Willemsen			xd.L2.Message = file.resolveMessageDependency(xd.L2.Message, listExtDeps, depIdx)
70*1c12ee1eSDan Willemsen			depIdx++
71*1c12ee1eSDan Willemsen		}
72*1c12ee1eSDan Willemsen
73*1c12ee1eSDan Willemsen		// Default is resolved here since it depends on Enum being resolved.
74*1c12ee1eSDan Willemsen		if v := xd.L2.Default.val; v.IsValid() {
75*1c12ee1eSDan Willemsen			xd.L2.Default = unmarshalDefault(v.Bytes(), xd.L1.Kind, file, xd.L2.Enum)
76*1c12ee1eSDan Willemsen		}
77*1c12ee1eSDan Willemsen	}
78*1c12ee1eSDan Willemsen}
79*1c12ee1eSDan Willemsen
80*1c12ee1eSDan Willemsenfunc (file *File) resolveServices() {
81*1c12ee1eSDan Willemsen	var depIdx int32
82*1c12ee1eSDan Willemsen	for i := range file.allServices {
83*1c12ee1eSDan Willemsen		sd := &file.allServices[i]
84*1c12ee1eSDan Willemsen
85*1c12ee1eSDan Willemsen		// Resolve method dependencies.
86*1c12ee1eSDan Willemsen		for j := range sd.L2.Methods.List {
87*1c12ee1eSDan Willemsen			md := &sd.L2.Methods.List[j]
88*1c12ee1eSDan Willemsen			md.L1.Input = file.resolveMessageDependency(md.L1.Input, listMethInDeps, depIdx)
89*1c12ee1eSDan Willemsen			md.L1.Output = file.resolveMessageDependency(md.L1.Output, listMethOutDeps, depIdx)
90*1c12ee1eSDan Willemsen			depIdx++
91*1c12ee1eSDan Willemsen		}
92*1c12ee1eSDan Willemsen	}
93*1c12ee1eSDan Willemsen}
94*1c12ee1eSDan Willemsen
95*1c12ee1eSDan Willemsenfunc (file *File) resolveEnumDependency(ed protoreflect.EnumDescriptor, i, j int32) protoreflect.EnumDescriptor {
96*1c12ee1eSDan Willemsen	r := file.builder.FileRegistry
97*1c12ee1eSDan Willemsen	if r, ok := r.(resolverByIndex); ok {
98*1c12ee1eSDan Willemsen		if ed2 := r.FindEnumByIndex(i, j, file.allEnums, file.allMessages); ed2 != nil {
99*1c12ee1eSDan Willemsen			return ed2
100*1c12ee1eSDan Willemsen		}
101*1c12ee1eSDan Willemsen	}
102*1c12ee1eSDan Willemsen	for i := range file.allEnums {
103*1c12ee1eSDan Willemsen		if ed2 := &file.allEnums[i]; ed2.L0.FullName == ed.FullName() {
104*1c12ee1eSDan Willemsen			return ed2
105*1c12ee1eSDan Willemsen		}
106*1c12ee1eSDan Willemsen	}
107*1c12ee1eSDan Willemsen	if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil {
108*1c12ee1eSDan Willemsen		return d.(protoreflect.EnumDescriptor)
109*1c12ee1eSDan Willemsen	}
110*1c12ee1eSDan Willemsen	return ed
111*1c12ee1eSDan Willemsen}
112*1c12ee1eSDan Willemsen
113*1c12ee1eSDan Willemsenfunc (file *File) resolveMessageDependency(md protoreflect.MessageDescriptor, i, j int32) protoreflect.MessageDescriptor {
114*1c12ee1eSDan Willemsen	r := file.builder.FileRegistry
115*1c12ee1eSDan Willemsen	if r, ok := r.(resolverByIndex); ok {
116*1c12ee1eSDan Willemsen		if md2 := r.FindMessageByIndex(i, j, file.allEnums, file.allMessages); md2 != nil {
117*1c12ee1eSDan Willemsen			return md2
118*1c12ee1eSDan Willemsen		}
119*1c12ee1eSDan Willemsen	}
120*1c12ee1eSDan Willemsen	for i := range file.allMessages {
121*1c12ee1eSDan Willemsen		if md2 := &file.allMessages[i]; md2.L0.FullName == md.FullName() {
122*1c12ee1eSDan Willemsen			return md2
123*1c12ee1eSDan Willemsen		}
124*1c12ee1eSDan Willemsen	}
125*1c12ee1eSDan Willemsen	if d, _ := r.FindDescriptorByName(md.FullName()); d != nil {
126*1c12ee1eSDan Willemsen		return d.(protoreflect.MessageDescriptor)
127*1c12ee1eSDan Willemsen	}
128*1c12ee1eSDan Willemsen	return md
129*1c12ee1eSDan Willemsen}
130*1c12ee1eSDan Willemsen
131*1c12ee1eSDan Willemsenfunc (fd *File) unmarshalFull(b []byte) {
132*1c12ee1eSDan Willemsen	sb := getBuilder()
133*1c12ee1eSDan Willemsen	defer putBuilder(sb)
134*1c12ee1eSDan Willemsen
135*1c12ee1eSDan Willemsen	var enumIdx, messageIdx, extensionIdx, serviceIdx int
136*1c12ee1eSDan Willemsen	var rawOptions []byte
137*1c12ee1eSDan Willemsen	fd.L2 = new(FileL2)
138*1c12ee1eSDan Willemsen	for len(b) > 0 {
139*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
140*1c12ee1eSDan Willemsen		b = b[n:]
141*1c12ee1eSDan Willemsen		switch typ {
142*1c12ee1eSDan Willemsen		case protowire.VarintType:
143*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
144*1c12ee1eSDan Willemsen			b = b[m:]
145*1c12ee1eSDan Willemsen			switch num {
146*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_PublicDependency_field_number:
147*1c12ee1eSDan Willemsen				fd.L2.Imports[v].IsPublic = true
148*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_WeakDependency_field_number:
149*1c12ee1eSDan Willemsen				fd.L2.Imports[v].IsWeak = true
150*1c12ee1eSDan Willemsen			}
151*1c12ee1eSDan Willemsen		case protowire.BytesType:
152*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
153*1c12ee1eSDan Willemsen			b = b[m:]
154*1c12ee1eSDan Willemsen			switch num {
155*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_Dependency_field_number:
156*1c12ee1eSDan Willemsen				path := sb.MakeString(v)
157*1c12ee1eSDan Willemsen				imp, _ := fd.builder.FileRegistry.FindFileByPath(path)
158*1c12ee1eSDan Willemsen				if imp == nil {
159*1c12ee1eSDan Willemsen					imp = PlaceholderFile(path)
160*1c12ee1eSDan Willemsen				}
161*1c12ee1eSDan Willemsen				fd.L2.Imports = append(fd.L2.Imports, protoreflect.FileImport{FileDescriptor: imp})
162*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_EnumType_field_number:
163*1c12ee1eSDan Willemsen				fd.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
164*1c12ee1eSDan Willemsen				enumIdx++
165*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_MessageType_field_number:
166*1c12ee1eSDan Willemsen				fd.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
167*1c12ee1eSDan Willemsen				messageIdx++
168*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_Extension_field_number:
169*1c12ee1eSDan Willemsen				fd.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
170*1c12ee1eSDan Willemsen				extensionIdx++
171*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_Service_field_number:
172*1c12ee1eSDan Willemsen				fd.L1.Services.List[serviceIdx].unmarshalFull(v, sb)
173*1c12ee1eSDan Willemsen				serviceIdx++
174*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_Options_field_number:
175*1c12ee1eSDan Willemsen				rawOptions = appendOptions(rawOptions, v)
176*1c12ee1eSDan Willemsen			}
177*1c12ee1eSDan Willemsen		default:
178*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
179*1c12ee1eSDan Willemsen			b = b[m:]
180*1c12ee1eSDan Willemsen		}
181*1c12ee1eSDan Willemsen	}
182*1c12ee1eSDan Willemsen	fd.L2.Options = fd.builder.optionsUnmarshaler(&descopts.File, rawOptions)
183*1c12ee1eSDan Willemsen}
184*1c12ee1eSDan Willemsen
185*1c12ee1eSDan Willemsenfunc (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) {
186*1c12ee1eSDan Willemsen	var rawValues [][]byte
187*1c12ee1eSDan Willemsen	var rawOptions []byte
188*1c12ee1eSDan Willemsen	if !ed.L1.eagerValues {
189*1c12ee1eSDan Willemsen		ed.L2 = new(EnumL2)
190*1c12ee1eSDan Willemsen	}
191*1c12ee1eSDan Willemsen	for len(b) > 0 {
192*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
193*1c12ee1eSDan Willemsen		b = b[n:]
194*1c12ee1eSDan Willemsen		switch typ {
195*1c12ee1eSDan Willemsen		case protowire.BytesType:
196*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
197*1c12ee1eSDan Willemsen			b = b[m:]
198*1c12ee1eSDan Willemsen			switch num {
199*1c12ee1eSDan Willemsen			case genid.EnumDescriptorProto_Value_field_number:
200*1c12ee1eSDan Willemsen				rawValues = append(rawValues, v)
201*1c12ee1eSDan Willemsen			case genid.EnumDescriptorProto_ReservedName_field_number:
202*1c12ee1eSDan Willemsen				ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, protoreflect.Name(sb.MakeString(v)))
203*1c12ee1eSDan Willemsen			case genid.EnumDescriptorProto_ReservedRange_field_number:
204*1c12ee1eSDan Willemsen				ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v))
205*1c12ee1eSDan Willemsen			case genid.EnumDescriptorProto_Options_field_number:
206*1c12ee1eSDan Willemsen				rawOptions = appendOptions(rawOptions, v)
207*1c12ee1eSDan Willemsen			}
208*1c12ee1eSDan Willemsen		default:
209*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
210*1c12ee1eSDan Willemsen			b = b[m:]
211*1c12ee1eSDan Willemsen		}
212*1c12ee1eSDan Willemsen	}
213*1c12ee1eSDan Willemsen	if !ed.L1.eagerValues && len(rawValues) > 0 {
214*1c12ee1eSDan Willemsen		ed.L2.Values.List = make([]EnumValue, len(rawValues))
215*1c12ee1eSDan Willemsen		for i, b := range rawValues {
216*1c12ee1eSDan Willemsen			ed.L2.Values.List[i].unmarshalFull(b, sb, ed.L0.ParentFile, ed, i)
217*1c12ee1eSDan Willemsen		}
218*1c12ee1eSDan Willemsen	}
219*1c12ee1eSDan Willemsen	ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Enum, rawOptions)
220*1c12ee1eSDan Willemsen}
221*1c12ee1eSDan Willemsen
222*1c12ee1eSDan Willemsenfunc unmarshalEnumReservedRange(b []byte) (r [2]protoreflect.EnumNumber) {
223*1c12ee1eSDan Willemsen	for len(b) > 0 {
224*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
225*1c12ee1eSDan Willemsen		b = b[n:]
226*1c12ee1eSDan Willemsen		switch typ {
227*1c12ee1eSDan Willemsen		case protowire.VarintType:
228*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
229*1c12ee1eSDan Willemsen			b = b[m:]
230*1c12ee1eSDan Willemsen			switch num {
231*1c12ee1eSDan Willemsen			case genid.EnumDescriptorProto_EnumReservedRange_Start_field_number:
232*1c12ee1eSDan Willemsen				r[0] = protoreflect.EnumNumber(v)
233*1c12ee1eSDan Willemsen			case genid.EnumDescriptorProto_EnumReservedRange_End_field_number:
234*1c12ee1eSDan Willemsen				r[1] = protoreflect.EnumNumber(v)
235*1c12ee1eSDan Willemsen			}
236*1c12ee1eSDan Willemsen		default:
237*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
238*1c12ee1eSDan Willemsen			b = b[m:]
239*1c12ee1eSDan Willemsen		}
240*1c12ee1eSDan Willemsen	}
241*1c12ee1eSDan Willemsen	return r
242*1c12ee1eSDan Willemsen}
243*1c12ee1eSDan Willemsen
244*1c12ee1eSDan Willemsenfunc (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
245*1c12ee1eSDan Willemsen	vd.L0.ParentFile = pf
246*1c12ee1eSDan Willemsen	vd.L0.Parent = pd
247*1c12ee1eSDan Willemsen	vd.L0.Index = i
248*1c12ee1eSDan Willemsen
249*1c12ee1eSDan Willemsen	var rawOptions []byte
250*1c12ee1eSDan Willemsen	for len(b) > 0 {
251*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
252*1c12ee1eSDan Willemsen		b = b[n:]
253*1c12ee1eSDan Willemsen		switch typ {
254*1c12ee1eSDan Willemsen		case protowire.VarintType:
255*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
256*1c12ee1eSDan Willemsen			b = b[m:]
257*1c12ee1eSDan Willemsen			switch num {
258*1c12ee1eSDan Willemsen			case genid.EnumValueDescriptorProto_Number_field_number:
259*1c12ee1eSDan Willemsen				vd.L1.Number = protoreflect.EnumNumber(v)
260*1c12ee1eSDan Willemsen			}
261*1c12ee1eSDan Willemsen		case protowire.BytesType:
262*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
263*1c12ee1eSDan Willemsen			b = b[m:]
264*1c12ee1eSDan Willemsen			switch num {
265*1c12ee1eSDan Willemsen			case genid.EnumValueDescriptorProto_Name_field_number:
266*1c12ee1eSDan Willemsen				// NOTE: Enum values are in the same scope as the enum parent.
267*1c12ee1eSDan Willemsen				vd.L0.FullName = appendFullName(sb, pd.Parent().FullName(), v)
268*1c12ee1eSDan Willemsen			case genid.EnumValueDescriptorProto_Options_field_number:
269*1c12ee1eSDan Willemsen				rawOptions = appendOptions(rawOptions, v)
270*1c12ee1eSDan Willemsen			}
271*1c12ee1eSDan Willemsen		default:
272*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
273*1c12ee1eSDan Willemsen			b = b[m:]
274*1c12ee1eSDan Willemsen		}
275*1c12ee1eSDan Willemsen	}
276*1c12ee1eSDan Willemsen	vd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.EnumValue, rawOptions)
277*1c12ee1eSDan Willemsen}
278*1c12ee1eSDan Willemsen
279*1c12ee1eSDan Willemsenfunc (md *Message) unmarshalFull(b []byte, sb *strs.Builder) {
280*1c12ee1eSDan Willemsen	var rawFields, rawOneofs [][]byte
281*1c12ee1eSDan Willemsen	var enumIdx, messageIdx, extensionIdx int
282*1c12ee1eSDan Willemsen	var rawOptions []byte
283*1c12ee1eSDan Willemsen	md.L2 = new(MessageL2)
284*1c12ee1eSDan Willemsen	for len(b) > 0 {
285*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
286*1c12ee1eSDan Willemsen		b = b[n:]
287*1c12ee1eSDan Willemsen		switch typ {
288*1c12ee1eSDan Willemsen		case protowire.BytesType:
289*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
290*1c12ee1eSDan Willemsen			b = b[m:]
291*1c12ee1eSDan Willemsen			switch num {
292*1c12ee1eSDan Willemsen			case genid.DescriptorProto_Field_field_number:
293*1c12ee1eSDan Willemsen				rawFields = append(rawFields, v)
294*1c12ee1eSDan Willemsen			case genid.DescriptorProto_OneofDecl_field_number:
295*1c12ee1eSDan Willemsen				rawOneofs = append(rawOneofs, v)
296*1c12ee1eSDan Willemsen			case genid.DescriptorProto_ReservedName_field_number:
297*1c12ee1eSDan Willemsen				md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, protoreflect.Name(sb.MakeString(v)))
298*1c12ee1eSDan Willemsen			case genid.DescriptorProto_ReservedRange_field_number:
299*1c12ee1eSDan Willemsen				md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v))
300*1c12ee1eSDan Willemsen			case genid.DescriptorProto_ExtensionRange_field_number:
301*1c12ee1eSDan Willemsen				r, rawOptions := unmarshalMessageExtensionRange(v)
302*1c12ee1eSDan Willemsen				opts := md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.ExtensionRange, rawOptions)
303*1c12ee1eSDan Willemsen				md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, r)
304*1c12ee1eSDan Willemsen				md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, opts)
305*1c12ee1eSDan Willemsen			case genid.DescriptorProto_EnumType_field_number:
306*1c12ee1eSDan Willemsen				md.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
307*1c12ee1eSDan Willemsen				enumIdx++
308*1c12ee1eSDan Willemsen			case genid.DescriptorProto_NestedType_field_number:
309*1c12ee1eSDan Willemsen				md.L1.Messages.List[messageIdx].unmarshalFull(v, sb)
310*1c12ee1eSDan Willemsen				messageIdx++
311*1c12ee1eSDan Willemsen			case genid.DescriptorProto_Extension_field_number:
312*1c12ee1eSDan Willemsen				md.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb)
313*1c12ee1eSDan Willemsen				extensionIdx++
314*1c12ee1eSDan Willemsen			case genid.DescriptorProto_Options_field_number:
315*1c12ee1eSDan Willemsen				md.unmarshalOptions(v)
316*1c12ee1eSDan Willemsen				rawOptions = appendOptions(rawOptions, v)
317*1c12ee1eSDan Willemsen			}
318*1c12ee1eSDan Willemsen		default:
319*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
320*1c12ee1eSDan Willemsen			b = b[m:]
321*1c12ee1eSDan Willemsen		}
322*1c12ee1eSDan Willemsen	}
323*1c12ee1eSDan Willemsen	if len(rawFields) > 0 || len(rawOneofs) > 0 {
324*1c12ee1eSDan Willemsen		md.L2.Fields.List = make([]Field, len(rawFields))
325*1c12ee1eSDan Willemsen		md.L2.Oneofs.List = make([]Oneof, len(rawOneofs))
326*1c12ee1eSDan Willemsen		for i, b := range rawFields {
327*1c12ee1eSDan Willemsen			fd := &md.L2.Fields.List[i]
328*1c12ee1eSDan Willemsen			fd.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
329*1c12ee1eSDan Willemsen			if fd.L1.Cardinality == protoreflect.Required {
330*1c12ee1eSDan Willemsen				md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number)
331*1c12ee1eSDan Willemsen			}
332*1c12ee1eSDan Willemsen		}
333*1c12ee1eSDan Willemsen		for i, b := range rawOneofs {
334*1c12ee1eSDan Willemsen			od := &md.L2.Oneofs.List[i]
335*1c12ee1eSDan Willemsen			od.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
336*1c12ee1eSDan Willemsen		}
337*1c12ee1eSDan Willemsen	}
338*1c12ee1eSDan Willemsen	md.L2.Options = md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Message, rawOptions)
339*1c12ee1eSDan Willemsen}
340*1c12ee1eSDan Willemsen
341*1c12ee1eSDan Willemsenfunc (md *Message) unmarshalOptions(b []byte) {
342*1c12ee1eSDan Willemsen	for len(b) > 0 {
343*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
344*1c12ee1eSDan Willemsen		b = b[n:]
345*1c12ee1eSDan Willemsen		switch typ {
346*1c12ee1eSDan Willemsen		case protowire.VarintType:
347*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
348*1c12ee1eSDan Willemsen			b = b[m:]
349*1c12ee1eSDan Willemsen			switch num {
350*1c12ee1eSDan Willemsen			case genid.MessageOptions_MapEntry_field_number:
351*1c12ee1eSDan Willemsen				md.L1.IsMapEntry = protowire.DecodeBool(v)
352*1c12ee1eSDan Willemsen			case genid.MessageOptions_MessageSetWireFormat_field_number:
353*1c12ee1eSDan Willemsen				md.L1.IsMessageSet = protowire.DecodeBool(v)
354*1c12ee1eSDan Willemsen			}
355*1c12ee1eSDan Willemsen		default:
356*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
357*1c12ee1eSDan Willemsen			b = b[m:]
358*1c12ee1eSDan Willemsen		}
359*1c12ee1eSDan Willemsen	}
360*1c12ee1eSDan Willemsen}
361*1c12ee1eSDan Willemsen
362*1c12ee1eSDan Willemsenfunc unmarshalMessageReservedRange(b []byte) (r [2]protoreflect.FieldNumber) {
363*1c12ee1eSDan Willemsen	for len(b) > 0 {
364*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
365*1c12ee1eSDan Willemsen		b = b[n:]
366*1c12ee1eSDan Willemsen		switch typ {
367*1c12ee1eSDan Willemsen		case protowire.VarintType:
368*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
369*1c12ee1eSDan Willemsen			b = b[m:]
370*1c12ee1eSDan Willemsen			switch num {
371*1c12ee1eSDan Willemsen			case genid.DescriptorProto_ReservedRange_Start_field_number:
372*1c12ee1eSDan Willemsen				r[0] = protoreflect.FieldNumber(v)
373*1c12ee1eSDan Willemsen			case genid.DescriptorProto_ReservedRange_End_field_number:
374*1c12ee1eSDan Willemsen				r[1] = protoreflect.FieldNumber(v)
375*1c12ee1eSDan Willemsen			}
376*1c12ee1eSDan Willemsen		default:
377*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
378*1c12ee1eSDan Willemsen			b = b[m:]
379*1c12ee1eSDan Willemsen		}
380*1c12ee1eSDan Willemsen	}
381*1c12ee1eSDan Willemsen	return r
382*1c12ee1eSDan Willemsen}
383*1c12ee1eSDan Willemsen
384*1c12ee1eSDan Willemsenfunc unmarshalMessageExtensionRange(b []byte) (r [2]protoreflect.FieldNumber, rawOptions []byte) {
385*1c12ee1eSDan Willemsen	for len(b) > 0 {
386*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
387*1c12ee1eSDan Willemsen		b = b[n:]
388*1c12ee1eSDan Willemsen		switch typ {
389*1c12ee1eSDan Willemsen		case protowire.VarintType:
390*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
391*1c12ee1eSDan Willemsen			b = b[m:]
392*1c12ee1eSDan Willemsen			switch num {
393*1c12ee1eSDan Willemsen			case genid.DescriptorProto_ExtensionRange_Start_field_number:
394*1c12ee1eSDan Willemsen				r[0] = protoreflect.FieldNumber(v)
395*1c12ee1eSDan Willemsen			case genid.DescriptorProto_ExtensionRange_End_field_number:
396*1c12ee1eSDan Willemsen				r[1] = protoreflect.FieldNumber(v)
397*1c12ee1eSDan Willemsen			}
398*1c12ee1eSDan Willemsen		case protowire.BytesType:
399*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
400*1c12ee1eSDan Willemsen			b = b[m:]
401*1c12ee1eSDan Willemsen			switch num {
402*1c12ee1eSDan Willemsen			case genid.DescriptorProto_ExtensionRange_Options_field_number:
403*1c12ee1eSDan Willemsen				rawOptions = appendOptions(rawOptions, v)
404*1c12ee1eSDan Willemsen			}
405*1c12ee1eSDan Willemsen		default:
406*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
407*1c12ee1eSDan Willemsen			b = b[m:]
408*1c12ee1eSDan Willemsen		}
409*1c12ee1eSDan Willemsen	}
410*1c12ee1eSDan Willemsen	return r, rawOptions
411*1c12ee1eSDan Willemsen}
412*1c12ee1eSDan Willemsen
413*1c12ee1eSDan Willemsenfunc (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
414*1c12ee1eSDan Willemsen	fd.L0.ParentFile = pf
415*1c12ee1eSDan Willemsen	fd.L0.Parent = pd
416*1c12ee1eSDan Willemsen	fd.L0.Index = i
417*1c12ee1eSDan Willemsen
418*1c12ee1eSDan Willemsen	var rawTypeName []byte
419*1c12ee1eSDan Willemsen	var rawOptions []byte
420*1c12ee1eSDan Willemsen	for len(b) > 0 {
421*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
422*1c12ee1eSDan Willemsen		b = b[n:]
423*1c12ee1eSDan Willemsen		switch typ {
424*1c12ee1eSDan Willemsen		case protowire.VarintType:
425*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
426*1c12ee1eSDan Willemsen			b = b[m:]
427*1c12ee1eSDan Willemsen			switch num {
428*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Number_field_number:
429*1c12ee1eSDan Willemsen				fd.L1.Number = protoreflect.FieldNumber(v)
430*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Label_field_number:
431*1c12ee1eSDan Willemsen				fd.L1.Cardinality = protoreflect.Cardinality(v)
432*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Type_field_number:
433*1c12ee1eSDan Willemsen				fd.L1.Kind = protoreflect.Kind(v)
434*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_OneofIndex_field_number:
435*1c12ee1eSDan Willemsen				// In Message.unmarshalFull, we allocate slices for both
436*1c12ee1eSDan Willemsen				// the field and oneof descriptors before unmarshaling either
437*1c12ee1eSDan Willemsen				// of them. This ensures pointers to slice elements are stable.
438*1c12ee1eSDan Willemsen				od := &pd.(*Message).L2.Oneofs.List[v]
439*1c12ee1eSDan Willemsen				od.L1.Fields.List = append(od.L1.Fields.List, fd)
440*1c12ee1eSDan Willemsen				if fd.L1.ContainingOneof != nil {
441*1c12ee1eSDan Willemsen					panic("oneof type already set")
442*1c12ee1eSDan Willemsen				}
443*1c12ee1eSDan Willemsen				fd.L1.ContainingOneof = od
444*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Proto3Optional_field_number:
445*1c12ee1eSDan Willemsen				fd.L1.IsProto3Optional = protowire.DecodeBool(v)
446*1c12ee1eSDan Willemsen			}
447*1c12ee1eSDan Willemsen		case protowire.BytesType:
448*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
449*1c12ee1eSDan Willemsen			b = b[m:]
450*1c12ee1eSDan Willemsen			switch num {
451*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Name_field_number:
452*1c12ee1eSDan Willemsen				fd.L0.FullName = appendFullName(sb, pd.FullName(), v)
453*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_JsonName_field_number:
454*1c12ee1eSDan Willemsen				fd.L1.StringName.InitJSON(sb.MakeString(v))
455*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_DefaultValue_field_number:
456*1c12ee1eSDan Willemsen				fd.L1.Default.val = protoreflect.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages
457*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_TypeName_field_number:
458*1c12ee1eSDan Willemsen				rawTypeName = v
459*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Options_field_number:
460*1c12ee1eSDan Willemsen				fd.unmarshalOptions(v)
461*1c12ee1eSDan Willemsen				rawOptions = appendOptions(rawOptions, v)
462*1c12ee1eSDan Willemsen			}
463*1c12ee1eSDan Willemsen		default:
464*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
465*1c12ee1eSDan Willemsen			b = b[m:]
466*1c12ee1eSDan Willemsen		}
467*1c12ee1eSDan Willemsen	}
468*1c12ee1eSDan Willemsen	if rawTypeName != nil {
469*1c12ee1eSDan Willemsen		name := makeFullName(sb, rawTypeName)
470*1c12ee1eSDan Willemsen		switch fd.L1.Kind {
471*1c12ee1eSDan Willemsen		case protoreflect.EnumKind:
472*1c12ee1eSDan Willemsen			fd.L1.Enum = PlaceholderEnum(name)
473*1c12ee1eSDan Willemsen		case protoreflect.MessageKind, protoreflect.GroupKind:
474*1c12ee1eSDan Willemsen			fd.L1.Message = PlaceholderMessage(name)
475*1c12ee1eSDan Willemsen		}
476*1c12ee1eSDan Willemsen	}
477*1c12ee1eSDan Willemsen	fd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Field, rawOptions)
478*1c12ee1eSDan Willemsen}
479*1c12ee1eSDan Willemsen
480*1c12ee1eSDan Willemsenfunc (fd *Field) unmarshalOptions(b []byte) {
481*1c12ee1eSDan Willemsen	const FieldOptions_EnforceUTF8 = 13
482*1c12ee1eSDan Willemsen
483*1c12ee1eSDan Willemsen	for len(b) > 0 {
484*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
485*1c12ee1eSDan Willemsen		b = b[n:]
486*1c12ee1eSDan Willemsen		switch typ {
487*1c12ee1eSDan Willemsen		case protowire.VarintType:
488*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
489*1c12ee1eSDan Willemsen			b = b[m:]
490*1c12ee1eSDan Willemsen			switch num {
491*1c12ee1eSDan Willemsen			case genid.FieldOptions_Packed_field_number:
492*1c12ee1eSDan Willemsen				fd.L1.HasPacked = true
493*1c12ee1eSDan Willemsen				fd.L1.IsPacked = protowire.DecodeBool(v)
494*1c12ee1eSDan Willemsen			case genid.FieldOptions_Weak_field_number:
495*1c12ee1eSDan Willemsen				fd.L1.IsWeak = protowire.DecodeBool(v)
496*1c12ee1eSDan Willemsen			case FieldOptions_EnforceUTF8:
497*1c12ee1eSDan Willemsen				fd.L1.HasEnforceUTF8 = true
498*1c12ee1eSDan Willemsen				fd.L1.EnforceUTF8 = protowire.DecodeBool(v)
499*1c12ee1eSDan Willemsen			}
500*1c12ee1eSDan Willemsen		default:
501*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
502*1c12ee1eSDan Willemsen			b = b[m:]
503*1c12ee1eSDan Willemsen		}
504*1c12ee1eSDan Willemsen	}
505*1c12ee1eSDan Willemsen}
506*1c12ee1eSDan Willemsen
507*1c12ee1eSDan Willemsenfunc (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
508*1c12ee1eSDan Willemsen	od.L0.ParentFile = pf
509*1c12ee1eSDan Willemsen	od.L0.Parent = pd
510*1c12ee1eSDan Willemsen	od.L0.Index = i
511*1c12ee1eSDan Willemsen
512*1c12ee1eSDan Willemsen	var rawOptions []byte
513*1c12ee1eSDan Willemsen	for len(b) > 0 {
514*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
515*1c12ee1eSDan Willemsen		b = b[n:]
516*1c12ee1eSDan Willemsen		switch typ {
517*1c12ee1eSDan Willemsen		case protowire.BytesType:
518*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
519*1c12ee1eSDan Willemsen			b = b[m:]
520*1c12ee1eSDan Willemsen			switch num {
521*1c12ee1eSDan Willemsen			case genid.OneofDescriptorProto_Name_field_number:
522*1c12ee1eSDan Willemsen				od.L0.FullName = appendFullName(sb, pd.FullName(), v)
523*1c12ee1eSDan Willemsen			case genid.OneofDescriptorProto_Options_field_number:
524*1c12ee1eSDan Willemsen				rawOptions = appendOptions(rawOptions, v)
525*1c12ee1eSDan Willemsen			}
526*1c12ee1eSDan Willemsen		default:
527*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
528*1c12ee1eSDan Willemsen			b = b[m:]
529*1c12ee1eSDan Willemsen		}
530*1c12ee1eSDan Willemsen	}
531*1c12ee1eSDan Willemsen	od.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Oneof, rawOptions)
532*1c12ee1eSDan Willemsen}
533*1c12ee1eSDan Willemsen
534*1c12ee1eSDan Willemsenfunc (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
535*1c12ee1eSDan Willemsen	var rawTypeName []byte
536*1c12ee1eSDan Willemsen	var rawOptions []byte
537*1c12ee1eSDan Willemsen	xd.L2 = new(ExtensionL2)
538*1c12ee1eSDan Willemsen	for len(b) > 0 {
539*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
540*1c12ee1eSDan Willemsen		b = b[n:]
541*1c12ee1eSDan Willemsen		switch typ {
542*1c12ee1eSDan Willemsen		case protowire.VarintType:
543*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
544*1c12ee1eSDan Willemsen			b = b[m:]
545*1c12ee1eSDan Willemsen			switch num {
546*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Proto3Optional_field_number:
547*1c12ee1eSDan Willemsen				xd.L2.IsProto3Optional = protowire.DecodeBool(v)
548*1c12ee1eSDan Willemsen			}
549*1c12ee1eSDan Willemsen		case protowire.BytesType:
550*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
551*1c12ee1eSDan Willemsen			b = b[m:]
552*1c12ee1eSDan Willemsen			switch num {
553*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_JsonName_field_number:
554*1c12ee1eSDan Willemsen				xd.L2.StringName.InitJSON(sb.MakeString(v))
555*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_DefaultValue_field_number:
556*1c12ee1eSDan Willemsen				xd.L2.Default.val = protoreflect.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions
557*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_TypeName_field_number:
558*1c12ee1eSDan Willemsen				rawTypeName = v
559*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Options_field_number:
560*1c12ee1eSDan Willemsen				xd.unmarshalOptions(v)
561*1c12ee1eSDan Willemsen				rawOptions = appendOptions(rawOptions, v)
562*1c12ee1eSDan Willemsen			}
563*1c12ee1eSDan Willemsen		default:
564*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
565*1c12ee1eSDan Willemsen			b = b[m:]
566*1c12ee1eSDan Willemsen		}
567*1c12ee1eSDan Willemsen	}
568*1c12ee1eSDan Willemsen	if rawTypeName != nil {
569*1c12ee1eSDan Willemsen		name := makeFullName(sb, rawTypeName)
570*1c12ee1eSDan Willemsen		switch xd.L1.Kind {
571*1c12ee1eSDan Willemsen		case protoreflect.EnumKind:
572*1c12ee1eSDan Willemsen			xd.L2.Enum = PlaceholderEnum(name)
573*1c12ee1eSDan Willemsen		case protoreflect.MessageKind, protoreflect.GroupKind:
574*1c12ee1eSDan Willemsen			xd.L2.Message = PlaceholderMessage(name)
575*1c12ee1eSDan Willemsen		}
576*1c12ee1eSDan Willemsen	}
577*1c12ee1eSDan Willemsen	xd.L2.Options = xd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Field, rawOptions)
578*1c12ee1eSDan Willemsen}
579*1c12ee1eSDan Willemsen
580*1c12ee1eSDan Willemsenfunc (xd *Extension) unmarshalOptions(b []byte) {
581*1c12ee1eSDan Willemsen	for len(b) > 0 {
582*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
583*1c12ee1eSDan Willemsen		b = b[n:]
584*1c12ee1eSDan Willemsen		switch typ {
585*1c12ee1eSDan Willemsen		case protowire.VarintType:
586*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
587*1c12ee1eSDan Willemsen			b = b[m:]
588*1c12ee1eSDan Willemsen			switch num {
589*1c12ee1eSDan Willemsen			case genid.FieldOptions_Packed_field_number:
590*1c12ee1eSDan Willemsen				xd.L2.IsPacked = protowire.DecodeBool(v)
591*1c12ee1eSDan Willemsen			}
592*1c12ee1eSDan Willemsen		default:
593*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
594*1c12ee1eSDan Willemsen			b = b[m:]
595*1c12ee1eSDan Willemsen		}
596*1c12ee1eSDan Willemsen	}
597*1c12ee1eSDan Willemsen}
598*1c12ee1eSDan Willemsen
599*1c12ee1eSDan Willemsenfunc (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) {
600*1c12ee1eSDan Willemsen	var rawMethods [][]byte
601*1c12ee1eSDan Willemsen	var rawOptions []byte
602*1c12ee1eSDan Willemsen	sd.L2 = new(ServiceL2)
603*1c12ee1eSDan Willemsen	for len(b) > 0 {
604*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
605*1c12ee1eSDan Willemsen		b = b[n:]
606*1c12ee1eSDan Willemsen		switch typ {
607*1c12ee1eSDan Willemsen		case protowire.BytesType:
608*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
609*1c12ee1eSDan Willemsen			b = b[m:]
610*1c12ee1eSDan Willemsen			switch num {
611*1c12ee1eSDan Willemsen			case genid.ServiceDescriptorProto_Method_field_number:
612*1c12ee1eSDan Willemsen				rawMethods = append(rawMethods, v)
613*1c12ee1eSDan Willemsen			case genid.ServiceDescriptorProto_Options_field_number:
614*1c12ee1eSDan Willemsen				rawOptions = appendOptions(rawOptions, v)
615*1c12ee1eSDan Willemsen			}
616*1c12ee1eSDan Willemsen		default:
617*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
618*1c12ee1eSDan Willemsen			b = b[m:]
619*1c12ee1eSDan Willemsen		}
620*1c12ee1eSDan Willemsen	}
621*1c12ee1eSDan Willemsen	if len(rawMethods) > 0 {
622*1c12ee1eSDan Willemsen		sd.L2.Methods.List = make([]Method, len(rawMethods))
623*1c12ee1eSDan Willemsen		for i, b := range rawMethods {
624*1c12ee1eSDan Willemsen			sd.L2.Methods.List[i].unmarshalFull(b, sb, sd.L0.ParentFile, sd, i)
625*1c12ee1eSDan Willemsen		}
626*1c12ee1eSDan Willemsen	}
627*1c12ee1eSDan Willemsen	sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Service, rawOptions)
628*1c12ee1eSDan Willemsen}
629*1c12ee1eSDan Willemsen
630*1c12ee1eSDan Willemsenfunc (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
631*1c12ee1eSDan Willemsen	md.L0.ParentFile = pf
632*1c12ee1eSDan Willemsen	md.L0.Parent = pd
633*1c12ee1eSDan Willemsen	md.L0.Index = i
634*1c12ee1eSDan Willemsen
635*1c12ee1eSDan Willemsen	var rawOptions []byte
636*1c12ee1eSDan Willemsen	for len(b) > 0 {
637*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
638*1c12ee1eSDan Willemsen		b = b[n:]
639*1c12ee1eSDan Willemsen		switch typ {
640*1c12ee1eSDan Willemsen		case protowire.VarintType:
641*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
642*1c12ee1eSDan Willemsen			b = b[m:]
643*1c12ee1eSDan Willemsen			switch num {
644*1c12ee1eSDan Willemsen			case genid.MethodDescriptorProto_ClientStreaming_field_number:
645*1c12ee1eSDan Willemsen				md.L1.IsStreamingClient = protowire.DecodeBool(v)
646*1c12ee1eSDan Willemsen			case genid.MethodDescriptorProto_ServerStreaming_field_number:
647*1c12ee1eSDan Willemsen				md.L1.IsStreamingServer = protowire.DecodeBool(v)
648*1c12ee1eSDan Willemsen			}
649*1c12ee1eSDan Willemsen		case protowire.BytesType:
650*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
651*1c12ee1eSDan Willemsen			b = b[m:]
652*1c12ee1eSDan Willemsen			switch num {
653*1c12ee1eSDan Willemsen			case genid.MethodDescriptorProto_Name_field_number:
654*1c12ee1eSDan Willemsen				md.L0.FullName = appendFullName(sb, pd.FullName(), v)
655*1c12ee1eSDan Willemsen			case genid.MethodDescriptorProto_InputType_field_number:
656*1c12ee1eSDan Willemsen				md.L1.Input = PlaceholderMessage(makeFullName(sb, v))
657*1c12ee1eSDan Willemsen			case genid.MethodDescriptorProto_OutputType_field_number:
658*1c12ee1eSDan Willemsen				md.L1.Output = PlaceholderMessage(makeFullName(sb, v))
659*1c12ee1eSDan Willemsen			case genid.MethodDescriptorProto_Options_field_number:
660*1c12ee1eSDan Willemsen				rawOptions = appendOptions(rawOptions, v)
661*1c12ee1eSDan Willemsen			}
662*1c12ee1eSDan Willemsen		default:
663*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
664*1c12ee1eSDan Willemsen			b = b[m:]
665*1c12ee1eSDan Willemsen		}
666*1c12ee1eSDan Willemsen	}
667*1c12ee1eSDan Willemsen	md.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Method, rawOptions)
668*1c12ee1eSDan Willemsen}
669*1c12ee1eSDan Willemsen
670*1c12ee1eSDan Willemsen// appendOptions appends src to dst, where the returned slice is never nil.
671*1c12ee1eSDan Willemsen// This is necessary to distinguish between empty and unpopulated options.
672*1c12ee1eSDan Willemsenfunc appendOptions(dst, src []byte) []byte {
673*1c12ee1eSDan Willemsen	if dst == nil {
674*1c12ee1eSDan Willemsen		dst = []byte{}
675*1c12ee1eSDan Willemsen	}
676*1c12ee1eSDan Willemsen	return append(dst, src...)
677*1c12ee1eSDan Willemsen}
678*1c12ee1eSDan Willemsen
679*1c12ee1eSDan Willemsen// optionsUnmarshaler constructs a lazy unmarshal function for an options message.
680*1c12ee1eSDan Willemsen//
681*1c12ee1eSDan Willemsen// The type of message to unmarshal to is passed as a pointer since the
682*1c12ee1eSDan Willemsen// vars in descopts may not yet be populated at the time this function is called.
683*1c12ee1eSDan Willemsenfunc (db *Builder) optionsUnmarshaler(p *protoreflect.ProtoMessage, b []byte) func() protoreflect.ProtoMessage {
684*1c12ee1eSDan Willemsen	if b == nil {
685*1c12ee1eSDan Willemsen		return nil
686*1c12ee1eSDan Willemsen	}
687*1c12ee1eSDan Willemsen	var opts protoreflect.ProtoMessage
688*1c12ee1eSDan Willemsen	var once sync.Once
689*1c12ee1eSDan Willemsen	return func() protoreflect.ProtoMessage {
690*1c12ee1eSDan Willemsen		once.Do(func() {
691*1c12ee1eSDan Willemsen			if *p == nil {
692*1c12ee1eSDan Willemsen				panic("Descriptor.Options called without importing the descriptor package")
693*1c12ee1eSDan Willemsen			}
694*1c12ee1eSDan Willemsen			opts = reflect.New(reflect.TypeOf(*p).Elem()).Interface().(protoreflect.ProtoMessage)
695*1c12ee1eSDan Willemsen			if err := (proto.UnmarshalOptions{
696*1c12ee1eSDan Willemsen				AllowPartial: true,
697*1c12ee1eSDan Willemsen				Resolver:     db.TypeResolver,
698*1c12ee1eSDan Willemsen			}).Unmarshal(b, opts); err != nil {
699*1c12ee1eSDan Willemsen				panic(err)
700*1c12ee1eSDan Willemsen			}
701*1c12ee1eSDan Willemsen		})
702*1c12ee1eSDan Willemsen		return opts
703*1c12ee1eSDan Willemsen	}
704*1c12ee1eSDan Willemsen}
705