From 1dceb1a2654bdc74ca97ad91f71f500eecc96269 Mon Sep 17 00:00:00 2001 From: David Symonds Date: Thu, 3 Sep 2015 11:38:02 +1000 Subject: [PATCH] Minor refactoring of oneof enabling. --- protoc-gen-go/generator/generator.go | 80 +++++++++++++++------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/protoc-gen-go/generator/generator.go b/protoc-gen-go/generator/generator.go index 40e08e57ac..fa1fcb9c21 100644 --- a/protoc-gen-go/generator/generator.go +++ b/protoc-gen-go/generator/generator.go @@ -136,6 +136,10 @@ func (d *Descriptor) TypeName() []string { return s } +func (d *Descriptor) allowOneof() bool { + return true +} + // EnumDescriptor describes an enum. If it's at top level, its parent will be nil. // Otherwise it will be the descriptor of the message in which it is defined. type EnumDescriptor struct { @@ -1516,7 +1520,7 @@ func (g *Generator) GoType(message *Descriptor, field *descriptor.FieldDescripto typ = "[]" + typ } else if message != nil && message.proto3() { return - } else if field.OneofIndex != nil && message != nil { + } else if field.OneofIndex != nil && message != nil && message.allowOneof() { return } else if needsStar(*field.Type) { typ = "*" + typ @@ -1589,7 +1593,7 @@ func (g *Generator) generateMessage(message *Descriptor) { fieldNames[field] = fieldName fieldGetterNames[field] = fieldGetterName - oneof := field.OneofIndex != nil + oneof := field.OneofIndex != nil && message.allowOneof() if oneof && oneofFieldName[*field.OneofIndex] == "" { odp := message.OneofDecl[int(*field.OneofIndex)] fname := allocName(odp.GetName()) @@ -1608,7 +1612,8 @@ func (g *Generator) generateMessage(message *Descriptor) { dname := "is" + ccTypeName + "_" + fname oneofFieldName[*field.OneofIndex] = fname oneofDisc[*field.OneofIndex] = dname - g.P(fname, " ", dname, " `protobuf_oneof:\"", odp.GetName(), "\"`") + tag := `protobuf_oneof:"` + odp.GetName() + `"` + g.P(fname, " ", dname, " `", tag, "`") } if *field.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE { @@ -1823,46 +1828,47 @@ func (g *Generator) generateMessage(message *Descriptor) { g.P() // Oneof per-field types, discriminants and getters. - // - // Generate unexported named types for the discriminant interfaces. - // We shouldn't have to do this, but there was (~19 Aug 2015) a compiler/linker bug - // that was triggered by using anonymous interfaces here. - // TODO: Revisit this and consider reverting back to anonymous interfaces. - for oi := range message.OneofDecl { - dname := oneofDisc[int32(oi)] - g.P("type ", dname, " interface { ", dname, "() }") - } - g.P() - for _, field := range message.Field { - if field.OneofIndex == nil { - continue + if message.allowOneof() { + // Generate unexported named types for the discriminant interfaces. + // We shouldn't have to do this, but there was (~19 Aug 2015) a compiler/linker bug + // that was triggered by using anonymous interfaces here. + // TODO: Revisit this and consider reverting back to anonymous interfaces. + for oi := range message.OneofDecl { + dname := oneofDisc[int32(oi)] + g.P("type ", dname, " interface { ", dname, "() }") } - _, wiretype := g.GoType(message, field) - tag := "protobuf:" + g.goTag(message, field, wiretype) - g.P("type ", oneofTypeName[field], " struct{ ", fieldNames[field], " ", fieldTypes[field], " `", tag, "` }") - g.RecordTypeUse(field.GetTypeName()) - } - g.P() - for _, field := range message.Field { - if field.OneofIndex == nil { - continue + g.P() + for _, field := range message.Field { + if field.OneofIndex == nil { + continue + } + _, wiretype := g.GoType(message, field) + tag := "protobuf:" + g.goTag(message, field, wiretype) + g.P("type ", oneofTypeName[field], " struct{ ", fieldNames[field], " ", fieldTypes[field], " `", tag, "` }") + g.RecordTypeUse(field.GetTypeName()) } - g.P("func (*", oneofTypeName[field], ") ", oneofDisc[*field.OneofIndex], "() {}") - } - g.P() - for oi := range message.OneofDecl { - fname := oneofFieldName[int32(oi)] - g.P("func (m *", ccTypeName, ") Get", fname, "() ", oneofDisc[int32(oi)], " {") - g.P("if m != nil { return m.", fname, " }") - g.P("return nil") - g.P("}") + g.P() + for _, field := range message.Field { + if field.OneofIndex == nil { + continue + } + g.P("func (*", oneofTypeName[field], ") ", oneofDisc[*field.OneofIndex], "() {}") + } + g.P() + for oi := range message.OneofDecl { + fname := oneofFieldName[int32(oi)] + g.P("func (m *", ccTypeName, ") Get", fname, "() ", oneofDisc[int32(oi)], " {") + g.P("if m != nil { return m.", fname, " }") + g.P("return nil") + g.P("}") + } + g.P() } - g.P() // Field getters var getters []getterSymbol for _, field := range message.Field { - oneof := field.OneofIndex != nil + oneof := field.OneofIndex != nil && message.allowOneof() fname := fieldNames[field] typename, _ := g.GoType(message, field) @@ -2006,7 +2012,7 @@ func (g *Generator) generateMessage(message *Descriptor) { } // Oneof functions - if len(message.OneofDecl) > 0 { + if len(message.OneofDecl) > 0 && message.allowOneof() { fieldWire := make(map[*descriptor.FieldDescriptorProto]string) // method