xref: /aosp_15_r20/external/golang-protobuf/internal/filedesc/desc_init.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	"sync"
9*1c12ee1eSDan Willemsen
10*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/encoding/protowire"
11*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/genid"
12*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/strs"
13*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/reflect/protoreflect"
14*1c12ee1eSDan Willemsen)
15*1c12ee1eSDan Willemsen
16*1c12ee1eSDan Willemsen// fileRaw is a data struct used when initializing a file descriptor from
17*1c12ee1eSDan Willemsen// a raw FileDescriptorProto.
18*1c12ee1eSDan Willemsentype fileRaw struct {
19*1c12ee1eSDan Willemsen	builder       Builder
20*1c12ee1eSDan Willemsen	allEnums      []Enum
21*1c12ee1eSDan Willemsen	allMessages   []Message
22*1c12ee1eSDan Willemsen	allExtensions []Extension
23*1c12ee1eSDan Willemsen	allServices   []Service
24*1c12ee1eSDan Willemsen}
25*1c12ee1eSDan Willemsen
26*1c12ee1eSDan Willemsenfunc newRawFile(db Builder) *File {
27*1c12ee1eSDan Willemsen	fd := &File{fileRaw: fileRaw{builder: db}}
28*1c12ee1eSDan Willemsen	fd.initDecls(db.NumEnums, db.NumMessages, db.NumExtensions, db.NumServices)
29*1c12ee1eSDan Willemsen	fd.unmarshalSeed(db.RawDescriptor)
30*1c12ee1eSDan Willemsen
31*1c12ee1eSDan Willemsen	// Extended message targets are eagerly resolved since registration
32*1c12ee1eSDan Willemsen	// needs this information at program init time.
33*1c12ee1eSDan Willemsen	for i := range fd.allExtensions {
34*1c12ee1eSDan Willemsen		xd := &fd.allExtensions[i]
35*1c12ee1eSDan Willemsen		xd.L1.Extendee = fd.resolveMessageDependency(xd.L1.Extendee, listExtTargets, int32(i))
36*1c12ee1eSDan Willemsen	}
37*1c12ee1eSDan Willemsen
38*1c12ee1eSDan Willemsen	fd.checkDecls()
39*1c12ee1eSDan Willemsen	return fd
40*1c12ee1eSDan Willemsen}
41*1c12ee1eSDan Willemsen
42*1c12ee1eSDan Willemsen// initDecls pre-allocates slices for the exact number of enums, messages
43*1c12ee1eSDan Willemsen// (including map entries), extensions, and services declared in the proto file.
44*1c12ee1eSDan Willemsen// This is done to avoid regrowing the slice, which would change the address
45*1c12ee1eSDan Willemsen// for any previously seen declaration.
46*1c12ee1eSDan Willemsen//
47*1c12ee1eSDan Willemsen// The alloc methods "allocates" slices by pulling from the capacity.
48*1c12ee1eSDan Willemsenfunc (fd *File) initDecls(numEnums, numMessages, numExtensions, numServices int32) {
49*1c12ee1eSDan Willemsen	fd.allEnums = make([]Enum, 0, numEnums)
50*1c12ee1eSDan Willemsen	fd.allMessages = make([]Message, 0, numMessages)
51*1c12ee1eSDan Willemsen	fd.allExtensions = make([]Extension, 0, numExtensions)
52*1c12ee1eSDan Willemsen	fd.allServices = make([]Service, 0, numServices)
53*1c12ee1eSDan Willemsen}
54*1c12ee1eSDan Willemsen
55*1c12ee1eSDan Willemsenfunc (fd *File) allocEnums(n int) []Enum {
56*1c12ee1eSDan Willemsen	total := len(fd.allEnums)
57*1c12ee1eSDan Willemsen	es := fd.allEnums[total : total+n]
58*1c12ee1eSDan Willemsen	fd.allEnums = fd.allEnums[:total+n]
59*1c12ee1eSDan Willemsen	return es
60*1c12ee1eSDan Willemsen}
61*1c12ee1eSDan Willemsenfunc (fd *File) allocMessages(n int) []Message {
62*1c12ee1eSDan Willemsen	total := len(fd.allMessages)
63*1c12ee1eSDan Willemsen	ms := fd.allMessages[total : total+n]
64*1c12ee1eSDan Willemsen	fd.allMessages = fd.allMessages[:total+n]
65*1c12ee1eSDan Willemsen	return ms
66*1c12ee1eSDan Willemsen}
67*1c12ee1eSDan Willemsenfunc (fd *File) allocExtensions(n int) []Extension {
68*1c12ee1eSDan Willemsen	total := len(fd.allExtensions)
69*1c12ee1eSDan Willemsen	xs := fd.allExtensions[total : total+n]
70*1c12ee1eSDan Willemsen	fd.allExtensions = fd.allExtensions[:total+n]
71*1c12ee1eSDan Willemsen	return xs
72*1c12ee1eSDan Willemsen}
73*1c12ee1eSDan Willemsenfunc (fd *File) allocServices(n int) []Service {
74*1c12ee1eSDan Willemsen	total := len(fd.allServices)
75*1c12ee1eSDan Willemsen	xs := fd.allServices[total : total+n]
76*1c12ee1eSDan Willemsen	fd.allServices = fd.allServices[:total+n]
77*1c12ee1eSDan Willemsen	return xs
78*1c12ee1eSDan Willemsen}
79*1c12ee1eSDan Willemsen
80*1c12ee1eSDan Willemsen// checkDecls performs a sanity check that the expected number of expected
81*1c12ee1eSDan Willemsen// declarations matches the number that were found in the descriptor proto.
82*1c12ee1eSDan Willemsenfunc (fd *File) checkDecls() {
83*1c12ee1eSDan Willemsen	switch {
84*1c12ee1eSDan Willemsen	case len(fd.allEnums) != cap(fd.allEnums):
85*1c12ee1eSDan Willemsen	case len(fd.allMessages) != cap(fd.allMessages):
86*1c12ee1eSDan Willemsen	case len(fd.allExtensions) != cap(fd.allExtensions):
87*1c12ee1eSDan Willemsen	case len(fd.allServices) != cap(fd.allServices):
88*1c12ee1eSDan Willemsen	default:
89*1c12ee1eSDan Willemsen		return
90*1c12ee1eSDan Willemsen	}
91*1c12ee1eSDan Willemsen	panic("mismatching cardinality")
92*1c12ee1eSDan Willemsen}
93*1c12ee1eSDan Willemsen
94*1c12ee1eSDan Willemsenfunc (fd *File) unmarshalSeed(b []byte) {
95*1c12ee1eSDan Willemsen	sb := getBuilder()
96*1c12ee1eSDan Willemsen	defer putBuilder(sb)
97*1c12ee1eSDan Willemsen
98*1c12ee1eSDan Willemsen	var prevField protoreflect.FieldNumber
99*1c12ee1eSDan Willemsen	var numEnums, numMessages, numExtensions, numServices int
100*1c12ee1eSDan Willemsen	var posEnums, posMessages, posExtensions, posServices int
101*1c12ee1eSDan Willemsen	b0 := b
102*1c12ee1eSDan Willemsen	for len(b) > 0 {
103*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
104*1c12ee1eSDan Willemsen		b = b[n:]
105*1c12ee1eSDan Willemsen		switch typ {
106*1c12ee1eSDan Willemsen		case protowire.BytesType:
107*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
108*1c12ee1eSDan Willemsen			b = b[m:]
109*1c12ee1eSDan Willemsen			switch num {
110*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_Syntax_field_number:
111*1c12ee1eSDan Willemsen				switch string(v) {
112*1c12ee1eSDan Willemsen				case "proto2":
113*1c12ee1eSDan Willemsen					fd.L1.Syntax = protoreflect.Proto2
114*1c12ee1eSDan Willemsen				case "proto3":
115*1c12ee1eSDan Willemsen					fd.L1.Syntax = protoreflect.Proto3
116*1c12ee1eSDan Willemsen				default:
117*1c12ee1eSDan Willemsen					panic("invalid syntax")
118*1c12ee1eSDan Willemsen				}
119*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_Name_field_number:
120*1c12ee1eSDan Willemsen				fd.L1.Path = sb.MakeString(v)
121*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_Package_field_number:
122*1c12ee1eSDan Willemsen				fd.L1.Package = protoreflect.FullName(sb.MakeString(v))
123*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_EnumType_field_number:
124*1c12ee1eSDan Willemsen				if prevField != genid.FileDescriptorProto_EnumType_field_number {
125*1c12ee1eSDan Willemsen					if numEnums > 0 {
126*1c12ee1eSDan Willemsen						panic("non-contiguous repeated field")
127*1c12ee1eSDan Willemsen					}
128*1c12ee1eSDan Willemsen					posEnums = len(b0) - len(b) - n - m
129*1c12ee1eSDan Willemsen				}
130*1c12ee1eSDan Willemsen				numEnums++
131*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_MessageType_field_number:
132*1c12ee1eSDan Willemsen				if prevField != genid.FileDescriptorProto_MessageType_field_number {
133*1c12ee1eSDan Willemsen					if numMessages > 0 {
134*1c12ee1eSDan Willemsen						panic("non-contiguous repeated field")
135*1c12ee1eSDan Willemsen					}
136*1c12ee1eSDan Willemsen					posMessages = len(b0) - len(b) - n - m
137*1c12ee1eSDan Willemsen				}
138*1c12ee1eSDan Willemsen				numMessages++
139*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_Extension_field_number:
140*1c12ee1eSDan Willemsen				if prevField != genid.FileDescriptorProto_Extension_field_number {
141*1c12ee1eSDan Willemsen					if numExtensions > 0 {
142*1c12ee1eSDan Willemsen						panic("non-contiguous repeated field")
143*1c12ee1eSDan Willemsen					}
144*1c12ee1eSDan Willemsen					posExtensions = len(b0) - len(b) - n - m
145*1c12ee1eSDan Willemsen				}
146*1c12ee1eSDan Willemsen				numExtensions++
147*1c12ee1eSDan Willemsen			case genid.FileDescriptorProto_Service_field_number:
148*1c12ee1eSDan Willemsen				if prevField != genid.FileDescriptorProto_Service_field_number {
149*1c12ee1eSDan Willemsen					if numServices > 0 {
150*1c12ee1eSDan Willemsen						panic("non-contiguous repeated field")
151*1c12ee1eSDan Willemsen					}
152*1c12ee1eSDan Willemsen					posServices = len(b0) - len(b) - n - m
153*1c12ee1eSDan Willemsen				}
154*1c12ee1eSDan Willemsen				numServices++
155*1c12ee1eSDan Willemsen			}
156*1c12ee1eSDan Willemsen			prevField = num
157*1c12ee1eSDan Willemsen		default:
158*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
159*1c12ee1eSDan Willemsen			b = b[m:]
160*1c12ee1eSDan Willemsen			prevField = -1 // ignore known field numbers of unknown wire type
161*1c12ee1eSDan Willemsen		}
162*1c12ee1eSDan Willemsen	}
163*1c12ee1eSDan Willemsen
164*1c12ee1eSDan Willemsen	// If syntax is missing, it is assumed to be proto2.
165*1c12ee1eSDan Willemsen	if fd.L1.Syntax == 0 {
166*1c12ee1eSDan Willemsen		fd.L1.Syntax = protoreflect.Proto2
167*1c12ee1eSDan Willemsen	}
168*1c12ee1eSDan Willemsen
169*1c12ee1eSDan Willemsen	// Must allocate all declarations before parsing each descriptor type
170*1c12ee1eSDan Willemsen	// to ensure we handled all descriptors in "flattened ordering".
171*1c12ee1eSDan Willemsen	if numEnums > 0 {
172*1c12ee1eSDan Willemsen		fd.L1.Enums.List = fd.allocEnums(numEnums)
173*1c12ee1eSDan Willemsen	}
174*1c12ee1eSDan Willemsen	if numMessages > 0 {
175*1c12ee1eSDan Willemsen		fd.L1.Messages.List = fd.allocMessages(numMessages)
176*1c12ee1eSDan Willemsen	}
177*1c12ee1eSDan Willemsen	if numExtensions > 0 {
178*1c12ee1eSDan Willemsen		fd.L1.Extensions.List = fd.allocExtensions(numExtensions)
179*1c12ee1eSDan Willemsen	}
180*1c12ee1eSDan Willemsen	if numServices > 0 {
181*1c12ee1eSDan Willemsen		fd.L1.Services.List = fd.allocServices(numServices)
182*1c12ee1eSDan Willemsen	}
183*1c12ee1eSDan Willemsen
184*1c12ee1eSDan Willemsen	if numEnums > 0 {
185*1c12ee1eSDan Willemsen		b := b0[posEnums:]
186*1c12ee1eSDan Willemsen		for i := range fd.L1.Enums.List {
187*1c12ee1eSDan Willemsen			_, n := protowire.ConsumeVarint(b)
188*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b[n:])
189*1c12ee1eSDan Willemsen			fd.L1.Enums.List[i].unmarshalSeed(v, sb, fd, fd, i)
190*1c12ee1eSDan Willemsen			b = b[n+m:]
191*1c12ee1eSDan Willemsen		}
192*1c12ee1eSDan Willemsen	}
193*1c12ee1eSDan Willemsen	if numMessages > 0 {
194*1c12ee1eSDan Willemsen		b := b0[posMessages:]
195*1c12ee1eSDan Willemsen		for i := range fd.L1.Messages.List {
196*1c12ee1eSDan Willemsen			_, n := protowire.ConsumeVarint(b)
197*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b[n:])
198*1c12ee1eSDan Willemsen			fd.L1.Messages.List[i].unmarshalSeed(v, sb, fd, fd, i)
199*1c12ee1eSDan Willemsen			b = b[n+m:]
200*1c12ee1eSDan Willemsen		}
201*1c12ee1eSDan Willemsen	}
202*1c12ee1eSDan Willemsen	if numExtensions > 0 {
203*1c12ee1eSDan Willemsen		b := b0[posExtensions:]
204*1c12ee1eSDan Willemsen		for i := range fd.L1.Extensions.List {
205*1c12ee1eSDan Willemsen			_, n := protowire.ConsumeVarint(b)
206*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b[n:])
207*1c12ee1eSDan Willemsen			fd.L1.Extensions.List[i].unmarshalSeed(v, sb, fd, fd, i)
208*1c12ee1eSDan Willemsen			b = b[n+m:]
209*1c12ee1eSDan Willemsen		}
210*1c12ee1eSDan Willemsen	}
211*1c12ee1eSDan Willemsen	if numServices > 0 {
212*1c12ee1eSDan Willemsen		b := b0[posServices:]
213*1c12ee1eSDan Willemsen		for i := range fd.L1.Services.List {
214*1c12ee1eSDan Willemsen			_, n := protowire.ConsumeVarint(b)
215*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b[n:])
216*1c12ee1eSDan Willemsen			fd.L1.Services.List[i].unmarshalSeed(v, sb, fd, fd, i)
217*1c12ee1eSDan Willemsen			b = b[n+m:]
218*1c12ee1eSDan Willemsen		}
219*1c12ee1eSDan Willemsen	}
220*1c12ee1eSDan Willemsen}
221*1c12ee1eSDan Willemsen
222*1c12ee1eSDan Willemsenfunc (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
223*1c12ee1eSDan Willemsen	ed.L0.ParentFile = pf
224*1c12ee1eSDan Willemsen	ed.L0.Parent = pd
225*1c12ee1eSDan Willemsen	ed.L0.Index = i
226*1c12ee1eSDan Willemsen
227*1c12ee1eSDan Willemsen	var numValues int
228*1c12ee1eSDan Willemsen	for b := b; len(b) > 0; {
229*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
230*1c12ee1eSDan Willemsen		b = b[n:]
231*1c12ee1eSDan Willemsen		switch typ {
232*1c12ee1eSDan Willemsen		case protowire.BytesType:
233*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
234*1c12ee1eSDan Willemsen			b = b[m:]
235*1c12ee1eSDan Willemsen			switch num {
236*1c12ee1eSDan Willemsen			case genid.EnumDescriptorProto_Name_field_number:
237*1c12ee1eSDan Willemsen				ed.L0.FullName = appendFullName(sb, pd.FullName(), v)
238*1c12ee1eSDan Willemsen			case genid.EnumDescriptorProto_Value_field_number:
239*1c12ee1eSDan Willemsen				numValues++
240*1c12ee1eSDan Willemsen			}
241*1c12ee1eSDan Willemsen		default:
242*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
243*1c12ee1eSDan Willemsen			b = b[m:]
244*1c12ee1eSDan Willemsen		}
245*1c12ee1eSDan Willemsen	}
246*1c12ee1eSDan Willemsen
247*1c12ee1eSDan Willemsen	// Only construct enum value descriptors for top-level enums since
248*1c12ee1eSDan Willemsen	// they are needed for registration.
249*1c12ee1eSDan Willemsen	if pd != pf {
250*1c12ee1eSDan Willemsen		return
251*1c12ee1eSDan Willemsen	}
252*1c12ee1eSDan Willemsen	ed.L1.eagerValues = true
253*1c12ee1eSDan Willemsen	ed.L2 = new(EnumL2)
254*1c12ee1eSDan Willemsen	ed.L2.Values.List = make([]EnumValue, numValues)
255*1c12ee1eSDan Willemsen	for i := 0; len(b) > 0; {
256*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
257*1c12ee1eSDan Willemsen		b = b[n:]
258*1c12ee1eSDan Willemsen		switch typ {
259*1c12ee1eSDan Willemsen		case protowire.BytesType:
260*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
261*1c12ee1eSDan Willemsen			b = b[m:]
262*1c12ee1eSDan Willemsen			switch num {
263*1c12ee1eSDan Willemsen			case genid.EnumDescriptorProto_Value_field_number:
264*1c12ee1eSDan Willemsen				ed.L2.Values.List[i].unmarshalFull(v, sb, pf, ed, i)
265*1c12ee1eSDan Willemsen				i++
266*1c12ee1eSDan Willemsen			}
267*1c12ee1eSDan Willemsen		default:
268*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
269*1c12ee1eSDan Willemsen			b = b[m:]
270*1c12ee1eSDan Willemsen		}
271*1c12ee1eSDan Willemsen	}
272*1c12ee1eSDan Willemsen}
273*1c12ee1eSDan Willemsen
274*1c12ee1eSDan Willemsenfunc (md *Message) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
275*1c12ee1eSDan Willemsen	md.L0.ParentFile = pf
276*1c12ee1eSDan Willemsen	md.L0.Parent = pd
277*1c12ee1eSDan Willemsen	md.L0.Index = i
278*1c12ee1eSDan Willemsen
279*1c12ee1eSDan Willemsen	var prevField protoreflect.FieldNumber
280*1c12ee1eSDan Willemsen	var numEnums, numMessages, numExtensions int
281*1c12ee1eSDan Willemsen	var posEnums, posMessages, posExtensions int
282*1c12ee1eSDan Willemsen	b0 := b
283*1c12ee1eSDan Willemsen	for len(b) > 0 {
284*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
285*1c12ee1eSDan Willemsen		b = b[n:]
286*1c12ee1eSDan Willemsen		switch typ {
287*1c12ee1eSDan Willemsen		case protowire.BytesType:
288*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
289*1c12ee1eSDan Willemsen			b = b[m:]
290*1c12ee1eSDan Willemsen			switch num {
291*1c12ee1eSDan Willemsen			case genid.DescriptorProto_Name_field_number:
292*1c12ee1eSDan Willemsen				md.L0.FullName = appendFullName(sb, pd.FullName(), v)
293*1c12ee1eSDan Willemsen			case genid.DescriptorProto_EnumType_field_number:
294*1c12ee1eSDan Willemsen				if prevField != genid.DescriptorProto_EnumType_field_number {
295*1c12ee1eSDan Willemsen					if numEnums > 0 {
296*1c12ee1eSDan Willemsen						panic("non-contiguous repeated field")
297*1c12ee1eSDan Willemsen					}
298*1c12ee1eSDan Willemsen					posEnums = len(b0) - len(b) - n - m
299*1c12ee1eSDan Willemsen				}
300*1c12ee1eSDan Willemsen				numEnums++
301*1c12ee1eSDan Willemsen			case genid.DescriptorProto_NestedType_field_number:
302*1c12ee1eSDan Willemsen				if prevField != genid.DescriptorProto_NestedType_field_number {
303*1c12ee1eSDan Willemsen					if numMessages > 0 {
304*1c12ee1eSDan Willemsen						panic("non-contiguous repeated field")
305*1c12ee1eSDan Willemsen					}
306*1c12ee1eSDan Willemsen					posMessages = len(b0) - len(b) - n - m
307*1c12ee1eSDan Willemsen				}
308*1c12ee1eSDan Willemsen				numMessages++
309*1c12ee1eSDan Willemsen			case genid.DescriptorProto_Extension_field_number:
310*1c12ee1eSDan Willemsen				if prevField != genid.DescriptorProto_Extension_field_number {
311*1c12ee1eSDan Willemsen					if numExtensions > 0 {
312*1c12ee1eSDan Willemsen						panic("non-contiguous repeated field")
313*1c12ee1eSDan Willemsen					}
314*1c12ee1eSDan Willemsen					posExtensions = len(b0) - len(b) - n - m
315*1c12ee1eSDan Willemsen				}
316*1c12ee1eSDan Willemsen				numExtensions++
317*1c12ee1eSDan Willemsen			case genid.DescriptorProto_Options_field_number:
318*1c12ee1eSDan Willemsen				md.unmarshalSeedOptions(v)
319*1c12ee1eSDan Willemsen			}
320*1c12ee1eSDan Willemsen			prevField = num
321*1c12ee1eSDan Willemsen		default:
322*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
323*1c12ee1eSDan Willemsen			b = b[m:]
324*1c12ee1eSDan Willemsen			prevField = -1 // ignore known field numbers of unknown wire type
325*1c12ee1eSDan Willemsen		}
326*1c12ee1eSDan Willemsen	}
327*1c12ee1eSDan Willemsen
328*1c12ee1eSDan Willemsen	// Must allocate all declarations before parsing each descriptor type
329*1c12ee1eSDan Willemsen	// to ensure we handled all descriptors in "flattened ordering".
330*1c12ee1eSDan Willemsen	if numEnums > 0 {
331*1c12ee1eSDan Willemsen		md.L1.Enums.List = pf.allocEnums(numEnums)
332*1c12ee1eSDan Willemsen	}
333*1c12ee1eSDan Willemsen	if numMessages > 0 {
334*1c12ee1eSDan Willemsen		md.L1.Messages.List = pf.allocMessages(numMessages)
335*1c12ee1eSDan Willemsen	}
336*1c12ee1eSDan Willemsen	if numExtensions > 0 {
337*1c12ee1eSDan Willemsen		md.L1.Extensions.List = pf.allocExtensions(numExtensions)
338*1c12ee1eSDan Willemsen	}
339*1c12ee1eSDan Willemsen
340*1c12ee1eSDan Willemsen	if numEnums > 0 {
341*1c12ee1eSDan Willemsen		b := b0[posEnums:]
342*1c12ee1eSDan Willemsen		for i := range md.L1.Enums.List {
343*1c12ee1eSDan Willemsen			_, n := protowire.ConsumeVarint(b)
344*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b[n:])
345*1c12ee1eSDan Willemsen			md.L1.Enums.List[i].unmarshalSeed(v, sb, pf, md, i)
346*1c12ee1eSDan Willemsen			b = b[n+m:]
347*1c12ee1eSDan Willemsen		}
348*1c12ee1eSDan Willemsen	}
349*1c12ee1eSDan Willemsen	if numMessages > 0 {
350*1c12ee1eSDan Willemsen		b := b0[posMessages:]
351*1c12ee1eSDan Willemsen		for i := range md.L1.Messages.List {
352*1c12ee1eSDan Willemsen			_, n := protowire.ConsumeVarint(b)
353*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b[n:])
354*1c12ee1eSDan Willemsen			md.L1.Messages.List[i].unmarshalSeed(v, sb, pf, md, i)
355*1c12ee1eSDan Willemsen			b = b[n+m:]
356*1c12ee1eSDan Willemsen		}
357*1c12ee1eSDan Willemsen	}
358*1c12ee1eSDan Willemsen	if numExtensions > 0 {
359*1c12ee1eSDan Willemsen		b := b0[posExtensions:]
360*1c12ee1eSDan Willemsen		for i := range md.L1.Extensions.List {
361*1c12ee1eSDan Willemsen			_, n := protowire.ConsumeVarint(b)
362*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b[n:])
363*1c12ee1eSDan Willemsen			md.L1.Extensions.List[i].unmarshalSeed(v, sb, pf, md, i)
364*1c12ee1eSDan Willemsen			b = b[n+m:]
365*1c12ee1eSDan Willemsen		}
366*1c12ee1eSDan Willemsen	}
367*1c12ee1eSDan Willemsen}
368*1c12ee1eSDan Willemsen
369*1c12ee1eSDan Willemsenfunc (md *Message) unmarshalSeedOptions(b []byte) {
370*1c12ee1eSDan Willemsen	for len(b) > 0 {
371*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
372*1c12ee1eSDan Willemsen		b = b[n:]
373*1c12ee1eSDan Willemsen		switch typ {
374*1c12ee1eSDan Willemsen		case protowire.VarintType:
375*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
376*1c12ee1eSDan Willemsen			b = b[m:]
377*1c12ee1eSDan Willemsen			switch num {
378*1c12ee1eSDan Willemsen			case genid.MessageOptions_MapEntry_field_number:
379*1c12ee1eSDan Willemsen				md.L1.IsMapEntry = protowire.DecodeBool(v)
380*1c12ee1eSDan Willemsen			case genid.MessageOptions_MessageSetWireFormat_field_number:
381*1c12ee1eSDan Willemsen				md.L1.IsMessageSet = protowire.DecodeBool(v)
382*1c12ee1eSDan Willemsen			}
383*1c12ee1eSDan Willemsen		default:
384*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
385*1c12ee1eSDan Willemsen			b = b[m:]
386*1c12ee1eSDan Willemsen		}
387*1c12ee1eSDan Willemsen	}
388*1c12ee1eSDan Willemsen}
389*1c12ee1eSDan Willemsen
390*1c12ee1eSDan Willemsenfunc (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
391*1c12ee1eSDan Willemsen	xd.L0.ParentFile = pf
392*1c12ee1eSDan Willemsen	xd.L0.Parent = pd
393*1c12ee1eSDan Willemsen	xd.L0.Index = i
394*1c12ee1eSDan Willemsen
395*1c12ee1eSDan Willemsen	for len(b) > 0 {
396*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
397*1c12ee1eSDan Willemsen		b = b[n:]
398*1c12ee1eSDan Willemsen		switch typ {
399*1c12ee1eSDan Willemsen		case protowire.VarintType:
400*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeVarint(b)
401*1c12ee1eSDan Willemsen			b = b[m:]
402*1c12ee1eSDan Willemsen			switch num {
403*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Number_field_number:
404*1c12ee1eSDan Willemsen				xd.L1.Number = protoreflect.FieldNumber(v)
405*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Label_field_number:
406*1c12ee1eSDan Willemsen				xd.L1.Cardinality = protoreflect.Cardinality(v)
407*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Type_field_number:
408*1c12ee1eSDan Willemsen				xd.L1.Kind = protoreflect.Kind(v)
409*1c12ee1eSDan Willemsen			}
410*1c12ee1eSDan Willemsen		case protowire.BytesType:
411*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
412*1c12ee1eSDan Willemsen			b = b[m:]
413*1c12ee1eSDan Willemsen			switch num {
414*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Name_field_number:
415*1c12ee1eSDan Willemsen				xd.L0.FullName = appendFullName(sb, pd.FullName(), v)
416*1c12ee1eSDan Willemsen			case genid.FieldDescriptorProto_Extendee_field_number:
417*1c12ee1eSDan Willemsen				xd.L1.Extendee = PlaceholderMessage(makeFullName(sb, v))
418*1c12ee1eSDan Willemsen			}
419*1c12ee1eSDan Willemsen		default:
420*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
421*1c12ee1eSDan Willemsen			b = b[m:]
422*1c12ee1eSDan Willemsen		}
423*1c12ee1eSDan Willemsen	}
424*1c12ee1eSDan Willemsen}
425*1c12ee1eSDan Willemsen
426*1c12ee1eSDan Willemsenfunc (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
427*1c12ee1eSDan Willemsen	sd.L0.ParentFile = pf
428*1c12ee1eSDan Willemsen	sd.L0.Parent = pd
429*1c12ee1eSDan Willemsen	sd.L0.Index = i
430*1c12ee1eSDan Willemsen
431*1c12ee1eSDan Willemsen	for len(b) > 0 {
432*1c12ee1eSDan Willemsen		num, typ, n := protowire.ConsumeTag(b)
433*1c12ee1eSDan Willemsen		b = b[n:]
434*1c12ee1eSDan Willemsen		switch typ {
435*1c12ee1eSDan Willemsen		case protowire.BytesType:
436*1c12ee1eSDan Willemsen			v, m := protowire.ConsumeBytes(b)
437*1c12ee1eSDan Willemsen			b = b[m:]
438*1c12ee1eSDan Willemsen			switch num {
439*1c12ee1eSDan Willemsen			case genid.ServiceDescriptorProto_Name_field_number:
440*1c12ee1eSDan Willemsen				sd.L0.FullName = appendFullName(sb, pd.FullName(), v)
441*1c12ee1eSDan Willemsen			}
442*1c12ee1eSDan Willemsen		default:
443*1c12ee1eSDan Willemsen			m := protowire.ConsumeFieldValue(num, typ, b)
444*1c12ee1eSDan Willemsen			b = b[m:]
445*1c12ee1eSDan Willemsen		}
446*1c12ee1eSDan Willemsen	}
447*1c12ee1eSDan Willemsen}
448*1c12ee1eSDan Willemsen
449*1c12ee1eSDan Willemsenvar nameBuilderPool = sync.Pool{
450*1c12ee1eSDan Willemsen	New: func() interface{} { return new(strs.Builder) },
451*1c12ee1eSDan Willemsen}
452*1c12ee1eSDan Willemsen
453*1c12ee1eSDan Willemsenfunc getBuilder() *strs.Builder {
454*1c12ee1eSDan Willemsen	return nameBuilderPool.Get().(*strs.Builder)
455*1c12ee1eSDan Willemsen}
456*1c12ee1eSDan Willemsenfunc putBuilder(b *strs.Builder) {
457*1c12ee1eSDan Willemsen	nameBuilderPool.Put(b)
458*1c12ee1eSDan Willemsen}
459*1c12ee1eSDan Willemsen
460*1c12ee1eSDan Willemsen// makeFullName converts b to a protoreflect.FullName,
461*1c12ee1eSDan Willemsen// where b must start with a leading dot.
462*1c12ee1eSDan Willemsenfunc makeFullName(sb *strs.Builder, b []byte) protoreflect.FullName {
463*1c12ee1eSDan Willemsen	if len(b) == 0 || b[0] != '.' {
464*1c12ee1eSDan Willemsen		panic("name reference must be fully qualified")
465*1c12ee1eSDan Willemsen	}
466*1c12ee1eSDan Willemsen	return protoreflect.FullName(sb.MakeString(b[1:]))
467*1c12ee1eSDan Willemsen}
468*1c12ee1eSDan Willemsen
469*1c12ee1eSDan Willemsenfunc appendFullName(sb *strs.Builder, prefix protoreflect.FullName, suffix []byte) protoreflect.FullName {
470*1c12ee1eSDan Willemsen	return sb.AppendFullName(prefix, protoreflect.Name(strs.UnsafeString(suffix)))
471*1c12ee1eSDan Willemsen}
472