Skip to content

Commit 67448a7

Browse files
committed
Merge pull request #50 from prashantv/union
Add union support to parser and generator
2 parents 5c5d1ca + 1f45dcc commit 67448a7

File tree

5 files changed

+619
-487
lines changed

5 files changed

+619
-487
lines changed

generator/go.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,13 @@ func (g *GoGenerator) formatType(pkg string, thrift *parser.Thrift, typ *parser.
205205
}
206206
return "*" + name
207207
}
208+
if u := thrift.Unions[typ.Name]; u != nil {
209+
name := u.Name
210+
if pkg != g.pkg {
211+
name = pkg + "." + name
212+
}
213+
return "*" + name
214+
}
208215

209216
g.error(ErrUnknownType(typ.Name))
210217
return ""
@@ -642,6 +649,13 @@ func (g *GoGenerator) generateSingle(out io.Writer, thriftPath string, thrift *p
642649
}
643650
}
644651

652+
for _, k := range sortedKeys(thrift.Unions) {
653+
un := thrift.Unions[k]
654+
if err := g.writeStruct(out, un); err != nil {
655+
g.error(err)
656+
}
657+
}
658+
645659
for _, k := range sortedKeys(thrift.Services) {
646660
svc := thrift.Services[k]
647661
if err := g.writeService(out, svc); err != nil {

parser/grammar.peg

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ type typeDef struct {
2121

2222
type exception *Struct
2323

24+
type union *Struct
25+
2426
type include string
2527

2628
func toIfaceSlice(v interface{}) []interface{} {
@@ -38,6 +40,15 @@ func ifaceSliceToString(v interface{}) string {
3840
}
3941
return string(b)
4042
}
43+
44+
// toStruct converts a union to a struct with all fields optional.
45+
func unionToStruct(u union) *Struct {
46+
st := (*Struct)(u)
47+
for _, f := range st.Fields {
48+
f.Optional = true
49+
}
50+
return st
51+
}
4152
}
4253

4354
Grammar ← __ statements:( Statement __ )* (EOF / SyntaxError) {
@@ -49,6 +60,7 @@ Grammar ← __ statements:( Statement __ )* (EOF / SyntaxError) {
4960
Enums: make(map[string]*Enum),
5061
Structs: make(map[string]*Struct),
5162
Exceptions: make(map[string]*Struct),
63+
Unions: make(map[string]*Struct),
5264
Services: make(map[string]*Service),
5365
}
5466
stmts := toIfaceSlice(statements)
@@ -66,6 +78,8 @@ Grammar ← __ statements:( Statement __ )* (EOF / SyntaxError) {
6678
thrift.Structs[v.Name] = v
6779
case exception:
6880
thrift.Exceptions[v.Name] = (*Struct)(v)
81+
case union:
82+
thrift.Unions[v.Name] = unionToStruct(v)
6983
case *Service:
7084
thrift.Services[v.Name] = v
7185
case include:
@@ -89,7 +103,7 @@ Include ← "include" _ file:Literal EOS {
89103
return include(file.(string)), nil
90104
}
91105

92-
Statement ← Include / Namespace / Const / Enum / TypeDef / Struct / Exception / Service
106+
Statement ← Include / Namespace / Const / Enum / TypeDef / Struct / Exception / Union / Service
93107

94108
Namespace ← "namespace" _ scope:[a-z.-]+ _ ns:Identifier EOS {
95109
return &namespace{
@@ -149,6 +163,7 @@ TypeDef ← "typedef" _ typ:FieldType _ name:Identifier EOS {
149163

150164
Struct ← "struct" _ st:StructLike { return st.(*Struct), nil }
151165
Exception ← "exception" _ st:StructLike { return exception(st.(*Struct)), nil }
166+
Union ← "union" _ st:StructLike { return union(st.(*Struct)), nil }
152167
StructLike ← name:Identifier __ '{' __ fields:FieldList '}' EOS {
153168
st := &Struct{
154169
Name: string(name.(Identifier)),

0 commit comments

Comments
 (0)