Kaynağa Gözat

Minor refactoring of oneof enabling.

David Symonds 10 yıl önce
ebeveyn
işleme
1dceb1a265
1 değiştirilmiş dosya ile 43 ekleme ve 37 silme
  1. 43 37
      protoc-gen-go/generator/generator.go

+ 43 - 37
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