...
1
2
3
4
5
6
7
8
9 package filedesc
10
11 import (
12 "google.golang.org/protobuf/encoding/protowire"
13 "google.golang.org/protobuf/internal/genid"
14 "google.golang.org/protobuf/reflect/protoreflect"
15 "google.golang.org/protobuf/reflect/protoregistry"
16 )
17
18
19 type Builder struct {
20
21 GoPackagePath string
22
23
24
25 RawDescriptor []byte
26
27
28 NumEnums int32
29
30
31 NumMessages int32
32
33 NumExtensions int32
34
35 NumServices int32
36
37
38
39 TypeResolver interface {
40 protoregistry.ExtensionTypeResolver
41 }
42
43
44
45
46 FileRegistry interface {
47 FindFileByPath(string) (protoreflect.FileDescriptor, error)
48 FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error)
49 RegisterFile(protoreflect.FileDescriptor) error
50 }
51 }
52
53
54
55
56 type resolverByIndex interface {
57 FindEnumByIndex(int32, int32, []Enum, []Message) protoreflect.EnumDescriptor
58 FindMessageByIndex(int32, int32, []Enum, []Message) protoreflect.MessageDescriptor
59 }
60
61
62 const (
63 listFieldDeps int32 = iota
64 listExtTargets
65 listExtDeps
66 listMethInDeps
67 listMethOutDeps
68 )
69
70
71 type Out struct {
72 File protoreflect.FileDescriptor
73
74
75 Enums []Enum
76
77
78 Messages []Message
79
80 Extensions []Extension
81
82 Services []Service
83 }
84
85
86
87
88
89
90
91 func (db Builder) Build() (out Out) {
92
93 if db.NumEnums+db.NumMessages+db.NumExtensions+db.NumServices == 0 {
94 db.unmarshalCounts(db.RawDescriptor, true)
95 }
96
97
98 if db.TypeResolver == nil {
99 db.TypeResolver = protoregistry.GlobalTypes
100 }
101 if db.FileRegistry == nil {
102 db.FileRegistry = protoregistry.GlobalFiles
103 }
104
105 fd := newRawFile(db)
106 out.File = fd
107 out.Enums = fd.allEnums
108 out.Messages = fd.allMessages
109 out.Extensions = fd.allExtensions
110 out.Services = fd.allServices
111
112 if err := db.FileRegistry.RegisterFile(fd); err != nil {
113 panic(err)
114 }
115 return out
116 }
117
118
119
120
121 func (db *Builder) unmarshalCounts(b []byte, isFile bool) {
122 for len(b) > 0 {
123 num, typ, n := protowire.ConsumeTag(b)
124 b = b[n:]
125 switch typ {
126 case protowire.BytesType:
127 v, m := protowire.ConsumeBytes(b)
128 b = b[m:]
129 if isFile {
130 switch num {
131 case genid.FileDescriptorProto_EnumType_field_number:
132 db.NumEnums++
133 case genid.FileDescriptorProto_MessageType_field_number:
134 db.unmarshalCounts(v, false)
135 db.NumMessages++
136 case genid.FileDescriptorProto_Extension_field_number:
137 db.NumExtensions++
138 case genid.FileDescriptorProto_Service_field_number:
139 db.NumServices++
140 }
141 } else {
142 switch num {
143 case genid.DescriptorProto_EnumType_field_number:
144 db.NumEnums++
145 case genid.DescriptorProto_NestedType_field_number:
146 db.unmarshalCounts(v, false)
147 db.NumMessages++
148 case genid.DescriptorProto_Extension_field_number:
149 db.NumExtensions++
150 }
151 }
152 default:
153 m := protowire.ConsumeFieldValue(num, typ, b)
154 b = b[m:]
155 }
156 }
157 }
158
View as plain text