Skip to content

Commit b53daba

Browse files
lvan100lianghuan
authored andcommitted
feat(golang): support oneof type
1 parent cb7fe41 commit b53daba

File tree

12 files changed

+393
-223
lines changed

12 files changed

+393
-223
lines changed

gen/generator/generator.go

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -56,41 +56,6 @@ func RegisterGenerator(language string, g Generator) {
5656
generators[language] = g
5757
}
5858

59-
// GetEnum searches all documents for an enum type with the given name.
60-
func GetEnum(files map[string]tidl.Document, name string) (tidl.Enum, bool) {
61-
for _, doc := range files {
62-
for _, e := range doc.Enums {
63-
if CapitalizeASCII(e.Name) == name {
64-
return e, true
65-
}
66-
}
67-
}
68-
return tidl.Enum{}, false
69-
}
70-
71-
// GetType searches all documents for a type with the given name.
72-
func GetType(files map[string]tidl.Document, name string) (tidl.Type, bool) {
73-
for _, doc := range files {
74-
for _, t := range doc.Types {
75-
if CapitalizeASCII(t.Name) == name {
76-
return t, true
77-
}
78-
}
79-
}
80-
return tidl.Type{}, false
81-
}
82-
83-
// CapitalizeASCII capitalizes the first ASCII letter of a string.
84-
func CapitalizeASCII(s string) string {
85-
if len(s) == 0 {
86-
return s
87-
}
88-
if s[0] >= 'a' && s[0] <= 'z' {
89-
return string(s[0]-'a'+'A') + s[1:]
90-
}
91-
return s
92-
}
93-
9459
// ToPascal converts a snake_case string to PascalCase.
9560
// For example: "hello_world" becomes "HelloWorld".
9661
func ToPascal(s string) string {

gen/generator/golang/server.go

Lines changed: 4 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gen/generator/golang/type.go

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,11 @@ const {{$c.Name}} {{$c.Type}} = {{$c.Value}}
208208
// genType generates a Go type file corresponding to the IDL file.
209209
// It includes constants, enums, and struct types.
210210
func (g *Generator) genType(ctx Context, fileName string, doc tidl.Document) error {
211-
consts, err := convertConsts(ctx, doc.Consts)
211+
consts, err := convertConsts(ctx, doc)
212212
if err != nil {
213213
return err
214214
}
215-
enums, err := convertEnums(doc.Enums)
215+
enums, err := convertEnums(ctx, doc)
216216
if err != nil {
217217
return err
218218
}
@@ -258,9 +258,9 @@ type Const struct {
258258
}
259259

260260
// convertConsts converts IDL constants to Go constants
261-
func convertConsts(ctx Context, consts []tidl.Const) ([]Const, error) {
261+
func convertConsts(ctx Context, doc tidl.Document) ([]Const, error) {
262262
var ret []Const
263-
for _, c := range consts {
263+
for _, c := range doc.Consts {
264264
typeName, err := getTypeName(ctx, tidl.BaseType{
265265
Name: c.Type,
266266
}, nil)
@@ -292,9 +292,9 @@ type EnumField struct {
292292
}
293293

294294
// convertEnums converts IDL enums to Go enums
295-
func convertEnums(enums []tidl.Enum) ([]Enum, error) {
295+
func convertEnums(ctx Context, doc tidl.Document) ([]Enum, error) {
296296
var ret []Enum
297-
for _, e := range enums {
297+
for _, e := range doc.Enums {
298298
var fields []EnumField
299299
for _, f := range e.Fields {
300300
fields = append(fields, EnumField{
@@ -304,11 +304,28 @@ func convertEnums(enums []tidl.Enum) ([]Enum, error) {
304304
})
305305
}
306306
ret = append(ret, Enum{
307-
Name: generator.CapitalizeASCII(e.Name),
307+
Name: tidl.CapitalizeASCII(e.Name),
308308
Fields: fields,
309309
Comment: genComment(e.Comments),
310310
})
311311
}
312+
for _, t := range doc.Types {
313+
if !t.OneOf {
314+
continue
315+
}
316+
name := tidl.CapitalizeASCII(t.Name) + "Type"
317+
var fields []EnumField
318+
for i, f := range t.Fields {
319+
fields = append(fields, EnumField{
320+
Name: generator.ToPascal(f.Name),
321+
Value: int64(i),
322+
})
323+
}
324+
ret = append(ret, Enum{
325+
Name: name,
326+
Fields: fields,
327+
})
328+
}
312329
return ret, nil
313330
}
314331

@@ -401,14 +418,14 @@ func convertTypes(ctx Context, doc tidl.Document) (_ []Type, err error) {
401418

402419
// convertResponseType instantiates a generic response type for RPC
403420
func convertResponseType(ctx Context, rpcName string, respType tidl.RespType) (Type, error) {
404-
t, ok := generator.GetType(ctx.files, respType.TypeName)
421+
t, ok := tidl.GetType(ctx.files, respType.TypeName)
405422
if !ok {
406423
return Type{}, fmt.Errorf("type %s not found", respType.TypeName)
407424
}
408425

409-
typeName := generator.CapitalizeASCII(rpcName)
410-
typeName += generator.CapitalizeASCII(t.Name)
411-
typeName += generator.CapitalizeASCII(respType.UserType.Name)
426+
typeName := tidl.CapitalizeASCII(rpcName)
427+
typeName += tidl.CapitalizeASCII(t.Name)
428+
typeName += tidl.CapitalizeASCII(respType.UserType.Name)
412429

413430
r := tidl.Type{
414431
Name: typeName,
@@ -430,7 +447,7 @@ func convertResponseType(ctx Context, rpcName string, respType tidl.RespType) (T
430447

431448
// convertRedefinedType instantiates a redefined generic struct type
432449
func convertRedefinedType(ctx Context, r tidl.Type) (Type, error) {
433-
t, ok := generator.GetType(ctx.files, r.Redefined.Name)
450+
t, ok := tidl.GetType(ctx.files, r.Redefined.Name)
434451
if !ok {
435452
return Type{}, fmt.Errorf("type %s not found", r.Redefined.Name)
436453
}
@@ -471,13 +488,23 @@ func resolveGenericType(t tidl.TypeDefinition, genericName string, r *tidl.Redef
471488
// convertType converts an IDL struct type to a Go struct type
472489
func convertType(ctx Context, t tidl.Type) (Type, error) {
473490
r := Type{
474-
Name: generator.CapitalizeASCII(t.Name),
491+
Name: tidl.CapitalizeASCII(t.Name),
475492
}
493+
494+
if t.OneOf {
495+
r.Fields = append(r.Fields, TypeField{
496+
Type: r.Name + "Type",
497+
TypeKind: TypeKindEnumType,
498+
Name: "FieldType",
499+
Tag: "`json:\"field_type\"`",
500+
})
501+
}
502+
476503
for _, f := range t.Fields {
477504

478505
// Handle embedded types (flatten their fields into the struct)
479506
if ft, ok := f.FieldType.(tidl.EmbedType); ok {
480-
et, ok := generator.GetType(ctx.files, ft.Name)
507+
et, ok := tidl.GetType(ctx.files, ft.Name)
481508
if !ok {
482509
return Type{}, fmt.Errorf("embedded type %s not found for field in struct %s", ft.Name, r.Name)
483510
}
@@ -516,7 +543,7 @@ func convertType(ctx Context, t tidl.Type) (Type, error) {
516543
}
517544

518545
// Generate struct tag for the field
519-
fieldTag, err := genFieldTag(fieldName, typeName, f.Annotations, binding)
546+
fieldTag, err := genFieldTag(f.Name, typeName, f.Annotations, binding)
520547
if err != nil {
521548
return Type{}, err
522549
}
@@ -574,14 +601,14 @@ func getTypeName(ctx Context, t tidl.TypeDefinition, arr []tidl.Annotation) (str
574601
}
575602
return typeName, nil
576603
case tidl.UserType:
577-
typeName := generator.CapitalizeASCII(ft.Name)
604+
typeName := tidl.CapitalizeASCII(ft.Name)
578605
if ft.Optional {
579606
typeName = "*" + typeName
580607
}
581608

582609
// Handle enum_as_string annotation
583610
if _, ok := tidl.GetOneOfAnnotation(arr, "enum_as_string"); ok {
584-
if _, ok := generator.GetEnum(ctx.files, ft.Name); !ok {
611+
if _, ok := tidl.GetEnum(ctx.files, ft.Name); !ok {
585612
return "", fmt.Errorf("enum %s not found", ft.Name)
586613
}
587614
typeName += "AsString"
@@ -641,13 +668,13 @@ func getTypeKind(ctx Context, typeName string) (TypeKind, error) {
641668
}
642669
return TypeKindMapType, nil
643670
default:
644-
if _, ok := generator.GetEnum(ctx.files, strings.TrimSuffix(typeName, "AsString")); ok {
671+
if _, ok := tidl.GetEnum(ctx.files, strings.TrimSuffix(typeName, "AsString")); ok {
645672
if optional {
646673
return TypeKindOptionalEnumType, nil
647674
}
648675
return TypeKindEnumType, nil
649676
}
650-
if _, ok := generator.GetType(ctx.files, typeName); ok {
677+
if _, ok := tidl.GetType(ctx.files, typeName); ok {
651678
if optional {
652679
return TypeKindOptionalStructType, nil
653680
}
@@ -683,10 +710,10 @@ func parseDefault(ctx Context, typeName string, v *string) (*string, error) {
683710
// Handle enum values like EnumName.VALUE
684711
asString := strings.HasSuffix(typeName, "AsString")
685712
typeNameTrimmed := strings.TrimSuffix(typeName, "AsString")
686-
if _, ok := generator.GetEnum(ctx.files, typeNameTrimmed); !ok {
713+
if _, ok := tidl.GetEnum(ctx.files, typeNameTrimmed); !ok {
687714
return v, nil // Treat as a regular string
688715
}
689-
s := generator.CapitalizeASCII(parts[0]) + "_" + parts[1]
716+
s := tidl.CapitalizeASCII(parts[0]) + "_" + parts[1]
690717
if asString {
691718
s = fmt.Sprintf("%sAsString(%s)", typeNameTrimmed, s)
692719
}

gen/testdata/manager/go/manager_http_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ func (m *MyManagerServer) Stream(ctx context.Context, req *proto.StreamReq, resp
4242
for i := 0; i < 5; i++ {
4343
resp <- &proto.StreamResp{
4444
Id: strconv.Itoa(i),
45+
Payload: proto.Payload{
46+
FieldType: proto.PayloadType_TextData,
47+
TextData: "123",
48+
},
4549
}
4650
}
4751
}

0 commit comments

Comments
 (0)