Add extensions to the generator.
R=r
CC=golang-dev
http://codereview.appspot.com/774041
diff --git a/compiler/testdata/extension_test.go b/compiler/testdata/extension_test.go
new file mode 100644
index 0000000..1ddb229
--- /dev/null
+++ b/compiler/testdata/extension_test.go
@@ -0,0 +1,159 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 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.
+
+// Test that we can use protocol buffers that use extensions.
+
+package main
+
+import (
+ "testing"
+
+ "goprotobuf.googlecode.com/hg/proto"
+ base "extension_base.pb"
+ user "extension_user.pb"
+)
+
+func TestSingleFieldExtension(t *testing.T) {
+ bm := base.NewBaseMessage()
+ bm.Height = proto.Int32(178)
+
+ // Use extension within scope of another type.
+ vol := proto.Uint32(11)
+ t.Logf("bm: %T, user.LoudMessage_Volume: %T", bm, user.LoudMessage_Volume)
+ err := proto.SetExtension(bm, user.LoudMessage_Volume, vol)
+ if err != nil {
+ t.Fatal("Failed setting extension:", err)
+ }
+ buf, err := proto.Marshal(bm)
+ if err != nil {
+ t.Fatal("Failed encoding message with extension:", err)
+ }
+ bm_new := base.NewBaseMessage()
+ if err := proto.Unmarshal(buf, bm_new); err != nil {
+ t.Fatal("Failed decoding message with extension:", err)
+ }
+ if !proto.HasExtension(bm_new, user.LoudMessage_Volume) {
+ t.Fatal("Decoded message didn't contain extension.")
+ }
+ vol_out, err := proto.GetExtension(bm_new, user.LoudMessage_Volume)
+ if err != nil {
+ t.Fatal("Failed getting extension:", err)
+ }
+ if v := vol_out.(*uint32); *v != *vol {
+ t.Errorf("vol_out = %v, expected %v", *v, *vol)
+ }
+ proto.ClearExtension(bm_new, user.LoudMessage_Volume)
+ if proto.HasExtension(bm_new, user.LoudMessage_Volume) {
+ t.Fatal("Failed clearing extension.")
+ }
+}
+
+func TestMessageExtension(t *testing.T) {
+ bm := base.NewBaseMessage()
+ bm.Height = proto.Int32(179)
+
+ // Use extension that is itself a message.
+ um := &user.UserMessage{
+ Name: proto.String("Dave"),
+ Rank: proto.String("Major"),
+ }
+ err := proto.SetExtension(bm, user.LoginMessage_UserMessage, um)
+ if err != nil {
+ t.Fatal("Failed setting extension:", err)
+ }
+ buf, err := proto.Marshal(bm)
+ if err != nil {
+ t.Fatal("Failed encoding message with extension:", err)
+ }
+ bm_new := base.NewBaseMessage()
+ if err := proto.Unmarshal(buf, bm_new); err != nil {
+ t.Fatal("Failed decoding message with extension:", err)
+ }
+ if !proto.HasExtension(bm_new, user.LoginMessage_UserMessage) {
+ t.Fatal("Decoded message didn't contain extension.")
+ }
+ um_out, err := proto.GetExtension(bm_new, user.LoginMessage_UserMessage)
+ if err != nil {
+ t.Fatal("Failed getting extension:", err)
+ }
+ if n := um_out.(*user.UserMessage).Name; *n != *um.Name {
+ t.Errorf("um_out.Name = %q, expected %q", *n, *um.Name)
+ }
+ if r := um_out.(*user.UserMessage).Rank; *r != *um.Rank {
+ t.Errorf("um_out.Rank = %q, expected %q", *r, *um.Rank)
+ }
+ proto.ClearExtension(bm_new, user.LoginMessage_UserMessage)
+ if proto.HasExtension(bm_new, user.LoginMessage_UserMessage) {
+ t.Fatal("Failed clearing extension.")
+ }
+}
+
+func TestTopLevelExtension(t *testing.T) {
+ bm := base.NewBaseMessage()
+ bm.Height = proto.Int32(179)
+
+ width := proto.Int32(17)
+ err := proto.SetExtension(bm, user.E_Width, width)
+ if err != nil {
+ t.Fatal("Failed setting extension:", err)
+ }
+ buf, err := proto.Marshal(bm)
+ if err != nil {
+ t.Fatal("Failed encoding message with extension:", err)
+ }
+ bm_new := base.NewBaseMessage()
+ if err := proto.Unmarshal(buf, bm_new); err != nil {
+ t.Fatal("Failed decoding message with extension:", err)
+ }
+ if !proto.HasExtension(bm_new, user.E_Width) {
+ t.Fatal("Decoded message didn't contain extension.")
+ }
+ width_out, err := proto.GetExtension(bm_new, user.E_Width)
+ if err != nil {
+ t.Fatal("Failed getting extension:", err)
+ }
+ if w := width_out.(*int32); *w != *width {
+ t.Errorf("width_out = %v, expected %v", *w, *width)
+ }
+ proto.ClearExtension(bm_new, user.E_Width)
+ if proto.HasExtension(bm_new, user.E_Width) {
+ t.Fatal("Failed clearing extension.")
+ }
+}
+
+func main() {
+ // simpler than rigging up gotest
+ testing.Main([]testing.Test{
+ testing.Test{"TestSingleFieldExtension", TestSingleFieldExtension},
+ testing.Test{"TestMessageExtension", TestMessageExtension},
+ testing.Test{"TestTopLevelExtension", TestTopLevelExtension},
+ })
+}