Skip to content

Commit e37444d

Browse files
lvan100lianghuan
authored andcommitted
111
1 parent 805e9e7 commit e37444d

File tree

1 file changed

+57
-47
lines changed

1 file changed

+57
-47
lines changed

gen/generator/golang/type.go

Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,6 @@ type Type struct {
323323
Comment string
324324
}
325325

326-
// Binding represents a field binding from headers, path, or query
327-
type Binding struct {
328-
From string // Source: header/path/query
329-
Name string // Field name in the source
330-
}
331-
332326
// TypeField represents a field in a Go struct
333327
type TypeField struct {
334328
Type string
@@ -340,6 +334,12 @@ type TypeField struct {
340334
Comment string
341335
}
342336

337+
// Binding represents a field binding from headers, path, or query
338+
type Binding struct {
339+
From string // Source: header/path/query
340+
Name string // Field name in the source
341+
}
342+
343343
// BindingCount returns the number of fields in the struct that have binding info
344344
func (t *Type) BindingCount() int {
345345
var count int
@@ -363,7 +363,7 @@ func (t *Type) ValidateCount() int {
363363
}
364364

365365
// convertTypes converts IDL struct types to Go struct types
366-
func convertTypes(ctx Context, doc tidl.Document) (_ []Type, err error) {
366+
func convertTypes(ctx Context, doc tidl.Document) ([]Type, error) {
367367
var ret []Type
368368

369369
// Handle type keyword defined structs
@@ -372,16 +372,19 @@ func convertTypes(ctx Context, doc tidl.Document) (_ []Type, err error) {
372372
if t.GenericName != nil {
373373
continue
374374
}
375-
var r Type
375+
var (
376+
typ Type
377+
err error
378+
)
376379
if t.Redefined != nil {
377-
r, err = convertRedefinedType(ctx, t)
380+
typ, err = convertRedefinedType(ctx, t)
378381
} else {
379-
r, err = convertType(ctx, t)
382+
typ, err = convertType(ctx, t)
380383
}
381384
if err != nil {
382385
return nil, err
383386
}
384-
ret = append(ret, r)
387+
ret = append(ret, typ)
385388
}
386389

387390
return ret, nil
@@ -396,7 +399,7 @@ func convertRedefinedType(ctx Context, r tidl.Type) (Type, error) {
396399

397400
var fields []tidl.TypeField
398401
for _, f := range t.Fields {
399-
f.FieldType = resolveGenericType(f.FieldType, *t.GenericName, r.Redefined)
402+
f.FieldType = replaceGenericType(f.FieldType, *t.GenericName, r.Redefined.GenericType)
400403
fields = append(fields, f)
401404
}
402405

@@ -408,19 +411,19 @@ func convertRedefinedType(ctx Context, r tidl.Type) (Type, error) {
408411
})
409412
}
410413

411-
// resolveGenericType replaces a generic type in a field with a concrete type
412-
func resolveGenericType(t tidl.TypeDefinition, genericName string, r *tidl.RedefinedType) tidl.TypeDefinition {
414+
// replaceGenericType replaces a generic type in a field with a concrete type
415+
func replaceGenericType(t tidl.TypeDefinition, genericName string, genericType tidl.TypeDefinition) tidl.TypeDefinition {
413416
switch u := t.(type) {
414417
case tidl.UserType:
415418
if u.Name == genericName {
416-
return r.GenericType
419+
return genericType
417420
}
418421
return u
419422
case tidl.ListType:
420-
u.Item = resolveGenericType(u.Item, genericName, r)
423+
u.Item = replaceGenericType(u.Item, genericName, genericType)
421424
return u
422425
case tidl.MapType:
423-
u.Value = resolveGenericType(u.Value, genericName, r)
426+
u.Value = replaceGenericType(u.Value, genericName, genericType)
424427
return u
425428
default:
426429
return t
@@ -433,6 +436,7 @@ func convertType(ctx Context, t tidl.Type) (Type, error) {
433436
Name: t.Name,
434437
}
435438

439+
// Handle oneof
436440
if t.OneOf {
437441
r.Fields = append(r.Fields, TypeField{
438442
Type: r.Name + "TypeAsString",
@@ -442,25 +446,27 @@ func convertType(ctx Context, t tidl.Type) (Type, error) {
442446
})
443447
}
444448

449+
// Handle fields
445450
for _, f := range t.Fields {
446451

447452
// Handle embedded types (flatten their fields into the struct)
448-
if ft, ok := f.FieldType.(tidl.EmbedType); ok {
449-
et, ok := tidl.GetType(ctx.files, ft.Name)
453+
if embedType, ok := f.FieldType.(tidl.EmbedType); ok {
454+
srcType, ok := tidl.GetType(ctx.files, embedType.Name)
450455
if !ok {
451-
return Type{}, fmt.Errorf("embedded type %s not found for field in struct %s", ft.Name, r.Name)
456+
return Type{}, fmt.Errorf("embedded type %s not found for field in struct %s", embedType.Name, r.Name)
452457
}
453-
rt, err := convertType(ctx, et)
458+
retType, err := convertType(ctx, srcType)
454459
if err != nil {
455-
return Type{}, fmt.Errorf("failed to convert embedded type %s in struct %s: %w", ft.Name, r.Name, err)
460+
return Type{}, fmt.Errorf("failed to convert embedded type %s in struct %s: %w", embedType.Name, r.Name, err)
456461
}
457462
// Append embedded type's fields
458-
r.Fields = append(r.Fields, rt.Fields...)
463+
r.Fields = append(r.Fields, retType.Fields...)
459464
continue
460465
}
461466

462-
// Get field name and Go type
463467
fieldName := tidl.ToPascal(f.Name)
468+
469+
// Get field name and Go type
464470
typeName, err := getTypeName(ctx, f.FieldType, f.Annotations)
465471
if err != nil {
466472
return Type{}, err
@@ -509,17 +515,23 @@ func convertType(ctx Context, t tidl.Type) (Type, error) {
509515
func getTypeName(ctx Context, t tidl.TypeDefinition, arr []tidl.Annotation) (string, error) {
510516

511517
// Handle go.type annotation
512-
if a, ok := tidl.GetAnnotation(arr, "go.type"); ok && a.Value != nil {
518+
if a, ok := tidl.GetAnnotation(arr, "go.type"); ok {
519+
if a.Value == nil {
520+
return "", fmt.Errorf("go.type annotation must have a value")
521+
}
513522
s := strings.Trim(strings.TrimSpace(*a.Value), "\"")
523+
if s == "" {
524+
return "", fmt.Errorf("go.type annotation must not empty")
525+
}
514526
return s, nil
515527
}
516528

517-
switch ft := t.(type) {
529+
switch typ := t.(type) {
518530
case tidl.AnyType:
519531
return "", fmt.Errorf("any type must have go.type annotation")
520532
case tidl.BaseType:
521533
var typeName string
522-
switch ft.Name {
534+
switch typ.Name {
523535
case "string":
524536
typeName = "string"
525537
case "int":
@@ -529,56 +541,51 @@ func getTypeName(ctx Context, t tidl.TypeDefinition, arr []tidl.Annotation) (str
529541
case "bool":
530542
typeName = "bool"
531543
default:
532-
return "", fmt.Errorf("unknown base type: %s", ft.Name)
544+
return "", fmt.Errorf("unknown base type: %s", typ.Name)
533545
}
534-
if ft.Optional {
546+
if typ.Optional {
535547
typeName = "*" + typeName
536548
}
537549
return typeName, nil
538550
case tidl.UserType:
539-
typeName := ft.Name
540-
if ft.Optional {
541-
typeName = "*" + typeName
542-
}
543-
551+
typeName := typ.Name
544552
// Handle enum_as_string annotation
545553
if _, ok := tidl.GetAnnotation(arr, "enum_as_string"); ok {
546-
if _, ok := tidl.GetEnum(ctx.files, ft.Name); !ok {
547-
return "", fmt.Errorf("enum %s not found", ft.Name)
554+
if _, ok := tidl.GetEnum(ctx.files, typ.Name); !ok {
555+
return "", fmt.Errorf("enum %s not found", typ.Name)
548556
}
549557
typeName += "AsString"
550558
}
559+
if typ.Optional {
560+
typeName = "*" + typeName
561+
}
551562
return typeName, nil
552563
case tidl.ListType:
553-
itemType, err := getTypeName(ctx, ft.Item, nil)
564+
itemType, err := getTypeName(ctx, typ.Item, nil)
554565
if err != nil {
555566
return "", err
556567
}
557568
return "[]" + itemType, nil
558569
case tidl.MapType:
559570
keyType := "string"
560-
if ft.Key == "int" {
571+
if typ.Key == "int" {
561572
keyType = "int64"
562573
}
563-
valueType, err := getTypeName(ctx, ft.Value, nil)
574+
valueType, err := getTypeName(ctx, typ.Value, nil)
564575
if err != nil {
565576
return "", err
566577
}
567578
return fmt.Sprintf("map[%s]%s", keyType, valueType), nil
568579
case tidl.BinaryType:
569-
// todo (lvan100) handle file
570-
return "[]byte", nil
580+
return "[]byte", nil // todo (lvan100) handle file
571581
default:
572582
return "", fmt.Errorf("unknown type: %s", t.Text())
573583
}
574584
}
575585

576586
// getTypeKind returns the category of a Go type (base, optional base, enum, struct, etc.)
577587
func getTypeKind(ctx Context, typeName string) (TypeKind, error) {
578-
optional := strings.HasPrefix(typeName, "*")
579-
if optional {
580-
typeName = strings.TrimPrefix(typeName, "*")
581-
}
588+
typeName, optional := strings.CutPrefix(typeName, "*")
582589

583590
switch typeName {
584591
case "int", "int8", "int16", "int32", "int64",
@@ -630,7 +637,10 @@ func parseBinding(arr []tidl.Annotation) (*Binding, error) {
630637
return nil, fmt.Errorf("annotation %s value is nil", a.Key)
631638
}
632639
val := strings.Trim(*a.Value, "\"")
633-
return &Binding{From: a.Key, Name: val}, nil
640+
return &Binding{
641+
From: a.Key,
642+
Name: val,
643+
}, nil
634644
}
635645

636646
// genFieldTag generates the struct tag for a field.
@@ -705,7 +715,6 @@ var builtinFuncs = map[string]struct{}{
705715
// genValidate generates validation code for a field based on annotations.
706716
// It returns a Go code snippet for validating the field.
707717
func genValidate(receiverType, fieldName, fieldType string, arr []tidl.Annotation, funcs map[string]ValidateFunc) (*string, error) {
708-
optional := strings.HasPrefix(fieldType, "*")
709718
a, ok := tidl.GetAnnotation(arr, "validate")
710719
if !ok {
711720
return nil, nil
@@ -729,6 +738,7 @@ func genValidate(receiverType, fieldName, fieldType string, arr []tidl.Annotatio
729738
return nil, err
730739
}
731740

741+
optional := strings.HasPrefix(fieldType, "*")
732742
dollar := "x." + fieldName
733743
if optional {
734744
dollar = "*" + dollar

0 commit comments

Comments
 (0)