1 package main
2
3 import (
4 "bytes"
5 "fmt"
6 "io/ioutil"
7 "os"
8 "path/filepath"
9 "sort"
10 "strconv"
11 "strings"
12 )
13
14 var maxKey int
15
16 func die(why string, args ...any) {
17 fmt.Fprintf(os.Stderr, why+"\n", args...)
18 os.Exit(1)
19 }
20
21 type (
22
23 LineWriter struct {
24 buf *bytes.Buffer
25 line int
26 }
27
28 Type interface {
29 WriteAppend(*LineWriter)
30 WriteDecode(*LineWriter)
31 TypeName() string
32 }
33
34 Bool struct {
35 HasDefault bool
36 Default bool
37 }
38 Int8 struct {
39 HasDefault bool
40 Default int8
41 }
42 Int16 struct {
43 HasDefault bool
44 Default int16
45 }
46 Uint16 struct {
47 HasDefault bool
48 Default uint16
49 }
50 Int32 struct {
51 HasDefault bool
52 Default int32
53 }
54 Int64 struct {
55 HasDefault bool
56 Default int64
57 }
58 Float64 struct {
59 HasDefault bool
60 Default float64
61 }
62 Uint32 struct {
63 HasDefault bool
64 Default uint32
65 }
66 Varint struct {
67 HasDefault bool
68 Default int32
69 }
70 Varlong struct {
71 HasDefault bool
72 Default int64
73 }
74 Uuid struct{}
75 VarintString struct{}
76 VarintBytes struct{}
77
78 FieldLengthMinusBytes struct {
79 Field string
80 LengthMinus int
81 }
82
83
84
85
86
87 String struct {
88 FromFlexible bool
89 }
90 NullableString struct {
91 HasDefault bool
92 FromFlexible bool
93 NullableVersion int
94 }
95 Bytes struct {
96 FromFlexible bool
97 }
98 NullableBytes struct {
99 HasDefault bool
100 FromFlexible bool
101 }
102
103 Array struct {
104 Inner Type
105 IsVarintArray bool
106 IsNullableArray bool
107 NullableVersion int
108
109 HasDefault bool
110
111
112
113 FromFlexible bool
114 }
115
116 StructField struct {
117 Comment string
118 MinVersion int
119 MaxVersion int
120 Tag int
121 FieldName string
122 Type Type
123 }
124
125 Throttle struct {
126 Switchup int
127 }
128 Timeout struct {
129 Int32
130 }
131
132 Struct struct {
133 TopLevel bool
134 WithVersionField bool
135 WithNoEncoding bool
136 Anonymous bool
137 Comment string
138 Name string
139
140 HasDefault bool
141
142
143
144
145 FromFlexible bool
146 Nullable bool
147
148 Fields []StructField
149
150 Key int
151
152
153 Admin bool
154 GroupCoordinator bool
155 TxnCoordinator bool
156 MaxVersion int
157 FlexibleAt int
158 ResponseKind string
159 RequestKind string
160 }
161
162 EnumValue struct {
163 Comment string
164 Value int
165 Word string
166 }
167
168 Enum struct {
169 Comment string
170 Name string
171 Type
172
173 HasZero bool
174 CamelCase bool
175
176 Values []EnumValue
177 }
178 )
179
180
181
182
183
184 type Defaulter interface {
185 SetDefault(string) Type
186 GetDefault() (any, bool)
187 GetTypeDefault() any
188 }
189
190 func (e Enum) SetDefault(s string) Type {
191 e.Type = e.Type.(Defaulter).SetDefault(s)
192 return e
193 }
194 func (e Enum) GetDefault() (any, bool) { return e.Type.(Defaulter).GetDefault() }
195 func (e Enum) GetTypeDefault() any { return e.Type.(Defaulter).GetTypeDefault() }
196
197 func (b Bool) SetDefault(s string) Type {
198 v, err := strconv.ParseBool(s)
199 if err != nil {
200 die("invalid bool default: %v", err)
201 }
202 b.Default = v
203 b.HasDefault = true
204 return b
205 }
206 func (b Bool) GetDefault() (any, bool) { return b.Default, b.HasDefault }
207 func (Bool) GetTypeDefault() any { return false }
208
209 func (i Int8) SetDefault(s string) Type {
210 v, err := strconv.ParseInt(s, 0, 8)
211 if err != nil {
212 die("invalid int8 default: %v", err)
213 }
214 i.Default = int8(v)
215 i.HasDefault = true
216 return i
217 }
218 func (i Int8) GetDefault() (any, bool) { return i.Default, i.HasDefault }
219 func (Int8) GetTypeDefault() any { return 0 }
220
221 func (i Int16) SetDefault(s string) Type {
222 v, err := strconv.ParseInt(s, 0, 16)
223 if err != nil {
224 die("invalid int16 default: %v", err)
225 }
226 i.Default = int16(v)
227 i.HasDefault = true
228 return i
229 }
230 func (i Int16) GetDefault() (any, bool) { return i.Default, i.HasDefault }
231 func (Int16) GetTypeDefault() any { return 0 }
232
233 func (u Uint16) SetDefault(s string) Type {
234 v, err := strconv.ParseUint(s, 0, 16)
235 if err != nil {
236 die("invalid uint16 default: %v", err)
237 }
238 u.Default = uint16(v)
239 u.HasDefault = true
240 return u
241 }
242 func (u Uint16) GetDefault() (any, bool) { return u.Default, u.HasDefault }
243 func (Uint16) GetTypeDefault() any { return 0 }
244
245 func (i Int32) SetDefault(s string) Type {
246 v, err := strconv.ParseInt(s, 0, 32)
247 if err != nil {
248 die("invalid int32 default: %v", err)
249 }
250 i.Default = int32(v)
251 i.HasDefault = true
252 return i
253 }
254 func (i Int32) GetDefault() (any, bool) { return i.Default, i.HasDefault }
255 func (Int32) GetTypeDefault() any { return 0 }
256
257 func (t Timeout) SetDefault(s string) Type {
258 t.Int32 = t.Int32.SetDefault(s).(Int32)
259 return t
260 }
261
262 func (i Int64) SetDefault(s string) Type {
263 v, err := strconv.ParseInt(s, 0, 64)
264 if err != nil {
265 die("invalid int64 default: %v", err)
266 }
267 i.Default = v
268 i.HasDefault = true
269 return i
270 }
271 func (i Int64) GetDefault() (any, bool) { return i.Default, i.HasDefault }
272 func (Int64) GetTypeDefault() any { return 0 }
273
274 func (f Float64) SetDefault(s string) Type {
275 v, err := strconv.ParseFloat(s, 64)
276 if err != nil {
277 die("invalid float64 default: %v", err)
278 }
279 f.Default = v
280 f.HasDefault = true
281 return f
282 }
283 func (f Float64) GetDefault() (any, bool) { return f.Default, f.HasDefault }
284 func (Float64) GetTypeDefault() any { return 0 }
285
286 func (u Uint32) SetDefault(s string) Type {
287 v, err := strconv.ParseUint(s, 10, 32)
288 if err != nil {
289 die("invalid uint32 default: %v", err)
290 }
291 u.Default = uint32(v)
292 u.HasDefault = true
293 return u
294 }
295 func (u Uint32) GetDefault() (any, bool) { return u.Default, u.HasDefault }
296 func (Uint32) GetTypeDefault() any { return 0 }
297
298 func (i Varint) SetDefault(s string) Type {
299 v, err := strconv.ParseInt(s, 0, 32)
300 if err != nil {
301 die("invalid varint default: %v", err)
302 }
303 i.Default = int32(v)
304 i.HasDefault = true
305 return i
306 }
307 func (i Varint) GetDefault() (any, bool) { return i.Default, i.HasDefault }
308 func (Varint) GetTypeDefault() any { return 0 }
309
310 func (i Varlong) SetDefault(s string) Type {
311 v, err := strconv.ParseInt(s, 0, 64)
312 if err != nil {
313 die("invalid varlong default: %v", err)
314 }
315 i.Default = v
316 i.HasDefault = true
317 return i
318 }
319 func (i Varlong) GetDefault() (any, bool) { return i.Default, i.HasDefault }
320 func (Varlong) GetTypeDefault() any { return 0 }
321
322 func (s NullableString) SetDefault(v string) Type {
323 if v != "null" {
324 die("unknown non-null default for nullable string")
325 }
326 s.HasDefault = true
327 return s
328 }
329
330 func (s NullableString) GetDefault() (any, bool) {
331 return "nil", s.HasDefault
332 }
333 func (NullableString) GetTypeDefault() any { return "nil" }
334
335 func (b NullableBytes) SetDefault(v string) Type {
336 if v != "null" {
337 die("unknown non-null default for nullable string")
338 }
339 b.HasDefault = true
340 return b
341 }
342
343 func (b NullableBytes) GetDefault() (any, bool) {
344 return "nil", b.HasDefault
345 }
346 func (NullableBytes) GetTypeDefault() any { return "nil" }
347
348 func (a Array) SetDefault(v string) Type {
349 if v != "null" {
350 die("unknown non-null default for array")
351 }
352 a.HasDefault = true
353 return a
354 }
355
356 func (a Array) GetDefault() (any, bool) {
357 return "nil", a.HasDefault
358 }
359 func (Array) GetTypeDefault() any { return "nil" }
360
361 func (s Struct) SetDefault(string) Type {
362 die("cannot set default on a struct; we already have a default")
363 return s
364 }
365
366 func (Struct) GetDefault() (any, bool) {
367 return "", false
368 }
369
370 func (s Struct) GetTypeDefault() any {
371 if s.Nullable {
372 return "nil"
373 }
374
375
376 return fmt.Sprintf("(func() %[1]s { var v %[1]s; v.Default(); return v })() ", s.Name)
377 }
378
379 type FlexibleSetter interface {
380 AsFromFlexible() Type
381 }
382
383 func (s String) AsFromFlexible() Type { dup := s; dup.FromFlexible = true; return dup }
384 func (s NullableString) AsFromFlexible() Type { dup := s; dup.FromFlexible = true; return dup }
385 func (b Bytes) AsFromFlexible() Type { dup := b; dup.FromFlexible = true; return dup }
386 func (b NullableBytes) AsFromFlexible() Type { dup := b; dup.FromFlexible = true; return dup }
387 func (a Array) AsFromFlexible() Type { dup := a; dup.FromFlexible = true; return dup }
388 func (s Struct) AsFromFlexible() Type { dup := s; dup.FromFlexible = true; return dup }
389
390 func (l *LineWriter) Write(line string, args ...any) {
391 fmt.Fprintf(l.buf, line, args...)
392 l.buf.WriteByte('\n')
393 l.line++
394 }
395
396
397 func main() {
398 const dir = "definitions"
399 const enums = "enums"
400 dirents, err := ioutil.ReadDir(dir)
401 if err != nil {
402 die("unable to read definitions dir %s: %v", dir, err)
403 }
404
405 {
406 f, err := ioutil.ReadFile(filepath.Join(dir, enums))
407 if err != nil {
408 die("unable to read %s/%s: %v", dir, enums, err)
409 }
410 ParseEnums(f)
411 }
412
413 for _, ent := range dirents {
414 if ent.Name() == enums || strings.HasPrefix(ent.Name(), ".") {
415 continue
416 }
417 f, err := ioutil.ReadFile(filepath.Join(dir, ent.Name()))
418 if err != nil {
419 die("unable to read %s/%s: %v", dir, ent.Name(), err)
420 }
421 Parse(f)
422 }
423
424 l := &LineWriter{buf: bytes.NewBuffer(make([]byte, 0, 300<<10))}
425 l.Write("package kmsg")
426 l.Write("import (")
427 l.Write(`"context"`)
428 l.Write(`"fmt"`)
429 l.Write(`"strings"`)
430 l.Write(`"reflect"`)
431 l.Write("")
432 l.Write(`"github.com/twmb/franz-go/pkg/kmsg/internal/kbin"`)
433 l.Write(")")
434 l.Write("// Code generated by franz-go/generate. DO NOT EDIT.\n")
435
436 l.Write("// MaxKey is the maximum key used for any messages in this package.")
437 l.Write("// Note that this value will change as Kafka adds more messages.")
438 l.Write("const MaxKey = %d\n", maxKey)
439
440 var name2structs []Struct
441
442 sort.SliceStable(newStructs, func(i, j int) bool { return newStructs[i].Key < newStructs[j].Key })
443 for _, s := range newStructs {
444 s.WriteDefn(l)
445 if s.TopLevel {
446 if s.ResponseKind != "" {
447 name2structs = append(name2structs, s)
448 }
449
450 s.WriteKeyFunc(l)
451 s.WriteMaxVersionFunc(l)
452 s.WriteSetVersionFunc(l)
453 s.WriteGetVersionFunc(l)
454 s.WriteIsFlexibleFunc(l)
455
456 for _, f := range s.Fields {
457 switch f.Type.(type) {
458 case Throttle:
459 s.WriteThrottleMillisFunc(f, l)
460 s.WriteSetThrottleMillisFunc(l)
461 case Timeout:
462 s.WriteTimeoutMillisFunc(l)
463 s.WriteSetTimeoutMillisFunc(l)
464 }
465 }
466
467 if s.ResponseKind != "" {
468 switch {
469 case s.Admin:
470 s.WriteAdminFunc(l)
471 case s.GroupCoordinator:
472 s.WriteGroupCoordinatorFunc(l)
473 case s.TxnCoordinator:
474 s.WriteTxnCoordinatorFunc(l)
475 }
476 s.WriteResponseKindFunc(l)
477 s.WriteRequestWithFunc(l)
478 }
479 if s.RequestKind != "" {
480 s.WriteRequestKindFunc(l)
481 }
482
483 l.Write("")
484 s.WriteAppendFunc(l)
485 s.WriteDecodeFunc(l)
486 s.WriteNewPtrFunc(l)
487 } else if !s.Anonymous && !s.WithNoEncoding {
488 s.WriteAppendFunc(l)
489 s.WriteDecodeFunc(l)
490 if s.FromFlexible {
491 s.WriteIsFlexibleFunc(l)
492 }
493 }
494
495
496 s.WriteDefaultFunc(l)
497 s.WriteNewFunc(l)
498 }
499
500 l.Write("// RequestForKey returns the request corresponding to the given request key")
501 l.Write("// or nil if the key is unknown.")
502 l.Write("func RequestForKey(key int16) Request {")
503 l.Write("switch key {")
504 l.Write("default: return nil")
505 for _, key2struct := range name2structs {
506 l.Write("case %d: return NewPtr%s()", key2struct.Key, key2struct.Name)
507 }
508 l.Write("}")
509 l.Write("}")
510
511 l.Write("// ResponseForKey returns the response corresponding to the given request key")
512 l.Write("// or nil if the key is unknown.")
513 l.Write("func ResponseForKey(key int16) Response {")
514 l.Write("switch key {")
515 l.Write("default: return nil")
516 for _, key2struct := range name2structs {
517 l.Write("case %d: return NewPtr%s()", key2struct.Key, strings.TrimSuffix(key2struct.Name, "Request")+"Response")
518 }
519 l.Write("}")
520 l.Write("}")
521
522 l.Write("// NameForKey returns the name (e.g., \"Fetch\") corresponding to a given request key")
523 l.Write("// or \"\" if the key is unknown.")
524 l.Write("func NameForKey(key int16) string {")
525 l.Write("switch key {")
526 l.Write("default: return \"Unknown\"")
527 for _, key2struct := range name2structs {
528 l.Write("case %d: return \"%s\"", key2struct.Key, strings.TrimSuffix(key2struct.Name, "Request"))
529 }
530 l.Write("}")
531 l.Write("}")
532
533 l.Write("// Key is a typed representation of a request key, with helper functions.")
534 l.Write("type Key int16")
535 l.Write("const (")
536 for _, key2struct := range name2structs {
537 l.Write("%s Key = %d", strings.TrimSuffix(key2struct.Name, "Request"), key2struct.Key)
538 }
539 l.Write(")")
540 l.Write("// Name returns the name for this key.")
541 l.Write("func (k Key) Name() string { return NameForKey(int16(k)) }")
542 l.Write("// Request returns a new request for this key if the key is known.")
543 l.Write("func (k Key) Request() Request { return RequestForKey(int16(k)) }")
544 l.Write("// Response returns a new response for this key if the key is known.")
545 l.Write("func (k Key) Response() Response { return ResponseForKey(int16(k)) }")
546 l.Write("// Int16 is an alias for int16(k).")
547 l.Write("func (k Key) Int16() int16 { return int16(k) }")
548
549 for _, e := range newEnums {
550 e.WriteDefn(l)
551 e.WriteStringFunc(l)
552 e.WriteStringsFunc(l)
553 e.WriteParseFunc(l)
554 e.WriteConsts(l)
555 e.WriteMarshalTextFunc(l)
556 e.WriteUnmarshalTextFunc(l)
557 }
558
559 writeStrnorm(l)
560
561 fmt.Println(l.buf.String())
562 }
563
View as plain text