goprotobuf: Better enum construction.

R=r
CC=golang-dev
http://codereview.appspot.com/6188053
diff --git a/proto/all_test.go b/proto/all_test.go
index edf0ca5..4a58ebe 100644
--- a/proto/all_test.go
+++ b/proto/all_test.go
@@ -115,7 +115,7 @@
 		pb.F_Sint64Defaulted = Int64(Default_GoTest_F_Sint64Defaulted)
 	}
 
-	pb.Kind = NewGoTest_KIND(GoTest_TIME)
+	pb.Kind = GoTest_TIME.Enum()
 	pb.RequiredField = initGoTestField()
 	pb.F_BoolRequired = Bool(true)
 	pb.F_Int32Required = Int32(3)
@@ -1129,7 +1129,7 @@
 // a type mismatch in reflect.PointTo.
 func TestEnum(t *testing.T) {
 	pb := new(GoEnum)
-	pb.Foo = NewFOO(FOO_FOO1)
+	pb.Foo = FOO_FOO1.Enum()
 	o := old()
 	if err := o.Marshal(pb); err != nil {
 		t.Fatal("error encoding enum:", err)
@@ -1250,7 +1250,7 @@
 		F_Bytes:   []byte("Bignose"),
 		F_Sint32:  Int32(-32),
 		F_Sint64:  Int64(-64),
-		F_Enum:    NewDefaults_Color(Defaults_GREEN),
+		F_Enum:    Defaults_GREEN.Enum(),
 		F_Pinf:    Float32(float32(math.Inf(1))),
 		F_Ninf:    Float32(float32(math.Inf(-1))),
 		F_Nan:     Float32(1.7),
diff --git a/proto/lib.go b/proto/lib.go
index 86187e0..50f694e 100644
--- a/proto/lib.go
+++ b/proto/lib.go
@@ -30,9 +30,9 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 /*
-	The proto package converts data structures to and from the
-	wire format of protocol buffers.  It works in concert with the
-	Go source code generated for .proto files by the protocol compiler.
+	Package proto converts data structures to and from the wire format of
+	protocol buffers.  It works in concert with the Go source code generated
+	for .proto files by the protocol compiler.
 
 	A summary of the properties of the protocol buffer interface
 	for a protocol buffer variable v:
@@ -51,9 +51,9 @@
 	  	s := proto.GetString(foo.String)  // get field
 	  - Constants are defined to hold the default values of all fields that
 		have them.  They have the form Default_StructName_FieldName.
-	  - Enums are given type names and maps between names to values,
-	  	plus a helper function to create values.  Enum values are prefixed
-	  	with the enum's type name. Enum types have a String method.
+	  - Enums are given type names and maps from names to values.
+		Enum values are prefixed with the enum's type name. Enum types have
+		a String method, and a Enum method to assist in message construction.
 	  - Nested groups and enums have type names prefixed with the name of
 	  	the surrounding message type.
 	  - Extensions are given descriptor names that start with E_,
@@ -76,7 +76,7 @@
 		  repeated int64 reps = 3;
 		  optional group OptionalGroup = 4 {
 		    required string RequiredField = 5;
-		  };
+		  }
 		}
 
 	The resulting file, test.pb.go, is:
@@ -87,41 +87,41 @@
 
 		type FOO int32
 		const (
-			FOO_X = 17
+			FOO_X FOO = 17
 		)
-		var FOO_name = map[int32] string {
+		var FOO_name = map[int32]string{
 			17: "X",
 		}
-		var FOO_value = map[string] int32 {
+		var FOO_value = map[string]int32{
 			"X": 17,
 		}
-		func NewFOO(x int32) *FOO {
-			e := FOO(x)
-			return &e
+
+		func (x FOO) Enum() *FOO {
+			p := new(FOO)
+			*p = x
+			return p
 		}
 		func (x FOO) String() string {
 			return proto.EnumName(FOO_name, int32(x))
 		}
 
 		type Test struct {
-			Label	*string	`protobuf:"bytes,1,req,name=label"`
-			Type	*int32	`protobuf:"varint,2,opt,name=type,def=77"`
-			Reps	[]int64	`protobuf:"varint,3,rep,name=reps"`
-			Optionalgroup	*Test_OptionalGroup	`protobuf:"group,4,opt,name=optionalgroup"`
-			XXX_unrecognized []byte
+			Label            *string             `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
+			Type             *int32              `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
+			Reps             []int64             `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
+			Optionalgroup    *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
+			XXX_unrecognized []byte              `json:"-"`
 		}
-		func (this *Test) Reset() {
-			*this = Test{}
-		}
+		func (this *Test) Reset()         { *this = Test{} }
+		func (this *Test) String() string { return proto.CompactTextString(this) }
 		const Default_Test_Type int32 = 77
 
 		type Test_OptionalGroup struct {
-			RequiredField	*string	`protobuf:"bytes,5,req"`
-			XXX_unrecognized []byte
+			RequiredField    *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
+			XXX_unrecognized []byte  `json:"-"`
 		}
-		func (this *Test_OptionalGroup) Reset() {
-			*this = Test_OptionalGroup{}
-		}
+		func (this *Test_OptionalGroup) Reset()         { *this = Test_OptionalGroup{} }
+		func (this *Test_OptionalGroup) String() string { return proto.CompactTextString(this) }
 
 		func init() {
 			proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
@@ -141,7 +141,7 @@
 		func main() {
 			test := &example.Test{
 				Label: proto.String("hello"),
-				Type: proto.Int32(17),
+				Type:  proto.Int32(17),
 				Optionalgroup: &example.Test_OptionalGroup{
 					RequiredField: proto.String("good bye"),
 				},
diff --git a/proto/testdata/test.pb.go b/proto/testdata/test.pb.go
index fdf5500..51e0252 100644
--- a/proto/testdata/test.pb.go
+++ b/proto/testdata/test.pb.go
@@ -23,10 +23,16 @@
 	"FOO1": 1,
 }
 
+// NewFOO is deprecated. Use x.Enum() instead.
 func NewFOO(x FOO) *FOO {
 	e := FOO(x)
 	return &e
 }
+func (x FOO) Enum() *FOO {
+	p := new(FOO)
+	*p = x
+	return p
+}
 func (x FOO) String() string {
 	return proto.EnumName(FOO_name, int32(x))
 }
@@ -80,10 +86,16 @@
 	"FUNCTION":    12,
 }
 
+// NewGoTest_KIND is deprecated. Use x.Enum() instead.
 func NewGoTest_KIND(x GoTest_KIND) *GoTest_KIND {
 	e := GoTest_KIND(x)
 	return &e
 }
+func (x GoTest_KIND) Enum() *GoTest_KIND {
+	p := new(GoTest_KIND)
+	*p = x
+	return p
+}
 func (x GoTest_KIND) String() string {
 	return proto.EnumName(GoTest_KIND_name, int32(x))
 }
@@ -107,10 +119,16 @@
 	"BLUE":  2,
 }
 
+// NewMyMessage_Color is deprecated. Use x.Enum() instead.
 func NewMyMessage_Color(x MyMessage_Color) *MyMessage_Color {
 	e := MyMessage_Color(x)
 	return &e
 }
+func (x MyMessage_Color) Enum() *MyMessage_Color {
+	p := new(MyMessage_Color)
+	*p = x
+	return p
+}
 func (x MyMessage_Color) String() string {
 	return proto.EnumName(MyMessage_Color_name, int32(x))
 }
@@ -134,10 +152,16 @@
 	"BLUE":  2,
 }
 
+// NewDefaults_Color is deprecated. Use x.Enum() instead.
 func NewDefaults_Color(x Defaults_Color) *Defaults_Color {
 	e := Defaults_Color(x)
 	return &e
 }
+func (x Defaults_Color) Enum() *Defaults_Color {
+	p := new(Defaults_Color)
+	*p = x
+	return p
+}
 func (x Defaults_Color) String() string {
 	return proto.EnumName(Defaults_Color_name, int32(x))
 }
@@ -155,10 +179,16 @@
 	"RED": 1,
 }
 
+// NewRepeatedEnum_Color is deprecated. Use x.Enum() instead.
 func NewRepeatedEnum_Color(x RepeatedEnum_Color) *RepeatedEnum_Color {
 	e := RepeatedEnum_Color(x)
 	return &e
 }
+func (x RepeatedEnum_Color) Enum() *RepeatedEnum_Color {
+	p := new(RepeatedEnum_Color)
+	*p = x
+	return p
+}
 func (x RepeatedEnum_Color) String() string {
 	return proto.EnumName(RepeatedEnum_Color_name, int32(x))
 }
diff --git a/proto/text_parser_test.go b/proto/text_parser_test.go
index dbd6b2c..f9f09d9 100644
--- a/proto/text_parser_test.go
+++ b/proto/text_parser_test.go
@@ -158,7 +158,7 @@
 		in: `count:42 bikeshed: BLUE`,
 		out: &MyMessage{
 			Count:    Int32(42),
-			Bikeshed: NewMyMessage_Color(MyMessage_BLUE),
+			Bikeshed: MyMessage_BLUE.Enum(),
 		},
 	},
 
diff --git a/proto/text_test.go b/proto/text_test.go
index f09b1ab..049eded 100644
--- a/proto/text_test.go
+++ b/proto/text_test.go
@@ -65,7 +65,7 @@
 				},
 			},
 		},
-		Bikeshed: pb.NewMyMessage_Color(pb.MyMessage_BLUE),
+		Bikeshed: pb.MyMessage_BLUE.Enum(),
 		Somegroup: &pb.MyMessage_SomeGroup{
 			GroupField: proto.Int32(8),
 		},
diff --git a/protoc-gen-go/generator/generator.go b/protoc-gen-go/generator/generator.go
index 7737aae..4c1b044 100644
--- a/protoc-gen-go/generator/generator.go
+++ b/protoc-gen-go/generator/generator.go
@@ -933,6 +933,7 @@
 	g.Out()
 	g.P("}")
 
+	g.P("// New", ccTypeName, " is deprecated. Use x.Enum() instead.")
 	g.P("func New", ccTypeName, "(x ", ccTypeName, ") *", ccTypeName, " {")
 	g.In()
 	g.P("e := ", ccTypeName, "(x)")
@@ -940,6 +941,14 @@
 	g.Out()
 	g.P("}")
 
+	g.P("func (x ", ccTypeName, ") Enum() *", ccTypeName, " {")
+	g.In()
+	g.P("p := new(", ccTypeName, ")")
+	g.P("*p = x")
+	g.P("return p")
+	g.Out()
+	g.P("}")
+
 	g.P("func (x ", ccTypeName, ") String() string {")
 	g.In()
 	g.P("return ", g.ProtoPkg, ".EnumName(", ccTypeName, "_name, int32(x))")
diff --git a/protoc-gen-go/testdata/imp.pb.go.golden b/protoc-gen-go/testdata/imp.pb.go.golden
index 831b66a..26bf6c6 100644
--- a/protoc-gen-go/testdata/imp.pb.go.golden
+++ b/protoc-gen-go/testdata/imp.pb.go.golden
@@ -38,10 +38,16 @@
 	"MIKE": 2,
 }
 
+// NewImportedMessage_Owner is deprecated. Use x.Enum() instead.
 func NewImportedMessage_Owner(x ImportedMessage_Owner) *ImportedMessage_Owner {
 	e := ImportedMessage_Owner(x)
 	return &e
 }
+func (x ImportedMessage_Owner) Enum() *ImportedMessage_Owner {
+	p := new(ImportedMessage_Owner)
+	*p = x
+	return p
+}
 func (x ImportedMessage_Owner) String() string {
 	return proto.EnumName(ImportedMessage_Owner_name, int32(x))
 }
diff --git a/protoc-gen-go/testdata/my_test/test.pb.go b/protoc-gen-go/testdata/my_test/test.pb.go
index 9019a6a..a658f02 100644
--- a/protoc-gen-go/testdata/my_test/test.pb.go
+++ b/protoc-gen-go/testdata/my_test/test.pb.go
@@ -28,10 +28,16 @@
 	"FEZ":    2,
 }
 
+// NewHatType is deprecated. Use x.Enum() instead.
 func NewHatType(x HatType) *HatType {
 	e := HatType(x)
 	return &e
 }
+func (x HatType) Enum() *HatType {
+	p := new(HatType)
+	*p = x
+	return p
+}
 func (x HatType) String() string {
 	return proto.EnumName(HatType_name, int32(x))
 }
@@ -55,10 +61,16 @@
 	"LUNDI":   1,
 }
 
+// NewDays is deprecated. Use x.Enum() instead.
 func NewDays(x Days) *Days {
 	e := Days(x)
 	return &e
 }
+func (x Days) Enum() *Days {
+	p := new(Days)
+	*p = x
+	return p
+}
 func (x Days) String() string {
 	return proto.EnumName(Days_name, int32(x))
 }
@@ -82,10 +94,16 @@
 	"BLUE":  2,
 }
 
+// NewRequest_Color is deprecated. Use x.Enum() instead.
 func NewRequest_Color(x Request_Color) *Request_Color {
 	e := Request_Color(x)
 	return &e
 }
+func (x Request_Color) Enum() *Request_Color {
+	p := new(Request_Color)
+	*p = x
+	return p
+}
 func (x Request_Color) String() string {
 	return proto.EnumName(Request_Color_name, int32(x))
 }
@@ -106,10 +124,16 @@
 	"TENNIS":   2,
 }
 
+// NewReply_Entry_Game is deprecated. Use x.Enum() instead.
 func NewReply_Entry_Game(x Reply_Entry_Game) *Reply_Entry_Game {
 	e := Reply_Entry_Game(x)
 	return &e
 }
+func (x Reply_Entry_Game) Enum() *Reply_Entry_Game {
+	p := new(Reply_Entry_Game)
+	*p = x
+	return p
+}
 func (x Reply_Entry_Game) String() string {
 	return proto.EnumName(Reply_Entry_Game_name, int32(x))
 }
diff --git a/protoc-gen-go/testdata/my_test/test.pb.go.golden b/protoc-gen-go/testdata/my_test/test.pb.go.golden
index 9019a6a..a658f02 100644
--- a/protoc-gen-go/testdata/my_test/test.pb.go.golden
+++ b/protoc-gen-go/testdata/my_test/test.pb.go.golden
@@ -28,10 +28,16 @@
 	"FEZ":    2,
 }
 
+// NewHatType is deprecated. Use x.Enum() instead.
 func NewHatType(x HatType) *HatType {
 	e := HatType(x)
 	return &e
 }
+func (x HatType) Enum() *HatType {
+	p := new(HatType)
+	*p = x
+	return p
+}
 func (x HatType) String() string {
 	return proto.EnumName(HatType_name, int32(x))
 }
@@ -55,10 +61,16 @@
 	"LUNDI":   1,
 }
 
+// NewDays is deprecated. Use x.Enum() instead.
 func NewDays(x Days) *Days {
 	e := Days(x)
 	return &e
 }
+func (x Days) Enum() *Days {
+	p := new(Days)
+	*p = x
+	return p
+}
 func (x Days) String() string {
 	return proto.EnumName(Days_name, int32(x))
 }
@@ -82,10 +94,16 @@
 	"BLUE":  2,
 }
 
+// NewRequest_Color is deprecated. Use x.Enum() instead.
 func NewRequest_Color(x Request_Color) *Request_Color {
 	e := Request_Color(x)
 	return &e
 }
+func (x Request_Color) Enum() *Request_Color {
+	p := new(Request_Color)
+	*p = x
+	return p
+}
 func (x Request_Color) String() string {
 	return proto.EnumName(Request_Color_name, int32(x))
 }
@@ -106,10 +124,16 @@
 	"TENNIS":   2,
 }
 
+// NewReply_Entry_Game is deprecated. Use x.Enum() instead.
 func NewReply_Entry_Game(x Reply_Entry_Game) *Reply_Entry_Game {
 	e := Reply_Entry_Game(x)
 	return &e
 }
+func (x Reply_Entry_Game) Enum() *Reply_Entry_Game {
+	p := new(Reply_Entry_Game)
+	*p = x
+	return p
+}
 func (x Reply_Entry_Game) String() string {
 	return proto.EnumName(Reply_Entry_Game_name, int32(x))
 }