1
1
package main
2
2
3
3
import (
4
- "bytes"
5
4
"fmt"
6
5
"io/fs"
7
6
"log"
8
7
"os"
9
8
"path/filepath"
10
- "strconv "
9
+ "sort "
11
10
"strings"
12
11
13
12
"github.com/jhump/protoreflect/desc/protoparse"
14
13
"github.com/samber/lo"
15
14
"github.com/spf13/pflag"
16
15
"google.golang.org/protobuf/types/descriptorpb"
16
+
17
+ oneprotou_til "github.com/joesonw/oneproto/util"
17
18
)
18
19
19
20
var (
23
24
pPackage = pflag .StringP ("package" , "P" , "" , "package name" )
24
25
25
26
allMessageDescriptors = map [string ]* descriptorpb.DescriptorProto {}
27
+ parentResolvedMap = map [* descriptorpb.DescriptorProto ]bool {}
26
28
)
27
29
28
30
func main () {
@@ -51,15 +53,17 @@ func main() {
51
53
os .Exit (1 )
52
54
}
53
55
54
- parser := protoparse.Parser {}
56
+ parser := protoparse.Parser {
57
+ IncludeSourceCodeInfo : true ,
58
+ }
55
59
files , err := parser .ParseFilesButDoNotLink (lo .Map (entries , func (entry string , index int ) string {
56
60
return filepath .Join (* pInclude , entry )
57
61
})... )
58
62
if err != nil {
59
63
log .Fatalln (err )
60
64
}
61
65
62
- buf := & Buffer { buf : & bytes. Buffer {}}
66
+ buf := oneprotou_til . NewBuffer ()
63
67
buf .Printf (string (templateContent ))
64
68
65
69
// group files by package name
@@ -83,17 +87,21 @@ func main() {
83
87
84
88
for _ , file := range packageFiles {
85
89
for _ , enum := range file .EnumType {
86
- generateEnum (buf , indentLevel , enum )
90
+ oneprotou_til . GenerateEnum (buf , indentLevel , enum )
87
91
buf .Printf ("" )
88
92
}
89
93
90
94
for _ , service := range file .Service {
91
- generateService (buf , indentLevel , service )
95
+ oneprotou_til . GenerateService (buf , indentLevel , service )
92
96
buf .Printf ("" )
93
97
}
94
98
95
99
for _ , message := range file .GetMessageType () {
96
- generateMessage (buf , indentLevel , message )
100
+ message .Field = append (message .Field , resolveMessageExtends (buf , indentLevel , message )... )
101
+ sort .Slice (message .Field , func (i , j int ) bool {
102
+ return message .Field [i ].GetNumber () < message .Field [j ].GetNumber ()
103
+ })
104
+ oneprotou_til .GenerateMessage (buf , indentLevel , message )
97
105
buf .Printf ("" )
98
106
}
99
107
}
@@ -108,152 +116,29 @@ func main() {
108
116
}
109
117
}
110
118
111
- type Buffer struct {
112
- buf * bytes.Buffer
113
- }
114
-
115
- func (b * Buffer ) Printf (f string , i ... any ) {
116
- _ , _ = b .buf .WriteString (fmt .Sprintf (f + "\n " , i ... ))
117
- }
118
-
119
- func (b * Buffer ) String () string {
120
- return b .buf .String ()
121
- }
122
-
123
- func (b * Buffer ) Bytes () []byte {
124
- return b .buf .Bytes ()
125
- }
126
-
127
- func stringifyUninterpretedOption (opt * descriptorpb.UninterpretedOption ) string {
128
- var value string
129
- if v := opt .IdentifierValue ; v != nil {
130
- value = * v
131
- } else if v := opt .DoubleValue ; v != nil {
132
- value = strconv .FormatFloat (* v , 'f' , - 1 , 64 )
133
- } else if v := opt .AggregateValue ; v != nil {
134
- value = fmt .Sprintf ("{%s}" , * v )
135
- } else if v := opt .StringValue ; v != nil {
136
- value = fmt .Sprintf ("'%s'" , v )
137
- } else if v := opt .PositiveIntValue ; v != nil {
138
- value = strconv .Itoa (int (* v ))
139
- } else if v := opt .NegativeIntValue ; v != nil {
140
- value = strconv .Itoa (int (* v ))
141
- }
142
- return fmt .Sprintf ("(%s) = %s" , strings .Join (lo .Map (opt .GetName (), func (name * descriptorpb.UninterpretedOption_NamePart , index int ) string {
143
- return name .GetNamePart ()
144
- }), "," ), value )
145
- }
146
-
147
- func stringifyField (message * descriptorpb.DescriptorProto , field * descriptorpb.FieldDescriptorProto ) string {
148
- repeated := field .GetLabel () == descriptorpb .FieldDescriptorProto_LABEL_REPEATED
149
- if field .Type == nil {
150
- name := field .GetTypeName ()
151
- for _ , nested := range message .NestedType {
152
- if name == nested .GetName () && strings .HasSuffix (name , "Entry" ) { // map entry
153
- return fmt .Sprintf ("map<%s,%s>" , stringifyField (nested , nested .Field [0 ]), stringifyField (nested , nested .Field [1 ]))
154
- }
155
- }
156
- if repeated {
157
- return "repeated " + name
158
- }
159
- return name
160
- }
161
- name := strings .ToLower (field .GetType ().String ()[5 :])
162
- if repeated {
163
- name = "repeated " + name
164
- }
165
- return name
166
- }
167
-
168
- func generateService (buf * Buffer , indentLevel int , service * descriptorpb.ServiceDescriptorProto ) {
169
- indent := strings .Repeat (" " , indentLevel * 4 )
170
- buf .Printf ("%sservice %s {" , indent , service .GetName ())
171
- generateHeadOptions (buf , indent , service .GetOptions ().GetUninterpretedOption ())
172
- for _ , method := range service .Method {
173
- buf .Printf ("%s rpc %s(%s) returns (%s) {" , indent , method .GetName (), method .GetInputType (), method .GetOutputType ())
174
- for _ , opt := range method .GetOptions ().GetUninterpretedOption () {
175
- buf .Printf ("%s option %s;" , indent , stringifyUninterpretedOption (opt ))
176
- }
177
- buf .Printf ("%s }" , indent )
178
- buf .Printf ("" )
179
- }
180
- buf .Printf ("%s}" , indent )
181
- }
182
-
183
- func generateEnum (buf * Buffer , indentLevel int , enum * descriptorpb.EnumDescriptorProto ) {
184
- indent := strings .Repeat (" " , indentLevel * 4 )
185
- buf .Printf ("%senum %s {" , indent , enum .GetName ())
186
- generateHeadOptions (buf , indent , enum .GetOptions ().GetUninterpretedOption ())
187
-
188
- for _ , value := range enum .Value {
189
- buf .Printf ("%s %s = %d%s;" , indent , value .GetName (), value .GetNumber (), stringifyValueOptions (value .GetOptions ().GetUninterpretedOption ()))
190
- }
191
- buf .Printf ("%s}" , indent )
192
- }
193
-
194
- func generateMessage (buf * Buffer , indentLevel int , message * descriptorpb.DescriptorProto ) {
195
- indent := strings .Repeat (" " , indentLevel * 4 )
196
- buf .Printf ("%smessage %s {" , indent , message .GetName ())
197
- generateHeadOptions (buf , indent , message .GetOptions ().GetUninterpretedOption ())
198
- generateExtendedMessage (buf , indentLevel , message )
199
- for _ , field := range message .GetField () {
200
- buf .Printf ("%s %s %s = %d%s;" , indent , stringifyField (message , field ), field .GetName (), field .GetNumber (), stringifyValueOptions (field .GetOptions ().GetUninterpretedOption ()))
201
- }
202
-
203
- for _ , enum := range message .EnumType {
204
- buf .Printf ("" )
205
- generateEnum (buf , indentLevel + 1 , enum )
206
- }
207
-
208
- for _ , nested := range message .NestedType {
209
- if nested .GetOptions ().GetMapEntry () {
210
- continue
211
- }
212
- buf .Printf ("" )
213
- generateMessage (buf , indentLevel + 1 , nested )
214
- }
215
- buf .Printf ("%s}" , indent )
216
- }
217
-
218
- func generateExtendedMessage (buf * Buffer , indentLevel int , message * descriptorpb.DescriptorProto ) {
219
- indent := strings .Repeat (" " , indentLevel * 4 )
220
- for _ , opt := range message .GetOptions ().GetUninterpretedOption () {
221
- if isOptionOneProtoExtends (opt ) {
222
- name := trimPackageFromName (string (opt .GetStringValue ()))
223
- buf .Printf ("%s // ↓↓↓↓↓ extends %s" , indent , name )
224
- parent := allMessageDescriptors [name ]
225
- generateExtendedMessage (buf , indentLevel , parent )
226
- for _ , field := range parent .GetField () {
227
- buf .Printf ("%s %s %s = %d%s;" , indent , stringifyField (message , field ), field .GetName (), field .GetNumber (), stringifyValueOptions (field .GetOptions ().GetUninterpretedOption ()))
119
+ func resolveMessageExtends (buf * oneprotou_til.Buffer , indentLevel int , message * descriptorpb.DescriptorProto ) []* descriptorpb.FieldDescriptorProto {
120
+ if parentResolvedMap [message ] {
121
+ return nil
122
+ }
123
+ parentResolvedMap [message ] = true
124
+ var fields []* descriptorpb.FieldDescriptorProto
125
+ for i , option := range message .GetOptions ().GetUninterpretedOption () {
126
+ if isOptionOneProtoExtends (option ) {
127
+ message .Options .UninterpretedOption = append (message .Options .UninterpretedOption [:i ], message .Options .UninterpretedOption [i + 1 :]... )
128
+ buf .Printf ("%s// extends %s" , strings .Repeat (" " , 4 * indentLevel ), option .GetStringValue ())
129
+ parent := allMessageDescriptors [trimPackageFromName (string (option .GetStringValue ()))]
130
+ if parent == nil {
131
+ log .Fatalf ("unable to find message %s" , option .GetStringValue ())
228
132
}
229
- buf . Printf ( "%s // ↑↑↑↑↑ extends %s" , indent , name )
230
- buf . Printf ( "" )
133
+ fields = append ( fields , parent . Field ... )
134
+ fields = append ( fields , resolveMessageExtends ( buf , indentLevel , parent ) ... )
231
135
}
232
136
}
137
+ return fields
233
138
}
234
139
235
- func generateHeadOptions (buf * Buffer , indent string , options []* descriptorpb.UninterpretedOption ) {
236
- if len (options ) == 0 {
237
- return
238
- }
239
- for _ , opt := range options {
240
- if isOptionOneProtoExtends (opt ) {
241
- continue
242
- }
243
- buf .Printf ("%s option %s;" , indent , stringifyUninterpretedOption (opt ))
244
- }
245
- buf .Printf ("" )
246
- }
247
-
248
- func stringifyValueOptions (options []* descriptorpb.UninterpretedOption ) string {
249
- if len (options ) == 0 {
250
- return ""
251
- }
252
- var opts []string
253
- for _ , opt := range options {
254
- opts = append (opts , stringifyUninterpretedOption (opt ))
255
- }
256
- return fmt .Sprintf (" [%s]" , strings .Join (opts , ", " ))
140
+ func trimPackageFromName (name string ) string {
141
+ return strings .TrimPrefix (name , * pPackage + "." )
257
142
}
258
143
259
144
func isOptionOneProtoExtends (option * descriptorpb.UninterpretedOption ) bool {
@@ -262,7 +147,3 @@ func isOptionOneProtoExtends(option *descriptorpb.UninterpretedOption) bool {
262
147
}
263
148
return false
264
149
}
265
-
266
- func trimPackageFromName (name string ) string {
267
- return strings .TrimPrefix (name , * pPackage + "." )
268
- }
0 commit comments