Quellcode durchsuchen

Fix size of oneof fields when they are set to their zero value.

We use the proto3 sizers for oneof fields (because they don't have
a pointer in the wrapper struct), but they are always encoded when set,
so we should not skip their zero value.

Fixes #74.
David Symonds vor 10 Jahren
Ursprung
Commit
535a104686

+ 5 - 0
jsonpb/jsonpb_test_proto/more_test_objects.pb.go

@@ -12,6 +12,11 @@ It is generated from these files:
 It has these top-level messages:
 	Simple3
 	Mappy
+	Simple
+	Repeats
+	Widget
+	Maps
+	MsgWithOneof
 */
 package jsonpb
 

+ 2 - 2
jsonpb/jsonpb_test_proto/test_objects.pb.go

@@ -341,10 +341,10 @@ type isMsgWithOneof_Union interface {
 }
 
 type MsgWithOneof_Title struct {
-	Title string `protobuf:"bytes,1,opt,name=title"`
+	Title string `protobuf:"bytes,1,opt,name=title,oneof"`
 }
 type MsgWithOneof_Salary struct {
-	Salary int64 `protobuf:"varint,2,opt,name=salary"`
+	Salary int64 `protobuf:"varint,2,opt,name=salary,oneof"`
 }
 
 func (*MsgWithOneof_Title) isMsgWithOneof_Union()  {}

+ 7 - 7
proto/encode.go

@@ -332,7 +332,7 @@ func size_bool(p *Properties, base structPointer) int {
 
 func size_proto3_bool(p *Properties, base structPointer) int {
 	v := *structPointer_BoolVal(base, p.field)
-	if !v {
+	if !v && !p.oneof {
 		return 0
 	}
 	return len(p.tagcode) + 1 // each bool takes exactly one byte
@@ -375,7 +375,7 @@ func size_int32(p *Properties, base structPointer) (n int) {
 func size_proto3_int32(p *Properties, base structPointer) (n int) {
 	v := structPointer_Word32Val(base, p.field)
 	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 	}
 	n += len(p.tagcode)
@@ -421,7 +421,7 @@ func size_uint32(p *Properties, base structPointer) (n int) {
 func size_proto3_uint32(p *Properties, base structPointer) (n int) {
 	v := structPointer_Word32Val(base, p.field)
 	x := word32Val_Get(v)
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 	}
 	n += len(p.tagcode)
@@ -466,7 +466,7 @@ func size_int64(p *Properties, base structPointer) (n int) {
 func size_proto3_int64(p *Properties, base structPointer) (n int) {
 	v := structPointer_Word64Val(base, p.field)
 	x := word64Val_Get(v)
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 	}
 	n += len(p.tagcode)
@@ -509,7 +509,7 @@ func size_string(p *Properties, base structPointer) (n int) {
 
 func size_proto3_string(p *Properties, base structPointer) (n int) {
 	v := *structPointer_StringVal(base, p.field)
-	if v == "" {
+	if v == "" && !p.oneof {
 		return 0
 	}
 	n += len(p.tagcode)
@@ -681,7 +681,7 @@ func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error
 
 func size_slice_byte(p *Properties, base structPointer) (n int) {
 	s := *structPointer_Bytes(base, p.field)
-	if s == nil {
+	if s == nil && !p.oneof {
 		return 0
 	}
 	n += len(p.tagcode)
@@ -691,7 +691,7 @@ func size_slice_byte(p *Properties, base structPointer) (n int) {
 
 func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
 	s := *structPointer_Bytes(base, p.field)
-	if len(s) == 0 {
+	if len(s) == 0 && !p.oneof {
 		return 0
 	}
 	n += len(p.tagcode)

+ 6 - 0
proto/properties.go

@@ -177,6 +177,7 @@ type Properties struct {
 	Packed   bool   // relevant for repeated primitives only
 	Enum     string // set for enum types only
 	proto3   bool   // whether this is known to be a proto3 field; set for []byte only
+	oneof    bool   // whether this is a oneof field
 
 	Default    string // default value
 	HasDefault bool   // whether an explicit default was provided
@@ -229,6 +230,9 @@ func (p *Properties) String() string {
 	if p.proto3 {
 		s += ",proto3"
 	}
+	if p.oneof {
+		s += ",oneof"
+	}
 	if len(p.Enum) > 0 {
 		s += ",enum=" + p.Enum
 	}
@@ -305,6 +309,8 @@ func (p *Properties) Parse(s string) {
 			p.Enum = f[5:]
 		case f == "proto3":
 			p.proto3 = true
+		case f == "oneof":
+			p.oneof = true
 		case strings.HasPrefix(f, "def="):
 			p.HasDefault = true
 			p.Default = f[4:] // rest of string

+ 1 - 0
proto/size_test.go

@@ -126,6 +126,7 @@ var SizeTests = []struct {
 	{"map field with big numeric key", &pb.MessageWithMap{NameMapping: map[int32]string{0xf00d: "om nom nom"}}},
 
 	{"oneof not set", &pb.Communique{}},
+	{"oneof zero int32", &pb.Communique{Union: &pb.Communique_Number{0}}},
 	{"oneof int32", &pb.Communique{Union: &pb.Communique_Number{3}}},
 	{"oneof string", &pb.Communique{Union: &pb.Communique_Name{"Rhythmic Fman"}}},
 }

+ 37 - 37
proto/testdata/test.pb.go

@@ -304,8 +304,8 @@ func (m *GoEnum) GetFoo() FOO {
 }
 
 type GoTestField struct {
-	Label            *string `protobuf:"bytes,1,req" json:"Label,omitempty"`
-	Type             *string `protobuf:"bytes,2,req" json:"Type,omitempty"`
+	Label            *string `protobuf:"bytes,1,req,name=Label" json:"Label,omitempty"`
+	Type             *string `protobuf:"bytes,2,req,name=Type" json:"Type,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
 }
 
@@ -329,13 +329,13 @@ func (m *GoTestField) GetType() string {
 
 type GoTest struct {
 	// Some typical parameters
-	Kind  *GoTest_KIND `protobuf:"varint,1,req,enum=testdata.GoTest_KIND" json:"Kind,omitempty"`
-	Table *string      `protobuf:"bytes,2,opt" json:"Table,omitempty"`
-	Param *int32       `protobuf:"varint,3,opt" json:"Param,omitempty"`
+	Kind  *GoTest_KIND `protobuf:"varint,1,req,name=Kind,enum=testdata.GoTest_KIND" json:"Kind,omitempty"`
+	Table *string      `protobuf:"bytes,2,opt,name=Table" json:"Table,omitempty"`
+	Param *int32       `protobuf:"varint,3,opt,name=Param" json:"Param,omitempty"`
 	// Required, repeated and optional foreign fields.
-	RequiredField *GoTestField   `protobuf:"bytes,4,req" json:"RequiredField,omitempty"`
-	RepeatedField []*GoTestField `protobuf:"bytes,5,rep" json:"RepeatedField,omitempty"`
-	OptionalField *GoTestField   `protobuf:"bytes,6,opt" json:"OptionalField,omitempty"`
+	RequiredField *GoTestField   `protobuf:"bytes,4,req,name=RequiredField" json:"RequiredField,omitempty"`
+	RepeatedField []*GoTestField `protobuf:"bytes,5,rep,name=RepeatedField" json:"RepeatedField,omitempty"`
+	OptionalField *GoTestField   `protobuf:"bytes,6,opt,name=OptionalField" json:"OptionalField,omitempty"`
 	// Required fields of all basic types
 	F_BoolRequired    *bool    `protobuf:"varint,10,req,name=F_Bool_required" json:"F_Bool_required,omitempty"`
 	F_Int32Required   *int32   `protobuf:"varint,11,req,name=F_Int32_required" json:"F_Int32_required,omitempty"`
@@ -936,7 +936,7 @@ func (m *GoTest) GetOptionalgroup() *GoTest_OptionalGroup {
 
 // Required, repeated, and optional groups.
 type GoTest_RequiredGroup struct {
-	RequiredField    *string `protobuf:"bytes,71,req" json:"RequiredField,omitempty"`
+	RequiredField    *string `protobuf:"bytes,71,req,name=RequiredField" json:"RequiredField,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
 }
 
@@ -952,7 +952,7 @@ func (m *GoTest_RequiredGroup) GetRequiredField() string {
 }
 
 type GoTest_RepeatedGroup struct {
-	RequiredField    *string `protobuf:"bytes,81,req" json:"RequiredField,omitempty"`
+	RequiredField    *string `protobuf:"bytes,81,req,name=RequiredField" json:"RequiredField,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
 }
 
@@ -968,7 +968,7 @@ func (m *GoTest_RepeatedGroup) GetRequiredField() string {
 }
 
 type GoTest_OptionalGroup struct {
-	RequiredField    *string `protobuf:"bytes,91,req" json:"RequiredField,omitempty"`
+	RequiredField    *string `protobuf:"bytes,91,req,name=RequiredField" json:"RequiredField,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
 }
 
@@ -1514,7 +1514,7 @@ func (m *Empty) String() string { return proto.CompactTextString(m) }
 func (*Empty) ProtoMessage()    {}
 
 type MessageList struct {
-	Message          []*MessageList_Message `protobuf:"group,1,rep" json:"message,omitempty"`
+	Message          []*MessageList_Message `protobuf:"group,1,rep,name=Message" json:"message,omitempty"`
 	XXX_unrecognized []byte                 `json:"-"`
 }
 
@@ -1580,24 +1580,24 @@ func (m *Strings) GetBytesField() []byte {
 type Defaults struct {
 	// Default-valued fields of all basic types.
 	// Same as GoTest, but copied here to make testing easier.
-	F_Bool    *bool           `protobuf:"varint,1,opt,def=1" json:"F_Bool,omitempty"`
-	F_Int32   *int32          `protobuf:"varint,2,opt,def=32" json:"F_Int32,omitempty"`
-	F_Int64   *int64          `protobuf:"varint,3,opt,def=64" json:"F_Int64,omitempty"`
-	F_Fixed32 *uint32         `protobuf:"fixed32,4,opt,def=320" json:"F_Fixed32,omitempty"`
-	F_Fixed64 *uint64         `protobuf:"fixed64,5,opt,def=640" json:"F_Fixed64,omitempty"`
-	F_Uint32  *uint32         `protobuf:"varint,6,opt,def=3200" json:"F_Uint32,omitempty"`
-	F_Uint64  *uint64         `protobuf:"varint,7,opt,def=6400" json:"F_Uint64,omitempty"`
-	F_Float   *float32        `protobuf:"fixed32,8,opt,def=314159" json:"F_Float,omitempty"`
-	F_Double  *float64        `protobuf:"fixed64,9,opt,def=271828" json:"F_Double,omitempty"`
-	F_String  *string         `protobuf:"bytes,10,opt,def=hello, \"world!\"\n" json:"F_String,omitempty"`
-	F_Bytes   []byte          `protobuf:"bytes,11,opt,def=Bignose" json:"F_Bytes,omitempty"`
-	F_Sint32  *int32          `protobuf:"zigzag32,12,opt,def=-32" json:"F_Sint32,omitempty"`
-	F_Sint64  *int64          `protobuf:"zigzag64,13,opt,def=-64" json:"F_Sint64,omitempty"`
-	F_Enum    *Defaults_Color `protobuf:"varint,14,opt,enum=testdata.Defaults_Color,def=1" json:"F_Enum,omitempty"`
+	F_Bool    *bool           `protobuf:"varint,1,opt,name=F_Bool,def=1" json:"F_Bool,omitempty"`
+	F_Int32   *int32          `protobuf:"varint,2,opt,name=F_Int32,def=32" json:"F_Int32,omitempty"`
+	F_Int64   *int64          `protobuf:"varint,3,opt,name=F_Int64,def=64" json:"F_Int64,omitempty"`
+	F_Fixed32 *uint32         `protobuf:"fixed32,4,opt,name=F_Fixed32,def=320" json:"F_Fixed32,omitempty"`
+	F_Fixed64 *uint64         `protobuf:"fixed64,5,opt,name=F_Fixed64,def=640" json:"F_Fixed64,omitempty"`
+	F_Uint32  *uint32         `protobuf:"varint,6,opt,name=F_Uint32,def=3200" json:"F_Uint32,omitempty"`
+	F_Uint64  *uint64         `protobuf:"varint,7,opt,name=F_Uint64,def=6400" json:"F_Uint64,omitempty"`
+	F_Float   *float32        `protobuf:"fixed32,8,opt,name=F_Float,def=314159" json:"F_Float,omitempty"`
+	F_Double  *float64        `protobuf:"fixed64,9,opt,name=F_Double,def=271828" json:"F_Double,omitempty"`
+	F_String  *string         `protobuf:"bytes,10,opt,name=F_String,def=hello, \"world!\"\n" json:"F_String,omitempty"`
+	F_Bytes   []byte          `protobuf:"bytes,11,opt,name=F_Bytes,def=Bignose" json:"F_Bytes,omitempty"`
+	F_Sint32  *int32          `protobuf:"zigzag32,12,opt,name=F_Sint32,def=-32" json:"F_Sint32,omitempty"`
+	F_Sint64  *int64          `protobuf:"zigzag64,13,opt,name=F_Sint64,def=-64" json:"F_Sint64,omitempty"`
+	F_Enum    *Defaults_Color `protobuf:"varint,14,opt,name=F_Enum,enum=testdata.Defaults_Color,def=1" json:"F_Enum,omitempty"`
 	// More fields with crazy defaults.
-	F_Pinf *float32 `protobuf:"fixed32,15,opt,def=inf" json:"F_Pinf,omitempty"`
-	F_Ninf *float32 `protobuf:"fixed32,16,opt,def=-inf" json:"F_Ninf,omitempty"`
-	F_Nan  *float32 `protobuf:"fixed32,17,opt,def=nan" json:"F_Nan,omitempty"`
+	F_Pinf *float32 `protobuf:"fixed32,15,opt,name=F_Pinf,def=inf" json:"F_Pinf,omitempty"`
+	F_Ninf *float32 `protobuf:"fixed32,16,opt,name=F_Ninf,def=-inf" json:"F_Ninf,omitempty"`
+	F_Nan  *float32 `protobuf:"fixed32,17,opt,name=F_Nan,def=nan" json:"F_Nan,omitempty"`
 	// Sub-message.
 	Sub *SubDefaults `protobuf:"bytes,18,opt,name=sub" json:"sub,omitempty"`
 	// Redundant but explicit defaults.
@@ -1862,7 +1862,7 @@ func (m *MoreRepeated) GetFixeds() []uint32 {
 }
 
 type GroupOld struct {
-	G                *GroupOld_G `protobuf:"group,101,opt" json:"g,omitempty"`
+	G                *GroupOld_G `protobuf:"group,101,opt,name=G" json:"g,omitempty"`
 	XXX_unrecognized []byte      `json:"-"`
 }
 
@@ -1894,7 +1894,7 @@ func (m *GroupOld_G) GetX() int32 {
 }
 
 type GroupNew struct {
-	G                *GroupNew_G `protobuf:"group,101,opt" json:"g,omitempty"`
+	G                *GroupNew_G `protobuf:"group,101,opt,name=G" json:"g,omitempty"`
 	XXX_unrecognized []byte      `json:"-"`
 }
 
@@ -2013,22 +2013,22 @@ type isCommunique_Union interface {
 }
 
 type Communique_Number struct {
-	Number int32 `protobuf:"varint,5,opt,name=number"`
+	Number int32 `protobuf:"varint,5,opt,name=number,oneof"`
 }
 type Communique_Name struct {
-	Name string `protobuf:"bytes,6,opt,name=name"`
+	Name string `protobuf:"bytes,6,opt,name=name,oneof"`
 }
 type Communique_Data struct {
-	Data []byte `protobuf:"bytes,7,opt,name=data"`
+	Data []byte `protobuf:"bytes,7,opt,name=data,oneof"`
 }
 type Communique_TempC struct {
-	TempC float64 `protobuf:"fixed64,8,opt,name=temp_c"`
+	TempC float64 `protobuf:"fixed64,8,opt,name=temp_c,oneof"`
 }
 type Communique_Col struct {
-	Col MyMessage_Color `protobuf:"varint,9,opt,name=col,enum=testdata.MyMessage_Color"`
+	Col MyMessage_Color `protobuf:"varint,9,opt,name=col,enum=testdata.MyMessage_Color,oneof"`
 }
 type Communique_Msg struct {
-	Msg *Strings `protobuf:"bytes,10,opt,name=msg"`
+	Msg *Strings `protobuf:"bytes,10,opt,name=msg,oneof"`
 }
 
 func (*Communique_Number) isCommunique_Union() {}

+ 42 - 6
protoc-gen-go/generator/generator.go

@@ -303,7 +303,7 @@ type getterSymbol struct {
 	name     string
 	typ      string
 	typeName string // canonical name in proto world; empty for proto.Message and similar
-	genType  bool   // whether typ is a generated type (message/group/enum)
+	genType  bool   // whether typ contains a generated type (message/group/enum)
 }
 
 func (ms *messageSymbol) GenerateAlias(g *Generator, pkg string) {
@@ -333,15 +333,19 @@ func (ms *messageSymbol) GenerateAlias(g *Generator, pkg string) {
 		typ := get.typ
 		val := "(*" + remoteSym + ")(m)." + get.name + "()"
 		if get.genType {
-			// typ will be "*pkg.T" (message/group) or "pkg.T" (enum).
-			// Either of those might have a "[]" prefix if it is repeated.
-			// Drop the package qualifier since we have hoisted the type into this package.
+			// typ will be "*pkg.T" (message/group) or "pkg.T" (enum)
+			// or "map[t]*pkg.T" (map to message/enum).
+			// The first two of those might have a "[]" prefix if it is repeated.
+			// Drop any package qualifier since we have hoisted the type into this package.
 			rep := strings.HasPrefix(typ, "[]")
 			if rep {
 				typ = typ[2:]
 			}
+			isMap := strings.HasPrefix(typ, "map[")
 			star := typ[0] == '*'
-			typ = typ[strings.Index(typ, ".")+1:]
+			if !isMap { // map types handled lower down
+				typ = typ[strings.Index(typ, ".")+1:]
+			}
 			if star {
 				typ = "*" + typ
 			}
@@ -376,6 +380,30 @@ func (ms *messageSymbol) GenerateAlias(g *Generator, pkg string) {
 				g.P("}")
 				continue
 			}
+			if isMap {
+				// Split map[keyTyp]valTyp.
+				bra, ket := strings.Index(typ, "["), strings.Index(typ, "]")
+				keyTyp, valTyp := typ[bra+1:ket], typ[ket+1:]
+				// Drop any package qualifier.
+				// Only the value type may be foreign.
+				star := valTyp[0] == '*'
+				valTyp = valTyp[strings.Index(valTyp, ".")+1:]
+				if star {
+					valTyp = "*" + valTyp
+				}
+
+				typ := "map[" + keyTyp + "]" + valTyp
+				g.P("func (m *", ms.sym, ") ", get.name, "() ", typ, " {")
+				g.P("o := ", val)
+				g.P("if o == nil { return nil }")
+				g.P("s := make(", typ, ", len(o))")
+				g.P("for k, v := range o {")
+				g.P("s[k] = (", valTyp, ")(v)")
+				g.P("}")
+				g.P("return s")
+				g.P("}")
+				continue
+			}
 			// Convert imported type into the forwarding type.
 			val = "(" + typ + ")(" + val + ")"
 		}
@@ -863,6 +891,9 @@ func wrapImported(file *descriptor.FileDescriptorProto, g *Generator) (sl []*Imp
 	for _, index := range file.PublicDependency {
 		df := g.fileByName(file.Dependency[index])
 		for _, d := range df.desc {
+			if d.GetOptions().GetMapEntry() {
+				continue
+			}
 			sl = append(sl, &ImportedDescriptor{common{file}, d})
 		}
 		for _, e := range df.enum {
@@ -1433,13 +1464,18 @@ func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptor
 			name += ",proto3"
 		}
 	}
-	return strconv.Quote(fmt.Sprintf("%s,%d,%s%s%s%s%s",
+	oneof := ""
+	if field.OneofIndex != nil {
+		oneof = ",oneof"
+	}
+	return strconv.Quote(fmt.Sprintf("%s,%d,%s%s%s%s%s%s",
 		wiretype,
 		field.GetNumber(),
 		optrepreq,
 		packed,
 		name,
 		enum,
+		oneof,
 		defaultValue))
 }
 

+ 2 - 0
protoc-gen-go/testdata/imp.proto

@@ -48,6 +48,8 @@ message ImportedMessage {
   repeated Owner boss = 6;
   repeated ImportedMessage2 memo = 7;
 
+  map<string, ImportedMessage2> msg_map = 8;
+
   enum Owner {
     DAVE = 1;
     MIKE = 2;

+ 10 - 10
protoc-gen-go/testdata/my_test/test.pb.go

@@ -489,34 +489,34 @@ type isCommunique_Union interface {
 }
 
 type Communique_Number struct {
-	Number int32 `protobuf:"varint,5,opt,name=number"`
+	Number int32 `protobuf:"varint,5,opt,name=number,oneof"`
 }
 type Communique_Name struct {
-	Name string `protobuf:"bytes,6,opt,name=name"`
+	Name string `protobuf:"bytes,6,opt,name=name,oneof"`
 }
 type Communique_Data struct {
-	Data []byte `protobuf:"bytes,7,opt,name=data"`
+	Data []byte `protobuf:"bytes,7,opt,name=data,oneof"`
 }
 type Communique_TempC struct {
-	TempC float64 `protobuf:"fixed64,8,opt,name=temp_c"`
+	TempC float64 `protobuf:"fixed64,8,opt,name=temp_c,oneof"`
 }
 type Communique_Height struct {
-	Height float32 `protobuf:"fixed32,9,opt,name=height"`
+	Height float32 `protobuf:"fixed32,9,opt,name=height,oneof"`
 }
 type Communique_Today struct {
-	Today Days `protobuf:"varint,10,opt,name=today,enum=my.test.Days"`
+	Today Days `protobuf:"varint,10,opt,name=today,enum=my.test.Days,oneof"`
 }
 type Communique_Maybe struct {
-	Maybe bool `protobuf:"varint,11,opt,name=maybe"`
+	Maybe bool `protobuf:"varint,11,opt,name=maybe,oneof"`
 }
 type Communique_Delta_ struct {
-	Delta int32 `protobuf:"zigzag32,12,opt,name=delta"`
+	Delta int32 `protobuf:"zigzag32,12,opt,name=delta,oneof"`
 }
 type Communique_Msg struct {
-	Msg *Reply `protobuf:"bytes,13,opt,name=msg"`
+	Msg *Reply `protobuf:"bytes,13,opt,name=msg,oneof"`
 }
 type Communique_Somegroup struct {
-	Somegroup *Communique_SomeGroup `protobuf:"group,14,opt,name=SomeGroup"`
+	Somegroup *Communique_SomeGroup `protobuf:"group,14,opt,name=SomeGroup,oneof"`
 }
 
 func (*Communique_Number) isCommunique_Union()    {}

+ 10 - 10
protoc-gen-go/testdata/my_test/test.pb.go.golden

@@ -489,34 +489,34 @@ type isCommunique_Union interface {
 }
 
 type Communique_Number struct {
-	Number int32 `protobuf:"varint,5,opt,name=number"`
+	Number int32 `protobuf:"varint,5,opt,name=number,oneof"`
 }
 type Communique_Name struct {
-	Name string `protobuf:"bytes,6,opt,name=name"`
+	Name string `protobuf:"bytes,6,opt,name=name,oneof"`
 }
 type Communique_Data struct {
-	Data []byte `protobuf:"bytes,7,opt,name=data"`
+	Data []byte `protobuf:"bytes,7,opt,name=data,oneof"`
 }
 type Communique_TempC struct {
-	TempC float64 `protobuf:"fixed64,8,opt,name=temp_c"`
+	TempC float64 `protobuf:"fixed64,8,opt,name=temp_c,oneof"`
 }
 type Communique_Height struct {
-	Height float32 `protobuf:"fixed32,9,opt,name=height"`
+	Height float32 `protobuf:"fixed32,9,opt,name=height,oneof"`
 }
 type Communique_Today struct {
-	Today Days `protobuf:"varint,10,opt,name=today,enum=my.test.Days"`
+	Today Days `protobuf:"varint,10,opt,name=today,enum=my.test.Days,oneof"`
 }
 type Communique_Maybe struct {
-	Maybe bool `protobuf:"varint,11,opt,name=maybe"`
+	Maybe bool `protobuf:"varint,11,opt,name=maybe,oneof"`
 }
 type Communique_Delta_ struct {
-	Delta int32 `protobuf:"zigzag32,12,opt,name=delta"`
+	Delta int32 `protobuf:"zigzag32,12,opt,name=delta,oneof"`
 }
 type Communique_Msg struct {
-	Msg *Reply `protobuf:"bytes,13,opt,name=msg"`
+	Msg *Reply `protobuf:"bytes,13,opt,name=msg,oneof"`
 }
 type Communique_Somegroup struct {
-	Somegroup *Communique_SomeGroup `protobuf:"group,14,opt,name=SomeGroup"`
+	Somegroup *Communique_SomeGroup `protobuf:"group,14,opt,name=SomeGroup,oneof"`
 }
 
 func (*Communique_Number) isCommunique_Union()    {}