goprotobuf: push out internal changes.
  - group text parsing and formatting
  - foreign extension types

R=adg
CC=golang-dev
http://codereview.appspot.com/4437079
diff --git a/compiler/generator/generator.go b/compiler/generator/generator.go
index 4d0063d..2d93658 100644
--- a/compiler/generator/generator.go
+++ b/compiler/generator/generator.go
@@ -49,7 +49,7 @@
 	"strings"
 
 	"goprotobuf.googlecode.com/hg/proto"
-	plugin     "goprotobuf.googlecode.com/hg/compiler/plugin"
+	plugin "goprotobuf.googlecode.com/hg/compiler/plugin"
 	descriptor "goprotobuf.googlecode.com/hg/compiler/descriptor"
 )
 
@@ -890,7 +890,17 @@
 		packed = ",packed"
 	}
 	name := proto.GetString(field.Name)
-	if name == CamelCase(name) {
+	if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP {
+		// We must use the type name for groups instead of
+		// the field name to preserve capitalization.
+		// type_name in FieldDescriptorProto is fully-qualified,
+		// but we only want the local part.
+		name = *field.TypeName
+		if i := strings.LastIndex(name, "."); i >= 0 {
+			name = name[i+1:]
+		}
+		name = ",name=" + name
+	} else if name == CamelCase(name) {
 		name = ""
 	} else {
 		name = ",name=" + name
@@ -1140,6 +1150,10 @@
 	fieldType, wireType := g.GoType(ext.parent, field)
 	tag := g.goTag(field, wireType)
 	g.RecordTypeUse(*ext.Extendee)
+	if n := ext.FieldDescriptorProto.TypeName; n != nil {
+		// foreign extension type
+		g.RecordTypeUse(*n)
+	}
 
 	g.P("var ", ccTypeName, " = &", g.ProtoPkg, ".ExtensionDesc{")
 	g.In()
diff --git a/compiler/testdata/Makefile b/compiler/testdata/Makefile
index 091c0d4..8238870 100644
--- a/compiler/testdata/Makefile
+++ b/compiler/testdata/Makefile
@@ -65,4 +65,4 @@
 test.pb.go:	imp.pb.go
 multi1.pb.go:	multi2.pb.go multi3.pb.go
 main.$O: imp.pb.$O test.pb.$O multi.a
-extension_test.$O: extension_base.pb.$O extension_user.pb.$O
+extension_test.$O: extension_base.pb.$O extension_extra.pb.$O extension_user.pb.$O
diff --git a/compiler/testdata/extension_extra.proto b/compiler/testdata/extension_extra.proto
new file mode 100644
index 0000000..08b949b
--- /dev/null
+++ b/compiler/testdata/extension_extra.proto
@@ -0,0 +1,38 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 Google Inc.  All rights reserved.
+// http://code.google.com/p/goprotobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+package extension_extra;
+
+message ExtraMessage {
+  optional int32 width = 1;
+}
diff --git a/compiler/testdata/extension_user.proto b/compiler/testdata/extension_user.proto
index f1d28cd..b5a731a 100644
--- a/compiler/testdata/extension_user.proto
+++ b/compiler/testdata/extension_user.proto
@@ -30,6 +30,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 import "extension_base.proto";
+import "extension_extra.proto";
 
 package extension_user;
 
@@ -43,6 +44,11 @@
   optional UserMessage user_message = 5;
 }
 
+// Extend with a foreign message
+extend extension_base.BaseMessage {
+  optional extension_extra.ExtraMessage extra_message = 9;
+}
+
 // Extend with some primitive types
 extend extension_base.BaseMessage {
   optional int32 width = 6;
diff --git a/compiler/testdata/test.pb.go.golden b/compiler/testdata/test.pb.go.golden
index 409f295..ccd0f09 100644
--- a/compiler/testdata/test.pb.go.golden
+++ b/compiler/testdata/test.pb.go.golden
@@ -123,6 +123,7 @@
 	Hat			*HatType			"PB(varint,4,opt,name=hat,enum=my_test.HatType,def=1)"
 	Owner			*imp.ImportedMessage_Owner	"PB(varint,6,opt,name=owner,enum=imp.ImportedMessage_Owner)"
 	Deadline		*float32			"PB(fixed32,7,opt,name=deadline,def=inf)"
+	Somegroup		*Request_SomeGroup		"PB(group,8,opt,name=SomeGroup)"
 	XXX_unrecognized	[]byte
 }
 
@@ -134,6 +135,15 @@
 
 var Default_Request_Deadline float32 = float32(math.Inf(1))
 
+type Request_SomeGroup struct {
+	GroupField		*int32	"PB(varint,9,opt,name=group_field)"
+	XXX_unrecognized	[]byte
+}
+
+func (this *Request_SomeGroup) Reset() {
+	*this = Request_SomeGroup{}
+}
+
 type Reply struct {
 	Found			[]*Reply_Entry	"PB(bytes,1,rep,name=found)"
 	CompactKeys		[]int32		"PB(varint,2,rep,packed,name=compact_keys)"
diff --git a/compiler/testdata/test.proto b/compiler/testdata/test.proto
index 7c7af50..fd26d1f 100644
--- a/compiler/testdata/test.proto
+++ b/compiler/testdata/test.proto
@@ -58,6 +58,9 @@
   optional HatType hat = 4 [default=FEDORA];
   optional imp.ImportedMessage.Owner owner = 6;
   optional float deadline = 7 [default=inf];
+  optional group SomeGroup = 8 {
+    optional int32 group_field = 9;
+  }
 }
 
 message Reply {