goprotobuf: Present comments in .proto files in the generated .pb.go.

This doesn't use every comment, but just the ones that I thought
would be most useful to someone reading the generated code, namely
those attached to these things:
        - messages
        - message fields
        - enums
        - enum values

R=r
CC=golang-dev
https://codereview.appspot.com/11889044
diff --git a/proto/testdata/test.pb.go b/proto/testdata/test.pb.go
index 5aa3a22..d5e2d5e 100644
--- a/proto/testdata/test.pb.go
+++ b/proto/testdata/test.pb.go
@@ -46,10 +46,12 @@
 	return nil
 }
 
+// An enum, for completeness.
 type GoTest_KIND int32
 
 const (
-	GoTest_VOID        GoTest_KIND = 0
+	GoTest_VOID GoTest_KIND = 0
+	// Basic types
 	GoTest_BOOL        GoTest_KIND = 1
 	GoTest_BYTES       GoTest_KIND = 2
 	GoTest_FINGERPRINT GoTest_KIND = 3
@@ -57,11 +59,14 @@
 	GoTest_INT         GoTest_KIND = 5
 	GoTest_STRING      GoTest_KIND = 6
 	GoTest_TIME        GoTest_KIND = 7
-	GoTest_TUPLE       GoTest_KIND = 8
-	GoTest_ARRAY       GoTest_KIND = 9
-	GoTest_MAP         GoTest_KIND = 10
-	GoTest_TABLE       GoTest_KIND = 11
-	GoTest_FUNCTION    GoTest_KIND = 12
+	// Groupings
+	GoTest_TUPLE GoTest_KIND = 8
+	GoTest_ARRAY GoTest_KIND = 9
+	GoTest_MAP   GoTest_KIND = 10
+	// Table types
+	GoTest_TABLE GoTest_KIND = 11
+	// Functions
+	GoTest_FUNCTION GoTest_KIND = 12
 )
 
 var GoTest_KIND_name = map[int32]string{
@@ -267,64 +272,71 @@
 }
 
 type GoTest struct {
-	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"`
-	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"`
-	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"`
-	F_Int64Required         *int64                  `protobuf:"varint,12,req,name=F_Int64_required" json:"F_Int64_required,omitempty"`
-	F_Fixed32Required       *uint32                 `protobuf:"fixed32,13,req,name=F_Fixed32_required" json:"F_Fixed32_required,omitempty"`
-	F_Fixed64Required       *uint64                 `protobuf:"fixed64,14,req,name=F_Fixed64_required" json:"F_Fixed64_required,omitempty"`
-	F_Uint32Required        *uint32                 `protobuf:"varint,15,req,name=F_Uint32_required" json:"F_Uint32_required,omitempty"`
-	F_Uint64Required        *uint64                 `protobuf:"varint,16,req,name=F_Uint64_required" json:"F_Uint64_required,omitempty"`
-	F_FloatRequired         *float32                `protobuf:"fixed32,17,req,name=F_Float_required" json:"F_Float_required,omitempty"`
-	F_DoubleRequired        *float64                `protobuf:"fixed64,18,req,name=F_Double_required" json:"F_Double_required,omitempty"`
-	F_StringRequired        *string                 `protobuf:"bytes,19,req,name=F_String_required" json:"F_String_required,omitempty"`
-	F_BytesRequired         []byte                  `protobuf:"bytes,101,req,name=F_Bytes_required" json:"F_Bytes_required,omitempty"`
-	F_Sint32Required        *int32                  `protobuf:"zigzag32,102,req,name=F_Sint32_required" json:"F_Sint32_required,omitempty"`
-	F_Sint64Required        *int64                  `protobuf:"zigzag64,103,req,name=F_Sint64_required" json:"F_Sint64_required,omitempty"`
-	F_BoolRepeated          []bool                  `protobuf:"varint,20,rep,name=F_Bool_repeated" json:"F_Bool_repeated,omitempty"`
-	F_Int32Repeated         []int32                 `protobuf:"varint,21,rep,name=F_Int32_repeated" json:"F_Int32_repeated,omitempty"`
-	F_Int64Repeated         []int64                 `protobuf:"varint,22,rep,name=F_Int64_repeated" json:"F_Int64_repeated,omitempty"`
-	F_Fixed32Repeated       []uint32                `protobuf:"fixed32,23,rep,name=F_Fixed32_repeated" json:"F_Fixed32_repeated,omitempty"`
-	F_Fixed64Repeated       []uint64                `protobuf:"fixed64,24,rep,name=F_Fixed64_repeated" json:"F_Fixed64_repeated,omitempty"`
-	F_Uint32Repeated        []uint32                `protobuf:"varint,25,rep,name=F_Uint32_repeated" json:"F_Uint32_repeated,omitempty"`
-	F_Uint64Repeated        []uint64                `protobuf:"varint,26,rep,name=F_Uint64_repeated" json:"F_Uint64_repeated,omitempty"`
-	F_FloatRepeated         []float32               `protobuf:"fixed32,27,rep,name=F_Float_repeated" json:"F_Float_repeated,omitempty"`
-	F_DoubleRepeated        []float64               `protobuf:"fixed64,28,rep,name=F_Double_repeated" json:"F_Double_repeated,omitempty"`
-	F_StringRepeated        []string                `protobuf:"bytes,29,rep,name=F_String_repeated" json:"F_String_repeated,omitempty"`
-	F_BytesRepeated         [][]byte                `protobuf:"bytes,201,rep,name=F_Bytes_repeated" json:"F_Bytes_repeated,omitempty"`
-	F_Sint32Repeated        []int32                 `protobuf:"zigzag32,202,rep,name=F_Sint32_repeated" json:"F_Sint32_repeated,omitempty"`
-	F_Sint64Repeated        []int64                 `protobuf:"zigzag64,203,rep,name=F_Sint64_repeated" json:"F_Sint64_repeated,omitempty"`
-	F_BoolOptional          *bool                   `protobuf:"varint,30,opt,name=F_Bool_optional" json:"F_Bool_optional,omitempty"`
-	F_Int32Optional         *int32                  `protobuf:"varint,31,opt,name=F_Int32_optional" json:"F_Int32_optional,omitempty"`
-	F_Int64Optional         *int64                  `protobuf:"varint,32,opt,name=F_Int64_optional" json:"F_Int64_optional,omitempty"`
-	F_Fixed32Optional       *uint32                 `protobuf:"fixed32,33,opt,name=F_Fixed32_optional" json:"F_Fixed32_optional,omitempty"`
-	F_Fixed64Optional       *uint64                 `protobuf:"fixed64,34,opt,name=F_Fixed64_optional" json:"F_Fixed64_optional,omitempty"`
-	F_Uint32Optional        *uint32                 `protobuf:"varint,35,opt,name=F_Uint32_optional" json:"F_Uint32_optional,omitempty"`
-	F_Uint64Optional        *uint64                 `protobuf:"varint,36,opt,name=F_Uint64_optional" json:"F_Uint64_optional,omitempty"`
-	F_FloatOptional         *float32                `protobuf:"fixed32,37,opt,name=F_Float_optional" json:"F_Float_optional,omitempty"`
-	F_DoubleOptional        *float64                `protobuf:"fixed64,38,opt,name=F_Double_optional" json:"F_Double_optional,omitempty"`
-	F_StringOptional        *string                 `protobuf:"bytes,39,opt,name=F_String_optional" json:"F_String_optional,omitempty"`
-	F_BytesOptional         []byte                  `protobuf:"bytes,301,opt,name=F_Bytes_optional" json:"F_Bytes_optional,omitempty"`
-	F_Sint32Optional        *int32                  `protobuf:"zigzag32,302,opt,name=F_Sint32_optional" json:"F_Sint32_optional,omitempty"`
-	F_Sint64Optional        *int64                  `protobuf:"zigzag64,303,opt,name=F_Sint64_optional" json:"F_Sint64_optional,omitempty"`
-	F_BoolDefaulted         *bool                   `protobuf:"varint,40,opt,name=F_Bool_defaulted,def=1" json:"F_Bool_defaulted,omitempty"`
-	F_Int32Defaulted        *int32                  `protobuf:"varint,41,opt,name=F_Int32_defaulted,def=32" json:"F_Int32_defaulted,omitempty"`
-	F_Int64Defaulted        *int64                  `protobuf:"varint,42,opt,name=F_Int64_defaulted,def=64" json:"F_Int64_defaulted,omitempty"`
-	F_Fixed32Defaulted      *uint32                 `protobuf:"fixed32,43,opt,name=F_Fixed32_defaulted,def=320" json:"F_Fixed32_defaulted,omitempty"`
-	F_Fixed64Defaulted      *uint64                 `protobuf:"fixed64,44,opt,name=F_Fixed64_defaulted,def=640" json:"F_Fixed64_defaulted,omitempty"`
-	F_Uint32Defaulted       *uint32                 `protobuf:"varint,45,opt,name=F_Uint32_defaulted,def=3200" json:"F_Uint32_defaulted,omitempty"`
-	F_Uint64Defaulted       *uint64                 `protobuf:"varint,46,opt,name=F_Uint64_defaulted,def=6400" json:"F_Uint64_defaulted,omitempty"`
-	F_FloatDefaulted        *float32                `protobuf:"fixed32,47,opt,name=F_Float_defaulted,def=314159" json:"F_Float_defaulted,omitempty"`
-	F_DoubleDefaulted       *float64                `protobuf:"fixed64,48,opt,name=F_Double_defaulted,def=271828" json:"F_Double_defaulted,omitempty"`
-	F_StringDefaulted       *string                 `protobuf:"bytes,49,opt,name=F_String_defaulted,def=hello, \"world!\"\n" json:"F_String_defaulted,omitempty"`
-	F_BytesDefaulted        []byte                  `protobuf:"bytes,401,opt,name=F_Bytes_defaulted,def=Bignose" json:"F_Bytes_defaulted,omitempty"`
-	F_Sint32Defaulted       *int32                  `protobuf:"zigzag32,402,opt,name=F_Sint32_defaulted,def=-32" json:"F_Sint32_defaulted,omitempty"`
-	F_Sint64Defaulted       *int64                  `protobuf:"zigzag64,403,opt,name=F_Sint64_defaulted,def=-64" json:"F_Sint64_defaulted,omitempty"`
+	// 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"`
+	// 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"`
+	// 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"`
+	F_Int64Required   *int64   `protobuf:"varint,12,req,name=F_Int64_required" json:"F_Int64_required,omitempty"`
+	F_Fixed32Required *uint32  `protobuf:"fixed32,13,req,name=F_Fixed32_required" json:"F_Fixed32_required,omitempty"`
+	F_Fixed64Required *uint64  `protobuf:"fixed64,14,req,name=F_Fixed64_required" json:"F_Fixed64_required,omitempty"`
+	F_Uint32Required  *uint32  `protobuf:"varint,15,req,name=F_Uint32_required" json:"F_Uint32_required,omitempty"`
+	F_Uint64Required  *uint64  `protobuf:"varint,16,req,name=F_Uint64_required" json:"F_Uint64_required,omitempty"`
+	F_FloatRequired   *float32 `protobuf:"fixed32,17,req,name=F_Float_required" json:"F_Float_required,omitempty"`
+	F_DoubleRequired  *float64 `protobuf:"fixed64,18,req,name=F_Double_required" json:"F_Double_required,omitempty"`
+	F_StringRequired  *string  `protobuf:"bytes,19,req,name=F_String_required" json:"F_String_required,omitempty"`
+	F_BytesRequired   []byte   `protobuf:"bytes,101,req,name=F_Bytes_required" json:"F_Bytes_required,omitempty"`
+	F_Sint32Required  *int32   `protobuf:"zigzag32,102,req,name=F_Sint32_required" json:"F_Sint32_required,omitempty"`
+	F_Sint64Required  *int64   `protobuf:"zigzag64,103,req,name=F_Sint64_required" json:"F_Sint64_required,omitempty"`
+	// Repeated fields of all basic types
+	F_BoolRepeated    []bool    `protobuf:"varint,20,rep,name=F_Bool_repeated" json:"F_Bool_repeated,omitempty"`
+	F_Int32Repeated   []int32   `protobuf:"varint,21,rep,name=F_Int32_repeated" json:"F_Int32_repeated,omitempty"`
+	F_Int64Repeated   []int64   `protobuf:"varint,22,rep,name=F_Int64_repeated" json:"F_Int64_repeated,omitempty"`
+	F_Fixed32Repeated []uint32  `protobuf:"fixed32,23,rep,name=F_Fixed32_repeated" json:"F_Fixed32_repeated,omitempty"`
+	F_Fixed64Repeated []uint64  `protobuf:"fixed64,24,rep,name=F_Fixed64_repeated" json:"F_Fixed64_repeated,omitempty"`
+	F_Uint32Repeated  []uint32  `protobuf:"varint,25,rep,name=F_Uint32_repeated" json:"F_Uint32_repeated,omitempty"`
+	F_Uint64Repeated  []uint64  `protobuf:"varint,26,rep,name=F_Uint64_repeated" json:"F_Uint64_repeated,omitempty"`
+	F_FloatRepeated   []float32 `protobuf:"fixed32,27,rep,name=F_Float_repeated" json:"F_Float_repeated,omitempty"`
+	F_DoubleRepeated  []float64 `protobuf:"fixed64,28,rep,name=F_Double_repeated" json:"F_Double_repeated,omitempty"`
+	F_StringRepeated  []string  `protobuf:"bytes,29,rep,name=F_String_repeated" json:"F_String_repeated,omitempty"`
+	F_BytesRepeated   [][]byte  `protobuf:"bytes,201,rep,name=F_Bytes_repeated" json:"F_Bytes_repeated,omitempty"`
+	F_Sint32Repeated  []int32   `protobuf:"zigzag32,202,rep,name=F_Sint32_repeated" json:"F_Sint32_repeated,omitempty"`
+	F_Sint64Repeated  []int64   `protobuf:"zigzag64,203,rep,name=F_Sint64_repeated" json:"F_Sint64_repeated,omitempty"`
+	// Optional fields of all basic types
+	F_BoolOptional    *bool    `protobuf:"varint,30,opt,name=F_Bool_optional" json:"F_Bool_optional,omitempty"`
+	F_Int32Optional   *int32   `protobuf:"varint,31,opt,name=F_Int32_optional" json:"F_Int32_optional,omitempty"`
+	F_Int64Optional   *int64   `protobuf:"varint,32,opt,name=F_Int64_optional" json:"F_Int64_optional,omitempty"`
+	F_Fixed32Optional *uint32  `protobuf:"fixed32,33,opt,name=F_Fixed32_optional" json:"F_Fixed32_optional,omitempty"`
+	F_Fixed64Optional *uint64  `protobuf:"fixed64,34,opt,name=F_Fixed64_optional" json:"F_Fixed64_optional,omitempty"`
+	F_Uint32Optional  *uint32  `protobuf:"varint,35,opt,name=F_Uint32_optional" json:"F_Uint32_optional,omitempty"`
+	F_Uint64Optional  *uint64  `protobuf:"varint,36,opt,name=F_Uint64_optional" json:"F_Uint64_optional,omitempty"`
+	F_FloatOptional   *float32 `protobuf:"fixed32,37,opt,name=F_Float_optional" json:"F_Float_optional,omitempty"`
+	F_DoubleOptional  *float64 `protobuf:"fixed64,38,opt,name=F_Double_optional" json:"F_Double_optional,omitempty"`
+	F_StringOptional  *string  `protobuf:"bytes,39,opt,name=F_String_optional" json:"F_String_optional,omitempty"`
+	F_BytesOptional   []byte   `protobuf:"bytes,301,opt,name=F_Bytes_optional" json:"F_Bytes_optional,omitempty"`
+	F_Sint32Optional  *int32   `protobuf:"zigzag32,302,opt,name=F_Sint32_optional" json:"F_Sint32_optional,omitempty"`
+	F_Sint64Optional  *int64   `protobuf:"zigzag64,303,opt,name=F_Sint64_optional" json:"F_Sint64_optional,omitempty"`
+	// Default-valued fields of all basic types
+	F_BoolDefaulted    *bool    `protobuf:"varint,40,opt,name=F_Bool_defaulted,def=1" json:"F_Bool_defaulted,omitempty"`
+	F_Int32Defaulted   *int32   `protobuf:"varint,41,opt,name=F_Int32_defaulted,def=32" json:"F_Int32_defaulted,omitempty"`
+	F_Int64Defaulted   *int64   `protobuf:"varint,42,opt,name=F_Int64_defaulted,def=64" json:"F_Int64_defaulted,omitempty"`
+	F_Fixed32Defaulted *uint32  `protobuf:"fixed32,43,opt,name=F_Fixed32_defaulted,def=320" json:"F_Fixed32_defaulted,omitempty"`
+	F_Fixed64Defaulted *uint64  `protobuf:"fixed64,44,opt,name=F_Fixed64_defaulted,def=640" json:"F_Fixed64_defaulted,omitempty"`
+	F_Uint32Defaulted  *uint32  `protobuf:"varint,45,opt,name=F_Uint32_defaulted,def=3200" json:"F_Uint32_defaulted,omitempty"`
+	F_Uint64Defaulted  *uint64  `protobuf:"varint,46,opt,name=F_Uint64_defaulted,def=6400" json:"F_Uint64_defaulted,omitempty"`
+	F_FloatDefaulted   *float32 `protobuf:"fixed32,47,opt,name=F_Float_defaulted,def=314159" json:"F_Float_defaulted,omitempty"`
+	F_DoubleDefaulted  *float64 `protobuf:"fixed64,48,opt,name=F_Double_defaulted,def=271828" json:"F_Double_defaulted,omitempty"`
+	F_StringDefaulted  *string  `protobuf:"bytes,49,opt,name=F_String_defaulted,def=hello, \"world!\"\n" json:"F_String_defaulted,omitempty"`
+	F_BytesDefaulted   []byte   `protobuf:"bytes,401,opt,name=F_Bytes_defaulted,def=Bignose" json:"F_Bytes_defaulted,omitempty"`
+	F_Sint32Defaulted  *int32   `protobuf:"zigzag32,402,opt,name=F_Sint32_defaulted,def=-32" json:"F_Sint32_defaulted,omitempty"`
+	F_Sint64Defaulted  *int64   `protobuf:"zigzag64,403,opt,name=F_Sint64_defaulted,def=-64" json:"F_Sint64_defaulted,omitempty"`
+	// Packed repeated fields (no string or bytes).
 	F_BoolRepeatedPacked    []bool                  `protobuf:"varint,50,rep,packed,name=F_Bool_repeated_packed" json:"F_Bool_repeated_packed,omitempty"`
 	F_Int32RepeatedPacked   []int32                 `protobuf:"varint,51,rep,packed,name=F_Int32_repeated_packed" json:"F_Int32_repeated_packed,omitempty"`
 	F_Int64RepeatedPacked   []int64                 `protobuf:"varint,52,rep,packed,name=F_Int64_repeated_packed" json:"F_Int64_repeated_packed,omitempty"`
@@ -866,6 +878,7 @@
 	return nil
 }
 
+// Required, repeated, and optional groups.
 type GoTest_RequiredGroup struct {
 	RequiredField    *string `protobuf:"bytes,71,req" json:"RequiredField,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
@@ -914,6 +927,9 @@
 	return ""
 }
 
+// For testing skipping of unrecognized fields.
+// Numbers are all big, larger than tag numbers in GoTestField,
+// the message used in the corresponding test.
 type GoSkipTest struct {
 	SkipInt32        *int32                `protobuf:"varint,11,req,name=skip_int32" json:"skip_int32,omitempty"`
 	SkipFixed32      *uint32               `protobuf:"fixed32,12,req,name=skip_fixed32" json:"skip_fixed32,omitempty"`
@@ -986,6 +1002,8 @@
 	return ""
 }
 
+// For testing packed/non-packed decoder switching.
+// A serialized instance of one should be deserializable as the other.
 type NonPackedTest struct {
 	A                []int32 `protobuf:"varint,1,rep,name=a" json:"a,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
@@ -1019,6 +1037,7 @@
 }
 
 type MaxTag struct {
+	// Maximum possible tag number.
 	LastField        *string `protobuf:"bytes,536870911,opt,name=last_field" json:"last_field,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
 }
@@ -1066,6 +1085,8 @@
 	return ""
 }
 
+// NewMessage is wire compatible with OldMessage;
+// imagine it as a future version.
 type NewMessage struct {
 	Nested           *NewMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"`
 	XXX_unrecognized []byte             `json:"-"`
@@ -1181,15 +1202,16 @@
 }
 
 type MyMessage struct {
-	Count            *int32                    `protobuf:"varint,1,req,name=count" json:"count,omitempty"`
-	Name             *string                   `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
-	Quote            *string                   `protobuf:"bytes,3,opt,name=quote" json:"quote,omitempty"`
-	Pet              []string                  `protobuf:"bytes,4,rep,name=pet" json:"pet,omitempty"`
-	Inner            *InnerMessage             `protobuf:"bytes,5,opt,name=inner" json:"inner,omitempty"`
-	Others           []*OtherMessage           `protobuf:"bytes,6,rep,name=others" json:"others,omitempty"`
-	RepInner         []*InnerMessage           `protobuf:"bytes,12,rep,name=rep_inner" json:"rep_inner,omitempty"`
-	Bikeshed         *MyMessage_Color          `protobuf:"varint,7,opt,name=bikeshed,enum=testdata.MyMessage_Color" json:"bikeshed,omitempty"`
-	Somegroup        *MyMessage_SomeGroup      `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"`
+	Count     *int32               `protobuf:"varint,1,req,name=count" json:"count,omitempty"`
+	Name      *string              `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
+	Quote     *string              `protobuf:"bytes,3,opt,name=quote" json:"quote,omitempty"`
+	Pet       []string             `protobuf:"bytes,4,rep,name=pet" json:"pet,omitempty"`
+	Inner     *InnerMessage        `protobuf:"bytes,5,opt,name=inner" json:"inner,omitempty"`
+	Others    []*OtherMessage      `protobuf:"bytes,6,rep,name=others" json:"others,omitempty"`
+	RepInner  []*InnerMessage      `protobuf:"bytes,12,rep,name=rep_inner" json:"rep_inner,omitempty"`
+	Bikeshed  *MyMessage_Color     `protobuf:"varint,7,opt,name=bikeshed,enum=testdata.MyMessage_Color" json:"bikeshed,omitempty"`
+	Somegroup *MyMessage_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"`
+	// This field becomes [][]byte in the generated code.
 	RepBytes         [][]byte                  `protobuf:"bytes,10,rep,name=rep_bytes" json:"rep_bytes,omitempty"`
 	Bigfloat         *float64                  `protobuf:"fixed64,11,opt,name=bigfloat" json:"bigfloat,omitempty"`
 	XXX_extensions   map[int32]proto.Extension `json:"-"`
@@ -1368,7 +1390,7 @@
 var _ proto.Unmarshaler = (*MyMessageSet)(nil)
 
 var extRange_MyMessageSet = []proto.ExtensionRange{
-	{100, 536870911},
+	{100, 2147483646},
 }
 
 func (*MyMessageSet) ExtensionRangeArray() []proto.ExtensionRange {
@@ -1454,25 +1476,29 @@
 }
 
 type Defaults struct {
-	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_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"`
-	Sub              *SubDefaults    `protobuf:"bytes,18,opt,name=sub" json:"sub,omitempty"`
-	XXX_unrecognized []byte          `json:"-"`
+	// 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"`
+	// 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"`
+	// Sub-message.
+	Sub              *SubDefaults `protobuf:"bytes,18,opt,name=sub" json:"sub,omitempty"`
+	XXX_unrecognized []byte       `json:"-"`
 }
 
 func (m *Defaults) Reset()         { *m = Defaults{} }
diff --git a/protoc-gen-go/descriptor/descriptor.pb.go b/protoc-gen-go/descriptor/descriptor.pb.go
index 1ea113b..3acbe29 100644
--- a/protoc-gen-go/descriptor/descriptor.pb.go
+++ b/protoc-gen-go/descriptor/descriptor.pb.go
@@ -16,17 +16,24 @@
 type FieldDescriptorProto_Type int32
 
 const (
-	FieldDescriptorProto_TYPE_DOUBLE   FieldDescriptorProto_Type = 1
-	FieldDescriptorProto_TYPE_FLOAT    FieldDescriptorProto_Type = 2
-	FieldDescriptorProto_TYPE_INT64    FieldDescriptorProto_Type = 3
-	FieldDescriptorProto_TYPE_UINT64   FieldDescriptorProto_Type = 4
-	FieldDescriptorProto_TYPE_INT32    FieldDescriptorProto_Type = 5
-	FieldDescriptorProto_TYPE_FIXED64  FieldDescriptorProto_Type = 6
-	FieldDescriptorProto_TYPE_FIXED32  FieldDescriptorProto_Type = 7
-	FieldDescriptorProto_TYPE_BOOL     FieldDescriptorProto_Type = 8
-	FieldDescriptorProto_TYPE_STRING   FieldDescriptorProto_Type = 9
-	FieldDescriptorProto_TYPE_GROUP    FieldDescriptorProto_Type = 10
-	FieldDescriptorProto_TYPE_MESSAGE  FieldDescriptorProto_Type = 11
+	// 0 is reserved for errors.
+	// Order is weird for historical reasons.
+	FieldDescriptorProto_TYPE_DOUBLE FieldDescriptorProto_Type = 1
+	FieldDescriptorProto_TYPE_FLOAT  FieldDescriptorProto_Type = 2
+	// Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
+	// negative values are likely.
+	FieldDescriptorProto_TYPE_INT64  FieldDescriptorProto_Type = 3
+	FieldDescriptorProto_TYPE_UINT64 FieldDescriptorProto_Type = 4
+	// Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
+	// negative values are likely.
+	FieldDescriptorProto_TYPE_INT32   FieldDescriptorProto_Type = 5
+	FieldDescriptorProto_TYPE_FIXED64 FieldDescriptorProto_Type = 6
+	FieldDescriptorProto_TYPE_FIXED32 FieldDescriptorProto_Type = 7
+	FieldDescriptorProto_TYPE_BOOL    FieldDescriptorProto_Type = 8
+	FieldDescriptorProto_TYPE_STRING  FieldDescriptorProto_Type = 9
+	FieldDescriptorProto_TYPE_GROUP   FieldDescriptorProto_Type = 10
+	FieldDescriptorProto_TYPE_MESSAGE FieldDescriptorProto_Type = 11
+	// New in version 2.
 	FieldDescriptorProto_TYPE_BYTES    FieldDescriptorProto_Type = 12
 	FieldDescriptorProto_TYPE_UINT32   FieldDescriptorProto_Type = 13
 	FieldDescriptorProto_TYPE_ENUM     FieldDescriptorProto_Type = 14
@@ -100,6 +107,7 @@
 type FieldDescriptorProto_Label int32
 
 const (
+	// 0 is reserved for errors
 	FieldDescriptorProto_LABEL_OPTIONAL FieldDescriptorProto_Label = 1
 	FieldDescriptorProto_LABEL_REQUIRED FieldDescriptorProto_Label = 2
 	FieldDescriptorProto_LABEL_REPEATED FieldDescriptorProto_Label = 3
@@ -136,10 +144,12 @@
 	return nil
 }
 
+// Generated classes can be optimized for speed or code size.
 type FileOptions_OptimizeMode int32
 
 const (
-	FileOptions_SPEED        FileOptions_OptimizeMode = 1
+	FileOptions_SPEED FileOptions_OptimizeMode = 1
+	// etc.
 	FileOptions_CODE_SIZE    FileOptions_OptimizeMode = 2
 	FileOptions_LITE_RUNTIME FileOptions_OptimizeMode = 3
 )
@@ -178,6 +188,7 @@
 type FieldOptions_CType int32
 
 const (
+	// Default mode.
 	FieldOptions_STRING       FieldOptions_CType = 0
 	FieldOptions_CORD         FieldOptions_CType = 1
 	FieldOptions_STRING_PIECE FieldOptions_CType = 2
@@ -214,6 +225,8 @@
 	return nil
 }
 
+// The protocol compiler can output a FileDescriptorSet containing the .proto
+// files it parses.
 type FileDescriptorSet struct {
 	File             []*FileDescriptorProto `protobuf:"bytes,1,rep,name=file" json:"file,omitempty"`
 	XXX_unrecognized []byte                 `json:"-"`
@@ -230,19 +243,29 @@
 	return nil
 }
 
+// Describes a complete .proto file.
 type FileDescriptorProto struct {
-	Name             *string                   `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
-	Package          *string                   `protobuf:"bytes,2,opt,name=package" json:"package,omitempty"`
-	Dependency       []string                  `protobuf:"bytes,3,rep,name=dependency" json:"dependency,omitempty"`
-	PublicDependency []int32                   `protobuf:"varint,10,rep,name=public_dependency" json:"public_dependency,omitempty"`
-	WeakDependency   []int32                   `protobuf:"varint,11,rep,name=weak_dependency" json:"weak_dependency,omitempty"`
-	MessageType      []*DescriptorProto        `protobuf:"bytes,4,rep,name=message_type" json:"message_type,omitempty"`
-	EnumType         []*EnumDescriptorProto    `protobuf:"bytes,5,rep,name=enum_type" json:"enum_type,omitempty"`
-	Service          []*ServiceDescriptorProto `protobuf:"bytes,6,rep,name=service" json:"service,omitempty"`
-	Extension        []*FieldDescriptorProto   `protobuf:"bytes,7,rep,name=extension" json:"extension,omitempty"`
-	Options          *FileOptions              `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"`
-	SourceCodeInfo   *SourceCodeInfo           `protobuf:"bytes,9,opt,name=source_code_info" json:"source_code_info,omitempty"`
-	XXX_unrecognized []byte                    `json:"-"`
+	Name    *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	Package *string `protobuf:"bytes,2,opt,name=package" json:"package,omitempty"`
+	// Names of files imported by this file.
+	Dependency []string `protobuf:"bytes,3,rep,name=dependency" json:"dependency,omitempty"`
+	// Indexes of the public imported files in the dependency list above.
+	PublicDependency []int32 `protobuf:"varint,10,rep,name=public_dependency" json:"public_dependency,omitempty"`
+	// Indexes of the weak imported files in the dependency list.
+	// For Google-internal migration only. Do not use.
+	WeakDependency []int32 `protobuf:"varint,11,rep,name=weak_dependency" json:"weak_dependency,omitempty"`
+	// All top-level definitions in this file.
+	MessageType []*DescriptorProto        `protobuf:"bytes,4,rep,name=message_type" json:"message_type,omitempty"`
+	EnumType    []*EnumDescriptorProto    `protobuf:"bytes,5,rep,name=enum_type" json:"enum_type,omitempty"`
+	Service     []*ServiceDescriptorProto `protobuf:"bytes,6,rep,name=service" json:"service,omitempty"`
+	Extension   []*FieldDescriptorProto   `protobuf:"bytes,7,rep,name=extension" json:"extension,omitempty"`
+	Options     *FileOptions              `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"`
+	// This field contains optional information about the original source code.
+	// You may safely remove this entire field whithout harming runtime
+	// functionality of the descriptors -- the information is needed only by
+	// development tools.
+	SourceCodeInfo   *SourceCodeInfo `protobuf:"bytes,9,opt,name=source_code_info" json:"source_code_info,omitempty"`
+	XXX_unrecognized []byte          `json:"-"`
 }
 
 func (m *FileDescriptorProto) Reset()         { *m = FileDescriptorProto{} }
@@ -326,6 +349,7 @@
 	return nil
 }
 
+// Describes a message type.
 type DescriptorProto struct {
 	Name             *string                           `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
 	Field            []*FieldDescriptorProto           `protobuf:"bytes,2,rep,name=field" json:"field,omitempty"`
@@ -414,16 +438,31 @@
 	return 0
 }
 
+// Describes a field within a message.
 type FieldDescriptorProto struct {
-	Name             *string                     `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
-	Number           *int32                      `protobuf:"varint,3,opt,name=number" json:"number,omitempty"`
-	Label            *FieldDescriptorProto_Label `protobuf:"varint,4,opt,name=label,enum=google.protobuf.FieldDescriptorProto_Label" json:"label,omitempty"`
-	Type             *FieldDescriptorProto_Type  `protobuf:"varint,5,opt,name=type,enum=google.protobuf.FieldDescriptorProto_Type" json:"type,omitempty"`
-	TypeName         *string                     `protobuf:"bytes,6,opt,name=type_name" json:"type_name,omitempty"`
-	Extendee         *string                     `protobuf:"bytes,2,opt,name=extendee" json:"extendee,omitempty"`
-	DefaultValue     *string                     `protobuf:"bytes,7,opt,name=default_value" json:"default_value,omitempty"`
-	Options          *FieldOptions               `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"`
-	XXX_unrecognized []byte                      `json:"-"`
+	Name   *string                     `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	Number *int32                      `protobuf:"varint,3,opt,name=number" json:"number,omitempty"`
+	Label  *FieldDescriptorProto_Label `protobuf:"varint,4,opt,name=label,enum=google.protobuf.FieldDescriptorProto_Label" json:"label,omitempty"`
+	// If type_name is set, this need not be set.  If both this and type_name
+	// are set, this must be either TYPE_ENUM or TYPE_MESSAGE.
+	Type *FieldDescriptorProto_Type `protobuf:"varint,5,opt,name=type,enum=google.protobuf.FieldDescriptorProto_Type" json:"type,omitempty"`
+	// For message and enum types, this is the name of the type.  If the name
+	// starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
+	// rules are used to find the type (i.e. first the nested types within this
+	// message are searched, then within the parent, on up to the root
+	// namespace).
+	TypeName *string `protobuf:"bytes,6,opt,name=type_name" json:"type_name,omitempty"`
+	// For extensions, this is the name of the type being extended.  It is
+	// resolved in the same manner as type_name.
+	Extendee *string `protobuf:"bytes,2,opt,name=extendee" json:"extendee,omitempty"`
+	// For numeric types, contains the original text representation of the value.
+	// For booleans, "true" or "false".
+	// For strings, contains the default text contents (not escaped in any way).
+	// For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
+	// TODO(kenton):  Base-64 encode?
+	DefaultValue     *string       `protobuf:"bytes,7,opt,name=default_value" json:"default_value,omitempty"`
+	Options          *FieldOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"`
+	XXX_unrecognized []byte        `json:"-"`
 }
 
 func (m *FieldDescriptorProto) Reset()         { *m = FieldDescriptorProto{} }
@@ -486,6 +525,7 @@
 	return nil
 }
 
+// Describes an enum type.
 type EnumDescriptorProto struct {
 	Name             *string                     `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
 	Value            []*EnumValueDescriptorProto `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"`
@@ -518,6 +558,7 @@
 	return nil
 }
 
+// Describes a value within an enum.
 type EnumValueDescriptorProto struct {
 	Name             *string           `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
 	Number           *int32            `protobuf:"varint,2,opt,name=number" json:"number,omitempty"`
@@ -550,6 +591,7 @@
 	return nil
 }
 
+// Describes a service.
 type ServiceDescriptorProto struct {
 	Name             *string                  `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
 	Method           []*MethodDescriptorProto `protobuf:"bytes,2,rep,name=method" json:"method,omitempty"`
@@ -582,8 +624,11 @@
 	return nil
 }
 
+// Describes a method of a service.
 type MethodDescriptorProto struct {
-	Name             *string        `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	// Input and output type names.  These are resolved in the same way as
+	// FieldDescriptorProto.type_name, but must refer to a message type.
 	InputType        *string        `protobuf:"bytes,2,opt,name=input_type" json:"input_type,omitempty"`
 	OutputType       *string        `protobuf:"bytes,3,opt,name=output_type" json:"output_type,omitempty"`
 	Options          *MethodOptions `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"`
@@ -623,18 +668,50 @@
 }
 
 type FileOptions struct {
-	JavaPackage               *string                   `protobuf:"bytes,1,opt,name=java_package" json:"java_package,omitempty"`
-	JavaOuterClassname        *string                   `protobuf:"bytes,8,opt,name=java_outer_classname" json:"java_outer_classname,omitempty"`
-	JavaMultipleFiles         *bool                     `protobuf:"varint,10,opt,name=java_multiple_files,def=0" json:"java_multiple_files,omitempty"`
+	// Sets the Java package where classes generated from this .proto will be
+	// placed.  By default, the proto package is used, but this is often
+	// inappropriate because proto packages do not normally start with backwards
+	// domain names.
+	JavaPackage *string `protobuf:"bytes,1,opt,name=java_package" json:"java_package,omitempty"`
+	// If set, all the classes from the .proto file are wrapped in a single
+	// outer class with the given name.  This applies to both Proto1
+	// (equivalent to the old "--one_java_file" option) and Proto2 (where
+	// a .proto always translates to a single class, but you may want to
+	// explicitly choose the class name).
+	JavaOuterClassname *string `protobuf:"bytes,8,opt,name=java_outer_classname" json:"java_outer_classname,omitempty"`
+	// If set true, then the Java code generator will generate a separate .java
+	// file for each top-level message, enum, and service defined in the .proto
+	// file.  Thus, these types will *not* be nested inside the outer class
+	// named by java_outer_classname.  However, the outer class will still be
+	// generated to contain the file's getDescriptor() method as well as any
+	// top-level extensions defined in the file.
+	JavaMultipleFiles *bool `protobuf:"varint,10,opt,name=java_multiple_files,def=0" json:"java_multiple_files,omitempty"`
+	// If set true, then the Java code generator will generate equals() and
+	// hashCode() methods for all messages defined in the .proto file. This is
+	// purely a speed optimization, as the AbstractMessage base class includes
+	// reflection-based implementations of these methods.
 	JavaGenerateEqualsAndHash *bool                     `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,def=0" json:"java_generate_equals_and_hash,omitempty"`
 	OptimizeFor               *FileOptions_OptimizeMode `protobuf:"varint,9,opt,name=optimize_for,enum=google.protobuf.FileOptions_OptimizeMode,def=1" json:"optimize_for,omitempty"`
-	GoPackage                 *string                   `protobuf:"bytes,11,opt,name=go_package" json:"go_package,omitempty"`
-	CcGenericServices         *bool                     `protobuf:"varint,16,opt,name=cc_generic_services,def=0" json:"cc_generic_services,omitempty"`
-	JavaGenericServices       *bool                     `protobuf:"varint,17,opt,name=java_generic_services,def=0" json:"java_generic_services,omitempty"`
-	PyGenericServices         *bool                     `protobuf:"varint,18,opt,name=py_generic_services,def=0" json:"py_generic_services,omitempty"`
-	UninterpretedOption       []*UninterpretedOption    `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"`
-	XXX_extensions            map[int32]proto.Extension `json:"-"`
-	XXX_unrecognized          []byte                    `json:"-"`
+	// Sets the Go package where structs generated from this .proto will be
+	// placed.  There is no default.
+	GoPackage *string `protobuf:"bytes,11,opt,name=go_package" json:"go_package,omitempty"`
+	// Should generic services be generated in each language?  "Generic" services
+	// are not specific to any particular RPC system.  They are generated by the
+	// main code generators in each language (without additional plugins).
+	// Generic services were the only kind of service generation supported by
+	// early versions of proto2.
+	//
+	// Generic services are now considered deprecated in favor of using plugins
+	// that generate code specific to your particular RPC system.  Therefore,
+	// these default to false.  Old code which depends on generic services should
+	// explicitly set them to true.
+	CcGenericServices   *bool `protobuf:"varint,16,opt,name=cc_generic_services,def=0" json:"cc_generic_services,omitempty"`
+	JavaGenericServices *bool `protobuf:"varint,17,opt,name=java_generic_services,def=0" json:"java_generic_services,omitempty"`
+	PyGenericServices   *bool `protobuf:"varint,18,opt,name=py_generic_services,def=0" json:"py_generic_services,omitempty"`
+	// The parser stores options it doesn't recognize here. See above.
+	UninterpretedOption []*UninterpretedOption    `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"`
+	XXX_extensions      map[int32]proto.Extension `json:"-"`
+	XXX_unrecognized    []byte                    `json:"-"`
 }
 
 func (m *FileOptions) Reset()         { *m = FileOptions{} }
@@ -733,11 +810,33 @@
 }
 
 type MessageOptions struct {
-	MessageSetWireFormat         *bool                     `protobuf:"varint,1,opt,name=message_set_wire_format,def=0" json:"message_set_wire_format,omitempty"`
-	NoStandardDescriptorAccessor *bool                     `protobuf:"varint,2,opt,name=no_standard_descriptor_accessor,def=0" json:"no_standard_descriptor_accessor,omitempty"`
-	UninterpretedOption          []*UninterpretedOption    `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"`
-	XXX_extensions               map[int32]proto.Extension `json:"-"`
-	XXX_unrecognized             []byte                    `json:"-"`
+	// Set true to use the old proto1 MessageSet wire format for extensions.
+	// This is provided for backwards-compatibility with the MessageSet wire
+	// format.  You should not use this for any other reason:  It's less
+	// efficient, has fewer features, and is more complicated.
+	//
+	// The message must be defined exactly as follows:
+	//   message Foo {
+	//     option message_set_wire_format = true;
+	//     extensions 4 to max;
+	//   }
+	// Note that the message cannot have any defined fields; MessageSets only
+	// have extensions.
+	//
+	// All extensions of your type must be singular messages; e.g. they cannot
+	// be int32s, enums, or repeated messages.
+	//
+	// Because this is an option, the above two restrictions are not enforced by
+	// the protocol compiler.
+	MessageSetWireFormat *bool `protobuf:"varint,1,opt,name=message_set_wire_format,def=0" json:"message_set_wire_format,omitempty"`
+	// Disables the generation of the standard "descriptor()" accessor, which can
+	// conflict with a field of the same name.  This is meant to make migration
+	// from proto1 easier; new code should avoid fields named "descriptor".
+	NoStandardDescriptorAccessor *bool `protobuf:"varint,2,opt,name=no_standard_descriptor_accessor,def=0" json:"no_standard_descriptor_accessor,omitempty"`
+	// The parser stores options it doesn't recognize here. See above.
+	UninterpretedOption []*UninterpretedOption    `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"`
+	XXX_extensions      map[int32]proto.Extension `json:"-"`
+	XXX_unrecognized    []byte                    `json:"-"`
 }
 
 func (m *MessageOptions) Reset()         { *m = MessageOptions{} }
@@ -783,12 +882,66 @@
 }
 
 type FieldOptions struct {
-	Ctype               *FieldOptions_CType       `protobuf:"varint,1,opt,name=ctype,enum=google.protobuf.FieldOptions_CType,def=0" json:"ctype,omitempty"`
-	Packed              *bool                     `protobuf:"varint,2,opt,name=packed" json:"packed,omitempty"`
-	Lazy                *bool                     `protobuf:"varint,5,opt,name=lazy,def=0" json:"lazy,omitempty"`
-	Deprecated          *bool                     `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"`
-	ExperimentalMapKey  *string                   `protobuf:"bytes,9,opt,name=experimental_map_key" json:"experimental_map_key,omitempty"`
-	Weak                *bool                     `protobuf:"varint,10,opt,name=weak,def=0" json:"weak,omitempty"`
+	// The ctype option instructs the C++ code generator to use a different
+	// representation of the field than it normally would.  See the specific
+	// options below.  This option is not yet implemented in the open source
+	// release -- sorry, we'll try to include it in a future version!
+	Ctype *FieldOptions_CType `protobuf:"varint,1,opt,name=ctype,enum=google.protobuf.FieldOptions_CType,def=0" json:"ctype,omitempty"`
+	// The packed option can be enabled for repeated primitive fields to enable
+	// a more efficient representation on the wire. Rather than repeatedly
+	// writing the tag and type for each element, the entire array is encoded as
+	// a single length-delimited blob.
+	Packed *bool `protobuf:"varint,2,opt,name=packed" json:"packed,omitempty"`
+	// Should this field be parsed lazily?  Lazy applies only to message-type
+	// fields.  It means that when the outer message is initially parsed, the
+	// inner message's contents will not be parsed but instead stored in encoded
+	// form.  The inner message will actually be parsed when it is first accessed.
+	//
+	// This is only a hint.  Implementations are free to choose whether to use
+	// eager or lazy parsing regardless of the value of this option.  However,
+	// setting this option true suggests that the protocol author believes that
+	// using lazy parsing on this field is worth the additional bookkeeping
+	// overhead typically needed to implement it.
+	//
+	// This option does not affect the public interface of any generated code;
+	// all method signatures remain the same.  Furthermore, thread-safety of the
+	// interface is not affected by this option; const methods remain safe to
+	// call from multiple threads concurrently, while non-const methods continue
+	// to require exclusive access.
+	//
+	//
+	// Note that implementations may choose not to check required fields within
+	// a lazy sub-message.  That is, calling IsInitialized() on the outher message
+	// may return true even if the inner message has missing required fields.
+	// This is necessary because otherwise the inner message would have to be
+	// parsed in order to perform the check, defeating the purpose of lazy
+	// parsing.  An implementation which chooses not to check required fields
+	// must be consistent about it.  That is, for any particular sub-message, the
+	// implementation must either *always* check its required fields, or *never*
+	// check its required fields, regardless of whether or not the message has
+	// been parsed.
+	Lazy *bool `protobuf:"varint,5,opt,name=lazy,def=0" json:"lazy,omitempty"`
+	// Is this field deprecated?
+	// Depending on the target platform, this can emit Deprecated annotations
+	// for accessors, or it will be completely ignored; in the very least, this
+	// is a formalization for deprecating fields.
+	Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"`
+	// EXPERIMENTAL.  DO NOT USE.
+	// For "map" fields, the name of the field in the enclosed type that
+	// is the key for this map.  For example, suppose we have:
+	//   message Item {
+	//     required string name = 1;
+	//     required string value = 2;
+	//   }
+	//   message Config {
+	//     repeated Item items = 1 [experimental_map_key="name"];
+	//   }
+	// In this situation, the map key for Item will be set to "name".
+	// TODO: Fully-implement this, then remove the "experimental_" prefix.
+	ExperimentalMapKey *string `protobuf:"bytes,9,opt,name=experimental_map_key" json:"experimental_map_key,omitempty"`
+	// For Google-internal migration only. Do not use.
+	Weak *bool `protobuf:"varint,10,opt,name=weak,def=0" json:"weak,omitempty"`
+	// The parser stores options it doesn't recognize here. See above.
 	UninterpretedOption []*UninterpretedOption    `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"`
 	XXX_extensions      map[int32]proto.Extension `json:"-"`
 	XXX_unrecognized    []byte                    `json:"-"`
@@ -867,7 +1020,10 @@
 }
 
 type EnumOptions struct {
-	AllowAlias          *bool                     `protobuf:"varint,2,opt,name=allow_alias,def=1" json:"allow_alias,omitempty"`
+	// Set this option to false to disallow mapping different tag names to a same
+	// value.
+	AllowAlias *bool `protobuf:"varint,2,opt,name=allow_alias,def=1" json:"allow_alias,omitempty"`
+	// The parser stores options it doesn't recognize here. See above.
 	UninterpretedOption []*UninterpretedOption    `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"`
 	XXX_extensions      map[int32]proto.Extension `json:"-"`
 	XXX_unrecognized    []byte                    `json:"-"`
@@ -908,6 +1064,7 @@
 }
 
 type EnumValueOptions struct {
+	// The parser stores options it doesn't recognize here. See above.
 	UninterpretedOption []*UninterpretedOption    `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"`
 	XXX_extensions      map[int32]proto.Extension `json:"-"`
 	XXX_unrecognized    []byte                    `json:"-"`
@@ -939,6 +1096,7 @@
 }
 
 type ServiceOptions struct {
+	// The parser stores options it doesn't recognize here. See above.
 	UninterpretedOption []*UninterpretedOption    `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"`
 	XXX_extensions      map[int32]proto.Extension `json:"-"`
 	XXX_unrecognized    []byte                    `json:"-"`
@@ -970,6 +1128,7 @@
 }
 
 type MethodOptions struct {
+	// The parser stores options it doesn't recognize here. See above.
 	UninterpretedOption []*UninterpretedOption    `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"`
 	XXX_extensions      map[int32]proto.Extension `json:"-"`
 	XXX_unrecognized    []byte                    `json:"-"`
@@ -1000,15 +1159,23 @@
 	return nil
 }
 
+// A message representing a option the parser does not recognize. This only
+// appears in options protos created by the compiler::Parser class.
+// DescriptorPool resolves these when building Descriptor objects. Therefore,
+// options protos in descriptor objects (e.g. returned by Descriptor::options(),
+// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
+// in them.
 type UninterpretedOption struct {
-	Name             []*UninterpretedOption_NamePart `protobuf:"bytes,2,rep,name=name" json:"name,omitempty"`
-	IdentifierValue  *string                         `protobuf:"bytes,3,opt,name=identifier_value" json:"identifier_value,omitempty"`
-	PositiveIntValue *uint64                         `protobuf:"varint,4,opt,name=positive_int_value" json:"positive_int_value,omitempty"`
-	NegativeIntValue *int64                          `protobuf:"varint,5,opt,name=negative_int_value" json:"negative_int_value,omitempty"`
-	DoubleValue      *float64                        `protobuf:"fixed64,6,opt,name=double_value" json:"double_value,omitempty"`
-	StringValue      []byte                          `protobuf:"bytes,7,opt,name=string_value" json:"string_value,omitempty"`
-	AggregateValue   *string                         `protobuf:"bytes,8,opt,name=aggregate_value" json:"aggregate_value,omitempty"`
-	XXX_unrecognized []byte                          `json:"-"`
+	Name []*UninterpretedOption_NamePart `protobuf:"bytes,2,rep,name=name" json:"name,omitempty"`
+	// The value of the uninterpreted option, in whatever type the tokenizer
+	// identified it as during parsing. Exactly one of these should be set.
+	IdentifierValue  *string  `protobuf:"bytes,3,opt,name=identifier_value" json:"identifier_value,omitempty"`
+	PositiveIntValue *uint64  `protobuf:"varint,4,opt,name=positive_int_value" json:"positive_int_value,omitempty"`
+	NegativeIntValue *int64   `protobuf:"varint,5,opt,name=negative_int_value" json:"negative_int_value,omitempty"`
+	DoubleValue      *float64 `protobuf:"fixed64,6,opt,name=double_value" json:"double_value,omitempty"`
+	StringValue      []byte   `protobuf:"bytes,7,opt,name=string_value" json:"string_value,omitempty"`
+	AggregateValue   *string  `protobuf:"bytes,8,opt,name=aggregate_value" json:"aggregate_value,omitempty"`
+	XXX_unrecognized []byte   `json:"-"`
 }
 
 func (m *UninterpretedOption) Reset()         { *m = UninterpretedOption{} }
@@ -1064,6 +1231,11 @@
 	return ""
 }
 
+// The name of the uninterpreted option.  Each string represents a segment in
+// a dot-separated name.  is_extension is true iff a segment represents an
+// extension (denoted with parentheses in options specs in .proto files).
+// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
+// "foo.(bar.baz).qux".
 type UninterpretedOption_NamePart struct {
 	NamePart         *string `protobuf:"bytes,1,req,name=name_part" json:"name_part,omitempty"`
 	IsExtension      *bool   `protobuf:"varint,2,req,name=is_extension" json:"is_extension,omitempty"`
@@ -1088,7 +1260,52 @@
 	return false
 }
 
+// Encapsulates information about the original source file from which a
+// FileDescriptorProto was generated.
 type SourceCodeInfo struct {
+	// A Location identifies a piece of source code in a .proto file which
+	// corresponds to a particular definition.  This information is intended
+	// to be useful to IDEs, code indexers, documentation generators, and similar
+	// tools.
+	//
+	// For example, say we have a file like:
+	//   message Foo {
+	//     optional string foo = 1;
+	//   }
+	// Let's look at just the field definition:
+	//   optional string foo = 1;
+	//   ^       ^^     ^^  ^  ^^^
+	//   a       bc     de  f  ghi
+	// We have the following locations:
+	//   span   path               represents
+	//   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
+	//   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
+	//   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
+	//   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
+	//   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
+	//
+	// Notes:
+	// - A location may refer to a repeated field itself (i.e. not to any
+	//   particular index within it).  This is used whenever a set of elements are
+	//   logically enclosed in a single code segment.  For example, an entire
+	//   extend block (possibly containing multiple extension definitions) will
+	//   have an outer location whose path refers to the "extensions" repeated
+	//   field without an index.
+	// - Multiple locations may have the same path.  This happens when a single
+	//   logical declaration is spread out across multiple places.  The most
+	//   obvious example is the "extend" block again -- there may be multiple
+	//   extend blocks in the same scope, each of which will have the same path.
+	// - A location's span is not always a subset of its parent's span.  For
+	//   example, the "extendee" of an extension declaration appears at the
+	//   beginning of the "extend" block and is shared by all extensions within
+	//   the block.
+	// - Just because a location's span is a subset of some other location's span
+	//   does not mean that it is a descendent.  For example, a "group" defines
+	//   both a type and a field in a single declaration.  Thus, the locations
+	//   corresponding to the type and field and their components will overlap.
+	// - Code which tries to interpret locations should probably be designed to
+	//   ignore those that it doesn't understand, as more types of locations could
+	//   be recorded in the future.
 	Location         []*SourceCodeInfo_Location `protobuf:"bytes,1,rep,name=location" json:"location,omitempty"`
 	XXX_unrecognized []byte                     `json:"-"`
 }
@@ -1105,8 +1322,70 @@
 }
 
 type SourceCodeInfo_Location struct {
-	Path             []int32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"`
-	Span             []int32 `protobuf:"varint,2,rep,packed,name=span" json:"span,omitempty"`
+	// Identifies which part of the FileDescriptorProto was defined at this
+	// location.
+	//
+	// Each element is a field number or an index.  They form a path from
+	// the root FileDescriptorProto to the place where the definition.  For
+	// example, this path:
+	//   [ 4, 3, 2, 7, 1 ]
+	// refers to:
+	//   file.message_type(3)  // 4, 3
+	//       .field(7)         // 2, 7
+	//       .name()           // 1
+	// This is because FileDescriptorProto.message_type has field number 4:
+	//   repeated DescriptorProto message_type = 4;
+	// and DescriptorProto.field has field number 2:
+	//   repeated FieldDescriptorProto field = 2;
+	// and FieldDescriptorProto.name has field number 1:
+	//   optional string name = 1;
+	//
+	// Thus, the above path gives the location of a field name.  If we removed
+	// the last element:
+	//   [ 4, 3, 2, 7 ]
+	// this path refers to the whole field declaration (from the beginning
+	// of the label to the terminating semicolon).
+	Path []int32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"`
+	// Always has exactly three or four elements: start line, start column,
+	// end line (optional, otherwise assumed same as start line), end column.
+	// These are packed into a single field for efficiency.  Note that line
+	// and column numbers are zero-based -- typically you will want to add
+	// 1 to each before displaying to a user.
+	Span []int32 `protobuf:"varint,2,rep,packed,name=span" json:"span,omitempty"`
+	// If this SourceCodeInfo represents a complete declaration, these are any
+	// comments appearing before and after the declaration which appear to be
+	// attached to the declaration.
+	//
+	// A series of line comments appearing on consecutive lines, with no other
+	// tokens appearing on those lines, will be treated as a single comment.
+	//
+	// Only the comment content is provided; comment markers (e.g. //) are
+	// stripped out.  For block comments, leading whitespace and an asterisk
+	// will be stripped from the beginning of each line other than the first.
+	// Newlines are included in the output.
+	//
+	// Examples:
+	//
+	//   optional int32 foo = 1;  // Comment attached to foo.
+	//   // Comment attached to bar.
+	//   optional int32 bar = 2;
+	//
+	//   optional string baz = 3;
+	//   // Comment attached to baz.
+	//   // Another line attached to baz.
+	//
+	//   // Comment attached to qux.
+	//   //
+	//   // Another line attached to qux.
+	//   optional double qux = 4;
+	//
+	//   optional string corge = 5;
+	//   /* Block comment attached
+	//    * to corge.  Leading asterisks
+	//    * will be removed. */
+	//   /* Block comment attached to
+	//    * grault. */
+	//   optional int32 grault = 6;
 	LeadingComments  *string `protobuf:"bytes,3,opt,name=leading_comments" json:"leading_comments,omitempty"`
 	TrailingComments *string `protobuf:"bytes,4,opt,name=trailing_comments" json:"trailing_comments,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
diff --git a/protoc-gen-go/generator/generator.go b/protoc-gen-go/generator/generator.go
index 3ad2d13..7fff0fa 100644
--- a/protoc-gen-go/generator/generator.go
+++ b/protoc-gen-go/generator/generator.go
@@ -104,6 +104,7 @@
 	ext      []*ExtensionDescriptor // Extensions, if any.
 	typename []string               // Cached typename vector.
 	index    int                    // The index into the container, whether the file or another message.
+	path     string                 // The SourceCodeInfo path as comma-separated integers.
 	group    bool
 }
 
@@ -133,6 +134,7 @@
 	*descriptor.EnumDescriptorProto
 	parent   *Descriptor // The containing message, if any.
 	typename []string    // Cached typename vector.
+	path     string      // The SourceCodeInfo path as comma-separated integers.
 }
 
 // TypeName returns the elements of the dotted type name.
@@ -230,6 +232,9 @@
 	ext  []*ExtensionDescriptor // All the top-level extensions defined in this file.
 	imp  []*ImportedDescriptor  // All types defined in files publicly imported by this file.
 
+	// Comments, stored as a map of path (comma-separated integers) to the comment.
+	comments map[string]*descriptor.SourceCodeInfo_Location
+
 	// The full list of symbols that are exported,
 	// as a map from the exported object to its symbols.
 	// This is used for supporting public imports.
@@ -245,6 +250,12 @@
 // the name was derived from the protocol buffer's package statement
 // or the input file name.
 func (d *FileDescriptor) goPackageName() (name string, explicit bool) {
+	// Does the file have a "go_package" option?
+	if opts := d.Options; opts != nil {
+		if pkg := opts.GetGoPackage(); pkg != "" {
+			return pkg, true
+		}
+	}
 
 	// Does the file have a package clause?
 	if pkg := d.GetPackage(); pkg != "" {
@@ -638,7 +649,7 @@
 		enums := wrapEnumDescriptors(f, descs)
 		exts := wrapExtensions(f)
 		imps := wrapImported(f, g)
-		g.allFiles[i] = &FileDescriptor{
+		fd := &FileDescriptor{
 			FileDescriptorProto: f,
 			desc:                descs,
 			enum:                enums,
@@ -646,6 +657,8 @@
 			imp:                 imps,
 			exported:            make(map[Object][]symbol),
 		}
+		extractComments(fd)
+		g.allFiles[i] = fd
 	}
 
 	g.genFiles = make([]*FileDescriptor, len(g.Request.FileToGenerate))
@@ -682,14 +695,19 @@
 	}
 }
 
-// Construct the Descriptor and add it to the slice
-func addDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto, index int) []*Descriptor {
+// Construct the Descriptor
+func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto, index int) *Descriptor {
 	d := &Descriptor{
 		common:          common{file},
 		DescriptorProto: desc,
 		parent:          parent,
 		index:           index,
 	}
+	if parent == nil {
+		d.path = fmt.Sprintf("%d,%d", messagePath, index)
+	} else {
+		d.path = fmt.Sprintf("%s,%d,%d", parent.path, messageMessagePath, index)
+	}
 
 	// The only way to distinguish a group from a message is whether
 	// the containing message has a TYPE_GROUP field that matches.
@@ -712,7 +730,7 @@
 		d.ext[i] = &ExtensionDescriptor{common{file}, field, d}
 	}
 
-	return append(sl, d)
+	return d
 }
 
 // Return a slice of all the Descriptors defined within this file
@@ -726,7 +744,7 @@
 
 // Wrap this Descriptor, recursively
 func wrapThisDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto, index int) []*Descriptor {
-	sl = addDescriptor(sl, desc, parent, file, index)
+	sl = append(sl, newDescriptor(desc, parent, file, index))
 	me := sl[len(sl)-1]
 	for i, nested := range desc.NestedType {
 		sl = wrapThisDescriptor(sl, nested, me, file, i)
@@ -734,22 +752,32 @@
 	return sl
 }
 
-// Construct the EnumDescriptor and add it to the slice
-func addEnumDescriptor(sl []*EnumDescriptor, desc *descriptor.EnumDescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto) []*EnumDescriptor {
-	return append(sl, &EnumDescriptor{common{file}, desc, parent, nil})
+// Construct the EnumDescriptor
+func newEnumDescriptor(desc *descriptor.EnumDescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto, index int) *EnumDescriptor {
+	ed := &EnumDescriptor{
+		common:              common{file},
+		EnumDescriptorProto: desc,
+		parent:              parent,
+	}
+	if parent == nil {
+		ed.path = fmt.Sprintf("%d,%d", enumPath, index)
+	} else {
+		ed.path = fmt.Sprintf("%s,%d,%d", parent.path, messageEnumPath, index)
+	}
+	return ed
 }
 
 // Return a slice of all the EnumDescriptors defined within this file
 func wrapEnumDescriptors(file *descriptor.FileDescriptorProto, descs []*Descriptor) []*EnumDescriptor {
 	sl := make([]*EnumDescriptor, 0, len(file.EnumType)+10)
 	// Top-level enums.
-	for _, enum := range file.EnumType {
-		sl = addEnumDescriptor(sl, enum, nil, file)
+	for i, enum := range file.EnumType {
+		sl = append(sl, newEnumDescriptor(enum, nil, file, i))
 	}
 	// Enums within messages. Enums within embedded messages appear in the outer-most message.
 	for _, nested := range descs {
-		for _, enum := range nested.EnumType {
-			sl = addEnumDescriptor(sl, enum, nested, file)
+		for i, enum := range nested.EnumType {
+			sl = append(sl, newEnumDescriptor(enum, nested, file, i))
 		}
 	}
 	return sl
@@ -781,6 +809,20 @@
 	return
 }
 
+func extractComments(file *FileDescriptor) {
+	file.comments = make(map[string]*descriptor.SourceCodeInfo_Location)
+	for _, loc := range file.GetSourceCodeInfo().GetLocation() {
+		if loc.LeadingComments == nil {
+			continue
+		}
+		var p []string
+		for _, n := range loc.Path {
+			p = append(p, strconv.Itoa(int(n)))
+		}
+		file.comments[strings.Join(p, ",")] = loc
+	}
+}
+
 // BuildTypeNameMap builds the map from fully qualified type names to objects.
 // The key names for the map come from the input data, which puts a period at the beginning.
 // It should be called after SetPackageNames and before GenerateAllFiles.
@@ -988,6 +1030,18 @@
 	g.P()
 }
 
+// PrintComments prints any comments from the source .proto file.
+// The path is a comma-separated list of integers.
+// See descriptor.proto for its format.
+func (g *Generator) PrintComments(path string) {
+	if loc, ok := g.file.comments[path]; ok {
+		text := strings.TrimSuffix(loc.GetLeadingComments(), "\n")
+		for _, line := range strings.Split(text, "\n") {
+			g.P("// ", strings.TrimPrefix(line, " "))
+		}
+	}
+}
+
 func (g *Generator) fileByName(filename string) *FileDescriptor {
 	for _, fd := range g.allFiles {
 		if fd.GetName() == filename {
@@ -1092,11 +1146,15 @@
 	// The full type name, CamelCased.
 	ccTypeName := CamelCaseSlice(typeName)
 	ccPrefix := enum.prefix()
+
+	g.PrintComments(enum.path)
 	g.P("type ", ccTypeName, " int32")
 	g.file.addExport(enum, enumSymbol(ccTypeName))
 	g.P("const (")
 	g.In()
-	for _, e := range enum.Value {
+	for i, e := range enum.Value {
+		g.PrintComments(fmt.Sprintf("%s,%d,%d", enum.path, enumValuePath, i))
+
 		name := ccPrefix + *e.Name
 		g.P(name, " ", ccTypeName, " = ", e.Number)
 		g.file.addExport(enum, constOrVarSymbol{name, "const"})
@@ -1362,10 +1420,14 @@
 	}
 	fieldNames := make(map[*descriptor.FieldDescriptorProto]string)
 	fieldGetterNames := make(map[*descriptor.FieldDescriptorProto]string)
+
+	g.PrintComments(message.path)
 	g.P("type ", ccTypeName, " struct {")
 	g.In()
 
-	for _, field := range message.Field {
+	for i, field := range message.Field {
+		g.PrintComments(fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i))
+
 		fieldName := CamelCase(*field.Name)
 		for usedNames[fieldName] {
 			fieldName += "_"
@@ -1789,3 +1851,23 @@
 	}
 	return name
 }
+
+// The SourceCodeInfo message describes the location of elements of a parsed
+// .proto file by way of a "path", which is a sequence of integers that
+// describe the route from a FileDescriptorProto to the relevant submessage.
+// The path alternates between a field number of a repeated field, and an index
+// into that repeated field. The constants below define the field numbers that
+// are used.
+//
+// See descriptor.proto for more information about this.
+const (
+	// tag numbers in FileDescriptorProto
+	messagePath = 4 // message_type
+	enumPath    = 5 // enum_type
+	// tag numbers in DescriptorProto
+	messageFieldPath   = 2 // field
+	messageMessagePath = 3 // nested_type
+	messageEnumPath    = 4 // enum_type
+	// tag numbers in EnumDescriptorProto
+	enumValuePath = 2 // value
+)
diff --git a/protoc-gen-go/plugin/plugin.pb.go b/protoc-gen-go/plugin/plugin.pb.go
index ccc2a4c..90e90ce 100644
--- a/protoc-gen-go/plugin/plugin.pb.go
+++ b/protoc-gen-go/plugin/plugin.pb.go
@@ -14,9 +14,25 @@
 var _ = &json.SyntaxError{}
 var _ = math.Inf
 
+// An encoded CodeGeneratorRequest is written to the plugin's stdin.
 type CodeGeneratorRequest struct {
-	FileToGenerate   []string                               `protobuf:"bytes,1,rep,name=file_to_generate" json:"file_to_generate,omitempty"`
-	Parameter        *string                                `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"`
+	// The .proto files that were explicitly listed on the command-line.  The
+	// code generator should generate code only for these files.  Each file's
+	// descriptor will be included in proto_file, below.
+	FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate" json:"file_to_generate,omitempty"`
+	// The generator parameter passed on the command-line.
+	Parameter *string `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"`
+	// FileDescriptorProtos for all files in files_to_generate and everything
+	// they import.  The files will appear in topological order, so each file
+	// appears before any file that imports it.
+	//
+	// protoc guarantees that all proto_files will be written after
+	// the fields above, even though this is not technically guaranteed by the
+	// protobuf wire format.  This theoretically could allow a plugin to stream
+	// in the FileDescriptorProtos and handle them one by one rather than read
+	// the entire set into memory at once.  However, as of this writing, this
+	// is not similarly optimized on protoc's end -- it will store all fields in
+	// memory at once before sending them to the plugin.
 	ProtoFile        []*google_protobuf.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file" json:"proto_file,omitempty"`
 	XXX_unrecognized []byte                                 `json:"-"`
 }
@@ -46,7 +62,16 @@
 	return nil
 }
 
+// The plugin writes an encoded CodeGeneratorResponse to stdout.
 type CodeGeneratorResponse struct {
+	// Error message.  If non-empty, code generation failed.  The plugin process
+	// should exit with status code zero even if it reports an error in this way.
+	//
+	// This should be used to indicate errors in .proto files which prevent the
+	// code generator from generating correct code.  Errors which indicate a
+	// problem in protoc itself -- such as the input CodeGeneratorRequest being
+	// unparseable -- should be reported by writing a message to stderr and
+	// exiting with a non-zero status code.
 	Error            *string                       `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"`
 	File             []*CodeGeneratorResponse_File `protobuf:"bytes,15,rep,name=file" json:"file,omitempty"`
 	XXX_unrecognized []byte                        `json:"-"`
@@ -70,9 +95,59 @@
 	return nil
 }
 
+// Represents a single generated file.
 type CodeGeneratorResponse_File struct {
-	Name             *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
-	InsertionPoint   *string `protobuf:"bytes,2,opt,name=insertion_point" json:"insertion_point,omitempty"`
+	// The file name, relative to the output directory.  The name must not
+	// contain "." or ".." components and must be relative, not be absolute (so,
+	// the file cannot lie outside the output directory).  "/" must be used as
+	// the path separator, not "\".
+	//
+	// If the name is omitted, the content will be appended to the previous
+	// file.  This allows the generator to break large files into small chunks,
+	// and allows the generated text to be streamed back to protoc so that large
+	// files need not reside completely in memory at one time.  Note that as of
+	// this writing protoc does not optimize for this -- it will read the entire
+	// CodeGeneratorResponse before writing files to disk.
+	Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	// If non-empty, indicates that the named file should already exist, and the
+	// content here is to be inserted into that file at a defined insertion
+	// point.  This feature allows a code generator to extend the output
+	// produced by another code generator.  The original generator may provide
+	// insertion points by placing special annotations in the file that look
+	// like:
+	//   @@protoc_insertion_point(NAME)
+	// The annotation can have arbitrary text before and after it on the line,
+	// which allows it to be placed in a comment.  NAME should be replaced with
+	// an identifier naming the point -- this is what other generators will use
+	// as the insertion_point.  Code inserted at this point will be placed
+	// immediately above the line containing the insertion point (thus multiple
+	// insertions to the same point will come out in the order they were added).
+	// The double-@ is intended to make it unlikely that the generated code
+	// could contain things that look like insertion points by accident.
+	//
+	// For example, the C++ code generator places the following line in the
+	// .pb.h files that it generates:
+	//   // @@protoc_insertion_point(namespace_scope)
+	// This line appears within the scope of the file's package namespace, but
+	// outside of any particular class.  Another plugin can then specify the
+	// insertion_point "namespace_scope" to generate additional classes or
+	// other declarations that should be placed in this scope.
+	//
+	// Note that if the line containing the insertion point begins with
+	// whitespace, the same whitespace will be added to every line of the
+	// inserted text.  This is useful for languages like Python, where
+	// indentation matters.  In these languages, the insertion point comment
+	// should be indented the same amount as any inserted code will need to be
+	// in order to work correctly in that context.
+	//
+	// The code generator that generates the initial file and the one which
+	// inserts into it must both run as part of a single invocation of protoc.
+	// Code generators are executed in the order in which they appear on the
+	// command line.
+	//
+	// If |insertion_point| is present, |name| must also be present.
+	InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point" json:"insertion_point,omitempty"`
+	// The file contents.
 	Content          *string `protobuf:"bytes,15,opt,name=content" json:"content,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
 }
diff --git a/protoc-gen-go/testdata/my_test/test.pb.go b/protoc-gen-go/testdata/my_test/test.pb.go
index 97bc4d4..a9d538d 100644
--- a/protoc-gen-go/testdata/my_test/test.pb.go
+++ b/protoc-gen-go/testdata/my_test/test.pb.go
@@ -18,6 +18,7 @@
 type HatType int32
 
 const (
+	// deliberately skipping 0
 	HatType_FEDORA HatType = 1
 	HatType_FEZ    HatType = 2
 )
@@ -51,6 +52,7 @@
 	return nil
 }
 
+// This enum represents days of the week.
 type Days int32
 
 const (
@@ -165,10 +167,13 @@
 	return nil
 }
 
+// This is a message that might be sent somewhere.
 type Request struct {
-	Key              []int64            `protobuf:"varint,1,rep,name=key" json:"key,omitempty"`
-	Hue              *Request_Color     `protobuf:"varint,3,opt,name=hue,enum=my.test.Request_Color" json:"hue,omitempty"`
-	Hat              *HatType           `protobuf:"varint,4,opt,name=hat,enum=my.test.HatType,def=1" json:"hat,omitempty"`
+	Key []int64 `protobuf:"varint,1,rep,name=key" json:"key,omitempty"`
+	//  optional imp.ImportedMessage imported_message = 2;
+	Hue *Request_Color `protobuf:"varint,3,opt,name=hue,enum=my.test.Request_Color" json:"hue,omitempty"`
+	Hat *HatType       `protobuf:"varint,4,opt,name=hat,enum=my.test.HatType,def=1" json:"hat,omitempty"`
+	//  optional imp.ImportedMessage.Owner owner = 6;
 	Deadline         *float32           `protobuf:"fixed32,7,opt,name=deadline,def=inf" json:"deadline,omitempty"`
 	Somegroup        *Request_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"`
 	Reset_           *int32             `protobuf:"varint,12,opt,name=reset" json:"reset,omitempty"`
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 97bc4d4..a9d538d 100644
--- a/protoc-gen-go/testdata/my_test/test.pb.go.golden
+++ b/protoc-gen-go/testdata/my_test/test.pb.go.golden
@@ -18,6 +18,7 @@
 type HatType int32
 
 const (
+	// deliberately skipping 0
 	HatType_FEDORA HatType = 1
 	HatType_FEZ    HatType = 2
 )
@@ -51,6 +52,7 @@
 	return nil
 }
 
+// This enum represents days of the week.
 type Days int32
 
 const (
@@ -165,10 +167,13 @@
 	return nil
 }
 
+// This is a message that might be sent somewhere.
 type Request struct {
-	Key              []int64            `protobuf:"varint,1,rep,name=key" json:"key,omitempty"`
-	Hue              *Request_Color     `protobuf:"varint,3,opt,name=hue,enum=my.test.Request_Color" json:"hue,omitempty"`
-	Hat              *HatType           `protobuf:"varint,4,opt,name=hat,enum=my.test.HatType,def=1" json:"hat,omitempty"`
+	Key []int64 `protobuf:"varint,1,rep,name=key" json:"key,omitempty"`
+	//  optional imp.ImportedMessage imported_message = 2;
+	Hue *Request_Color `protobuf:"varint,3,opt,name=hue,enum=my.test.Request_Color" json:"hue,omitempty"`
+	Hat *HatType       `protobuf:"varint,4,opt,name=hat,enum=my.test.HatType,def=1" json:"hat,omitempty"`
+	//  optional imp.ImportedMessage.Owner owner = 6;
 	Deadline         *float32           `protobuf:"fixed32,7,opt,name=deadline,def=inf" json:"deadline,omitempty"`
 	Somegroup        *Request_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"`
 	Reset_           *int32             `protobuf:"varint,12,opt,name=reset" json:"reset,omitempty"`
diff --git a/protoc-gen-go/testdata/my_test/test.proto b/protoc-gen-go/testdata/my_test/test.proto
index d99e71b..d26e20c 100644
--- a/protoc-gen-go/testdata/my_test/test.proto
+++ b/protoc-gen-go/testdata/my_test/test.proto
@@ -40,6 +40,7 @@
   FEZ = 2;
 }
 
+// This enum represents days of the week.
 enum Days {
   option allow_alias = true;
 
@@ -48,6 +49,7 @@
   LUNDI = 1;  // same value as MONDAY
 }
 
+// This is a message that might be sent somewhere.
 message Request {
   enum Color {
     RED = 0;