Browse Source

bump(github.com/coreos/raft): ef3280ce54f60fff98a72012f547ed2b3415841f

Brandon Philips 12 years ago
parent
commit
76da437f29
80 changed files with 20358 additions and 584 deletions
  1. 1 1
      etcd.go
  2. 2 2
      server/peer_server.go
  3. 1 1
      server/peer_server_handlers.go
  4. 1 1
      tests/server_utils.go
  5. 40 0
      third_party/code.google.com/p/gogoprotobuf/proto/Makefile
  6. 1893 0
      third_party/code.google.com/p/gogoprotobuf/proto/all_test.go
  7. 166 0
      third_party/code.google.com/p/gogoprotobuf/proto/clone.go
  8. 180 0
      third_party/code.google.com/p/gogoprotobuf/proto/clone_test.go
  9. 732 0
      third_party/code.google.com/p/gogoprotobuf/proto/decode.go
  10. 220 0
      third_party/code.google.com/p/gogoprotobuf/proto/decode_gogo.go
  11. 952 0
      third_party/code.google.com/p/gogoprotobuf/proto/encode.go
  12. 367 0
      third_party/code.google.com/p/gogoprotobuf/proto/encode_gogo.go
  13. 241 0
      third_party/code.google.com/p/gogoprotobuf/proto/equal.go
  14. 166 0
      third_party/code.google.com/p/gogoprotobuf/proto/equal_test.go
  15. 350 0
      third_party/code.google.com/p/gogoprotobuf/proto/extensions.go
  16. 94 0
      third_party/code.google.com/p/gogoprotobuf/proto/extensions_gogo.go
  17. 789 0
      third_party/code.google.com/p/gogoprotobuf/proto/lib.go
  18. 40 0
      third_party/code.google.com/p/gogoprotobuf/proto/lib_gogo.go
  19. 216 0
      third_party/code.google.com/p/gogoprotobuf/proto/message_set.go
  20. 384 0
      third_party/code.google.com/p/gogoprotobuf/proto/pointer_reflect.go
  21. 218 0
      third_party/code.google.com/p/gogoprotobuf/proto/pointer_unsafe.go
  22. 159 0
      third_party/code.google.com/p/gogoprotobuf/proto/pointer_unsafe_gogo.go
  23. 664 0
      third_party/code.google.com/p/gogoprotobuf/proto/properties.go
  24. 107 0
      third_party/code.google.com/p/gogoprotobuf/proto/properties_gogo.go
  25. 63 0
      third_party/code.google.com/p/gogoprotobuf/proto/size2_test.go
  26. 118 0
      third_party/code.google.com/p/gogoprotobuf/proto/size_test.go
  27. 116 0
      third_party/code.google.com/p/gogoprotobuf/proto/skip_gogo.go
  28. 47 0
      third_party/code.google.com/p/gogoprotobuf/proto/testdata/Makefile
  29. 86 0
      third_party/code.google.com/p/gogoprotobuf/proto/testdata/golden_test.go
  30. 2294 0
      third_party/code.google.com/p/gogoprotobuf/proto/testdata/test.pb.go
  31. 1737 0
      third_party/code.google.com/p/gogoprotobuf/proto/testdata/test.pb.go.golden
  32. 420 0
      third_party/code.google.com/p/gogoprotobuf/proto/testdata/test.proto
  33. 686 0
      third_party/code.google.com/p/gogoprotobuf/proto/text.go
  34. 55 0
      third_party/code.google.com/p/gogoprotobuf/proto/text_gogo.go
  35. 713 0
      third_party/code.google.com/p/gogoprotobuf/proto/text_parser.go
  36. 452 0
      third_party/code.google.com/p/gogoprotobuf/proto/text_parser_test.go
  37. 357 0
      third_party/code.google.com/p/gogoprotobuf/proto/text_test.go
  38. 1 0
      third_party/github.com/coreos/raft/.gitignore
  39. 7 4
      third_party/github.com/coreos/raft/Makefile
  40. 18 34
      third_party/github.com/coreos/raft/append_entries_request.go
  41. 35 32
      third_party/github.com/coreos/raft/append_entries_response.go
  42. 0 1
      third_party/github.com/coreos/raft/command.go
  43. 1 1
      third_party/github.com/coreos/raft/event.go
  44. 1 1
      third_party/github.com/coreos/raft/event_dispatcher_test.go
  45. 4 4
      third_party/github.com/coreos/raft/http_transporter_test.go
  46. 40 38
      third_party/github.com/coreos/raft/log.go
  47. 36 30
      third_party/github.com/coreos/raft/log_entry.go
  48. 9 9
      third_party/github.com/coreos/raft/log_test.go
  49. 39 35
      third_party/github.com/coreos/raft/peer.go
  50. 608 46
      third_party/github.com/coreos/raft/protobuf/append_entries_request.pb.go
  51. 17 10
      third_party/github.com/coreos/raft/protobuf/append_entries_request.proto
  52. 501 10
      third_party/github.com/coreos/raft/protobuf/append_entries_responses.pb.go
  53. 15 1
      third_party/github.com/coreos/raft/protobuf/append_entries_responses.proto
  54. 503 10
      third_party/github.com/coreos/raft/protobuf/log_entry.pb.go
  55. 15 1
      third_party/github.com/coreos/raft/protobuf/log_entry.proto
  56. 503 10
      third_party/github.com/coreos/raft/protobuf/request_vote_request.pb.go
  57. 15 1
      third_party/github.com/coreos/raft/protobuf/request_vote_request.proto
  58. 407 8
      third_party/github.com/coreos/raft/protobuf/request_vote_responses.pb.go
  59. 15 1
      third_party/github.com/coreos/raft/protobuf/request_vote_responses.proto
  60. 828 25
      third_party/github.com/coreos/raft/protobuf/snapshot_recovery_request.pb.go
  61. 17 3
      third_party/github.com/coreos/raft/protobuf/snapshot_recovery_request.proto
  62. 454 9
      third_party/github.com/coreos/raft/protobuf/snapshot_recovery_response.pb.go
  63. 15 1
      third_party/github.com/coreos/raft/protobuf/snapshot_recovery_response.proto
  64. 456 9
      third_party/github.com/coreos/raft/protobuf/snapshot_request.pb.go
  65. 15 1
      third_party/github.com/coreos/raft/protobuf/snapshot_request.proto
  66. 360 7
      third_party/github.com/coreos/raft/protobuf/snapshot_response.pb.go
  67. 15 1
      third_party/github.com/coreos/raft/protobuf/snapshot_response.proto
  68. 5 4
      third_party/github.com/coreos/raft/request_vote_request.go
  69. 5 4
      third_party/github.com/coreos/raft/request_vote_response.go
  70. 93 119
      third_party/github.com/coreos/raft/server.go
  71. 36 29
      third_party/github.com/coreos/raft/server_test.go
  72. 22 25
      third_party/github.com/coreos/raft/snapshot.go
  73. 7 12
      third_party/github.com/coreos/raft/snapshot_recovery_request.go
  74. 8 14
      third_party/github.com/coreos/raft/snapshot_recovery_response.go
  75. 5 10
      third_party/github.com/coreos/raft/snapshot_request.go
  76. 5 10
      third_party/github.com/coreos/raft/snapshot_response.go
  77. 73 0
      third_party/github.com/coreos/raft/snapshot_test.go
  78. 0 6
      third_party/github.com/coreos/raft/statemachine.go
  79. 19 0
      third_party/github.com/coreos/raft/statemachine_test.go
  80. 3 3
      third_party/github.com/coreos/raft/test.go

+ 1 - 1
etcd.go

@@ -158,7 +158,7 @@ func main() {
 		log.Fatal(err)
 	}
 	raftServer.SetElectionTimeout(electionTimeout)
-	raftServer.SetHeartbeatTimeout(heartbeatTimeout)
+	raftServer.SetHeartbeatInterval(heartbeatTimeout)
 	ps.SetRaftServer(raftServer)
 
 	// Create etcd server

+ 2 - 2
server/peer_server.go

@@ -91,7 +91,7 @@ func (s *PeerServer) SetRaftServer(raftServer raft.Server) {
 	raftServer.AddEventListener(raft.TermChangeEventType, s.raftEventLogger)
 	raftServer.AddEventListener(raft.AddPeerEventType, s.raftEventLogger)
 	raftServer.AddEventListener(raft.RemovePeerEventType, s.raftEventLogger)
-	raftServer.AddEventListener(raft.HeartbeatTimeoutEventType, s.raftEventLogger)
+	raftServer.AddEventListener(raft.HeartbeatIntervalEventType, s.raftEventLogger)
 	raftServer.AddEventListener(raft.ElectionTimeoutThresholdEventType, s.raftEventLogger)
 
 	raftServer.AddEventListener(raft.HeartbeatEventType, s.recordMetricEvent)
@@ -392,7 +392,7 @@ func (s *PeerServer) raftEventLogger(event raft.Event) {
 		log.Infof("%s: peer added: '%v'", s.Config.Name, value)
 	case raft.RemovePeerEventType:
 		log.Infof("%s: peer removed: '%v'", s.Config.Name, value)
-	case raft.HeartbeatTimeoutEventType:
+	case raft.HeartbeatIntervalEventType:
 		var name = "<unknown>"
 		if peer, ok := value.(*raft.Peer); ok {
 			name = peer.Name

+ 1 - 1
server/peer_server_handlers.go

@@ -73,7 +73,7 @@ func (ps *PeerServer) AppendEntriesHttpHandler(w http.ResponseWriter, req *http.
 		return
 	}
 
-	if !resp.Success {
+	if !resp.Success() {
 		log.Debugf("[Append Entry] Step back")
 	}
 

+ 1 - 1
tests/server_utils.go

@@ -59,7 +59,7 @@ func RunServer(f func(*server.Server)) {
 		panic(err)
 	}
 	raftServer.SetElectionTimeout(testElectionTimeout)
-	raftServer.SetHeartbeatTimeout(testHeartbeatTimeout)
+	raftServer.SetHeartbeatInterval(testHeartbeatTimeout)
 	ps.SetRaftServer(raftServer)
 
 	s := server.New(testName, "http://"+testClientURL, ps, registry, store, nil)

+ 40 - 0
third_party/code.google.com/p/gogoprotobuf/proto/Makefile

@@ -0,0 +1,40 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 The Go Authors.  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.
+
+install:
+	go install
+
+test: install generate-test-pbs
+	go test
+
+
+generate-test-pbs:
+	make install && cd testdata && make

+ 1893 - 0
third_party/code.google.com/p/gogoprotobuf/proto/all_test.go

@@ -0,0 +1,1893 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+package proto_test
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"math"
+	"math/rand"
+	"reflect"
+	"runtime/debug"
+	"strings"
+	"testing"
+	"time"
+
+	. "./testdata"
+	. "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+)
+
+var globalO *Buffer
+
+func old() *Buffer {
+	if globalO == nil {
+		globalO = NewBuffer(nil)
+	}
+	globalO.Reset()
+	return globalO
+}
+
+func equalbytes(b1, b2 []byte, t *testing.T) {
+	if len(b1) != len(b2) {
+		t.Errorf("wrong lengths: 2*%d != %d", len(b1), len(b2))
+		return
+	}
+	for i := 0; i < len(b1); i++ {
+		if b1[i] != b2[i] {
+			t.Errorf("bad byte[%d]:%x %x: %s %s", i, b1[i], b2[i], b1, b2)
+		}
+	}
+}
+
+func initGoTestField() *GoTestField {
+	f := new(GoTestField)
+	f.Label = String("label")
+	f.Type = String("type")
+	return f
+}
+
+// These are all structurally equivalent but the tag numbers differ.
+// (It's remarkable that required, optional, and repeated all have
+// 8 letters.)
+func initGoTest_RequiredGroup() *GoTest_RequiredGroup {
+	return &GoTest_RequiredGroup{
+		RequiredField: String("required"),
+	}
+}
+
+func initGoTest_OptionalGroup() *GoTest_OptionalGroup {
+	return &GoTest_OptionalGroup{
+		RequiredField: String("optional"),
+	}
+}
+
+func initGoTest_RepeatedGroup() *GoTest_RepeatedGroup {
+	return &GoTest_RepeatedGroup{
+		RequiredField: String("repeated"),
+	}
+}
+
+func initGoTest(setdefaults bool) *GoTest {
+	pb := new(GoTest)
+	if setdefaults {
+		pb.F_BoolDefaulted = Bool(Default_GoTest_F_BoolDefaulted)
+		pb.F_Int32Defaulted = Int32(Default_GoTest_F_Int32Defaulted)
+		pb.F_Int64Defaulted = Int64(Default_GoTest_F_Int64Defaulted)
+		pb.F_Fixed32Defaulted = Uint32(Default_GoTest_F_Fixed32Defaulted)
+		pb.F_Fixed64Defaulted = Uint64(Default_GoTest_F_Fixed64Defaulted)
+		pb.F_Uint32Defaulted = Uint32(Default_GoTest_F_Uint32Defaulted)
+		pb.F_Uint64Defaulted = Uint64(Default_GoTest_F_Uint64Defaulted)
+		pb.F_FloatDefaulted = Float32(Default_GoTest_F_FloatDefaulted)
+		pb.F_DoubleDefaulted = Float64(Default_GoTest_F_DoubleDefaulted)
+		pb.F_StringDefaulted = String(Default_GoTest_F_StringDefaulted)
+		pb.F_BytesDefaulted = Default_GoTest_F_BytesDefaulted
+		pb.F_Sint32Defaulted = Int32(Default_GoTest_F_Sint32Defaulted)
+		pb.F_Sint64Defaulted = Int64(Default_GoTest_F_Sint64Defaulted)
+	}
+
+	pb.Kind = GoTest_TIME.Enum()
+	pb.RequiredField = initGoTestField()
+	pb.F_BoolRequired = Bool(true)
+	pb.F_Int32Required = Int32(3)
+	pb.F_Int64Required = Int64(6)
+	pb.F_Fixed32Required = Uint32(32)
+	pb.F_Fixed64Required = Uint64(64)
+	pb.F_Uint32Required = Uint32(3232)
+	pb.F_Uint64Required = Uint64(6464)
+	pb.F_FloatRequired = Float32(3232)
+	pb.F_DoubleRequired = Float64(6464)
+	pb.F_StringRequired = String("string")
+	pb.F_BytesRequired = []byte("bytes")
+	pb.F_Sint32Required = Int32(-32)
+	pb.F_Sint64Required = Int64(-64)
+	pb.Requiredgroup = initGoTest_RequiredGroup()
+
+	return pb
+}
+
+func fail(msg string, b *bytes.Buffer, s string, t *testing.T) {
+	data := b.Bytes()
+	ld := len(data)
+	ls := len(s) / 2
+
+	fmt.Printf("fail %s ld=%d ls=%d\n", msg, ld, ls)
+
+	// find the interesting spot - n
+	n := ls
+	if ld < ls {
+		n = ld
+	}
+	j := 0
+	for i := 0; i < n; i++ {
+		bs := hex(s[j])*16 + hex(s[j+1])
+		j += 2
+		if data[i] == bs {
+			continue
+		}
+		n = i
+		break
+	}
+	l := n - 10
+	if l < 0 {
+		l = 0
+	}
+	h := n + 10
+
+	// find the interesting spot - n
+	fmt.Printf("is[%d]:", l)
+	for i := l; i < h; i++ {
+		if i >= ld {
+			fmt.Printf(" --")
+			continue
+		}
+		fmt.Printf(" %.2x", data[i])
+	}
+	fmt.Printf("\n")
+
+	fmt.Printf("sb[%d]:", l)
+	for i := l; i < h; i++ {
+		if i >= ls {
+			fmt.Printf(" --")
+			continue
+		}
+		bs := hex(s[j])*16 + hex(s[j+1])
+		j += 2
+		fmt.Printf(" %.2x", bs)
+	}
+	fmt.Printf("\n")
+
+	t.Fail()
+
+	//	t.Errorf("%s: \ngood: %s\nbad: %x", msg, s, b.Bytes())
+	// Print the output in a partially-decoded format; can
+	// be helpful when updating the test.  It produces the output
+	// that is pasted, with minor edits, into the argument to verify().
+	//	data := b.Bytes()
+	//	nesting := 0
+	//	for b.Len() > 0 {
+	//		start := len(data) - b.Len()
+	//		var u uint64
+	//		u, err := DecodeVarint(b)
+	//		if err != nil {
+	//			fmt.Printf("decode error on varint:", err)
+	//			return
+	//		}
+	//		wire := u & 0x7
+	//		tag := u >> 3
+	//		switch wire {
+	//		case WireVarint:
+	//			v, err := DecodeVarint(b)
+	//			if err != nil {
+	//				fmt.Printf("decode error on varint:", err)
+	//				return
+	//			}
+	//			fmt.Printf("\t\t\"%x\"  // field %d, encoding %d, value %d\n",
+	//				data[start:len(data)-b.Len()], tag, wire, v)
+	//		case WireFixed32:
+	//			v, err := DecodeFixed32(b)
+	//			if err != nil {
+	//				fmt.Printf("decode error on fixed32:", err)
+	//				return
+	//			}
+	//			fmt.Printf("\t\t\"%x\"  // field %d, encoding %d, value %d\n",
+	//				data[start:len(data)-b.Len()], tag, wire, v)
+	//		case WireFixed64:
+	//			v, err := DecodeFixed64(b)
+	//			if err != nil {
+	//				fmt.Printf("decode error on fixed64:", err)
+	//				return
+	//			}
+	//			fmt.Printf("\t\t\"%x\"  // field %d, encoding %d, value %d\n",
+	//				data[start:len(data)-b.Len()], tag, wire, v)
+	//		case WireBytes:
+	//			nb, err := DecodeVarint(b)
+	//			if err != nil {
+	//				fmt.Printf("decode error on bytes:", err)
+	//				return
+	//			}
+	//			after_tag := len(data) - b.Len()
+	//			str := make([]byte, nb)
+	//			_, err = b.Read(str)
+	//			if err != nil {
+	//				fmt.Printf("decode error on bytes:", err)
+	//				return
+	//			}
+	//			fmt.Printf("\t\t\"%x\" \"%x\"  // field %d, encoding %d (FIELD)\n",
+	//				data[start:after_tag], str, tag, wire)
+	//		case WireStartGroup:
+	//			nesting++
+	//			fmt.Printf("\t\t\"%x\"\t\t// start group field %d level %d\n",
+	//				data[start:len(data)-b.Len()], tag, nesting)
+	//		case WireEndGroup:
+	//			fmt.Printf("\t\t\"%x\"\t\t// end group field %d level %d\n",
+	//				data[start:len(data)-b.Len()], tag, nesting)
+	//			nesting--
+	//		default:
+	//			fmt.Printf("unrecognized wire type %d\n", wire)
+	//			return
+	//		}
+	//	}
+}
+
+func hex(c uint8) uint8 {
+	if '0' <= c && c <= '9' {
+		return c - '0'
+	}
+	if 'a' <= c && c <= 'f' {
+		return 10 + c - 'a'
+	}
+	if 'A' <= c && c <= 'F' {
+		return 10 + c - 'A'
+	}
+	return 0
+}
+
+func equal(b []byte, s string, t *testing.T) bool {
+	if 2*len(b) != len(s) {
+		//		fail(fmt.Sprintf("wrong lengths: 2*%d != %d", len(b), len(s)), b, s, t)
+		fmt.Printf("wrong lengths: 2*%d != %d\n", len(b), len(s))
+		return false
+	}
+	for i, j := 0, 0; i < len(b); i, j = i+1, j+2 {
+		x := hex(s[j])*16 + hex(s[j+1])
+		if b[i] != x {
+			//			fail(fmt.Sprintf("bad byte[%d]:%x %x", i, b[i], x), b, s, t)
+			fmt.Printf("bad byte[%d]:%x %x", i, b[i], x)
+			return false
+		}
+	}
+	return true
+}
+
+func overify(t *testing.T, pb *GoTest, expected string) {
+	o := old()
+	err := o.Marshal(pb)
+	if err != nil {
+		fmt.Printf("overify marshal-1 err = %v", err)
+		o.DebugPrint("", o.Bytes())
+		t.Fatalf("expected = %s", expected)
+	}
+	if !equal(o.Bytes(), expected, t) {
+		o.DebugPrint("overify neq 1", o.Bytes())
+		t.Fatalf("expected = %s", expected)
+	}
+
+	// Now test Unmarshal by recreating the original buffer.
+	pbd := new(GoTest)
+	err = o.Unmarshal(pbd)
+	if err != nil {
+		t.Fatalf("overify unmarshal err = %v", err)
+		o.DebugPrint("", o.Bytes())
+		t.Fatalf("string = %s", expected)
+	}
+	o.Reset()
+	err = o.Marshal(pbd)
+	if err != nil {
+		t.Errorf("overify marshal-2 err = %v", err)
+		o.DebugPrint("", o.Bytes())
+		t.Fatalf("string = %s", expected)
+	}
+	if !equal(o.Bytes(), expected, t) {
+		o.DebugPrint("overify neq 2", o.Bytes())
+		t.Fatalf("string = %s", expected)
+	}
+}
+
+// Simple tests for numeric encode/decode primitives (varint, etc.)
+func TestNumericPrimitives(t *testing.T) {
+	for i := uint64(0); i < 1e6; i += 111 {
+		o := old()
+		if o.EncodeVarint(i) != nil {
+			t.Error("EncodeVarint")
+			break
+		}
+		x, e := o.DecodeVarint()
+		if e != nil {
+			t.Fatal("DecodeVarint")
+		}
+		if x != i {
+			t.Fatal("varint decode fail:", i, x)
+		}
+
+		o = old()
+		if o.EncodeFixed32(i) != nil {
+			t.Fatal("encFixed32")
+		}
+		x, e = o.DecodeFixed32()
+		if e != nil {
+			t.Fatal("decFixed32")
+		}
+		if x != i {
+			t.Fatal("fixed32 decode fail:", i, x)
+		}
+
+		o = old()
+		if o.EncodeFixed64(i*1234567) != nil {
+			t.Error("encFixed64")
+			break
+		}
+		x, e = o.DecodeFixed64()
+		if e != nil {
+			t.Error("decFixed64")
+			break
+		}
+		if x != i*1234567 {
+			t.Error("fixed64 decode fail:", i*1234567, x)
+			break
+		}
+
+		o = old()
+		i32 := int32(i - 12345)
+		if o.EncodeZigzag32(uint64(i32)) != nil {
+			t.Fatal("EncodeZigzag32")
+		}
+		x, e = o.DecodeZigzag32()
+		if e != nil {
+			t.Fatal("DecodeZigzag32")
+		}
+		if x != uint64(uint32(i32)) {
+			t.Fatal("zigzag32 decode fail:", i32, x)
+		}
+
+		o = old()
+		i64 := int64(i - 12345)
+		if o.EncodeZigzag64(uint64(i64)) != nil {
+			t.Fatal("EncodeZigzag64")
+		}
+		x, e = o.DecodeZigzag64()
+		if e != nil {
+			t.Fatal("DecodeZigzag64")
+		}
+		if x != uint64(i64) {
+			t.Fatal("zigzag64 decode fail:", i64, x)
+		}
+	}
+}
+
+// Simple tests for bytes
+func TestBytesPrimitives(t *testing.T) {
+	o := old()
+	bytes := []byte{'n', 'o', 'w', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 't', 'i', 'm', 'e'}
+	if o.EncodeRawBytes(bytes) != nil {
+		t.Error("EncodeRawBytes")
+	}
+	decb, e := o.DecodeRawBytes(false)
+	if e != nil {
+		t.Error("DecodeRawBytes")
+	}
+	equalbytes(bytes, decb, t)
+}
+
+// Simple tests for strings
+func TestStringPrimitives(t *testing.T) {
+	o := old()
+	s := "now is the time"
+	if o.EncodeStringBytes(s) != nil {
+		t.Error("enc_string")
+	}
+	decs, e := o.DecodeStringBytes()
+	if e != nil {
+		t.Error("dec_string")
+	}
+	if s != decs {
+		t.Error("string encode/decode fail:", s, decs)
+	}
+}
+
+// Do we catch the "required bit not set" case?
+func TestRequiredBit(t *testing.T) {
+	o := old()
+	pb := new(GoTest)
+	err := o.Marshal(pb)
+	if err == nil {
+		t.Error("did not catch missing required fields")
+	} else if strings.Index(err.Error(), "Kind") < 0 {
+		t.Error("wrong error type:", err)
+	}
+}
+
+// Check that all fields are nil.
+// Clearly silly, and a residue from a more interesting test with an earlier,
+// different initialization property, but it once caught a compiler bug so
+// it lives.
+func checkInitialized(pb *GoTest, t *testing.T) {
+	if pb.F_BoolDefaulted != nil {
+		t.Error("New or Reset did not set boolean:", *pb.F_BoolDefaulted)
+	}
+	if pb.F_Int32Defaulted != nil {
+		t.Error("New or Reset did not set int32:", *pb.F_Int32Defaulted)
+	}
+	if pb.F_Int64Defaulted != nil {
+		t.Error("New or Reset did not set int64:", *pb.F_Int64Defaulted)
+	}
+	if pb.F_Fixed32Defaulted != nil {
+		t.Error("New or Reset did not set fixed32:", *pb.F_Fixed32Defaulted)
+	}
+	if pb.F_Fixed64Defaulted != nil {
+		t.Error("New or Reset did not set fixed64:", *pb.F_Fixed64Defaulted)
+	}
+	if pb.F_Uint32Defaulted != nil {
+		t.Error("New or Reset did not set uint32:", *pb.F_Uint32Defaulted)
+	}
+	if pb.F_Uint64Defaulted != nil {
+		t.Error("New or Reset did not set uint64:", *pb.F_Uint64Defaulted)
+	}
+	if pb.F_FloatDefaulted != nil {
+		t.Error("New or Reset did not set float:", *pb.F_FloatDefaulted)
+	}
+	if pb.F_DoubleDefaulted != nil {
+		t.Error("New or Reset did not set double:", *pb.F_DoubleDefaulted)
+	}
+	if pb.F_StringDefaulted != nil {
+		t.Error("New or Reset did not set string:", *pb.F_StringDefaulted)
+	}
+	if pb.F_BytesDefaulted != nil {
+		t.Error("New or Reset did not set bytes:", string(pb.F_BytesDefaulted))
+	}
+	if pb.F_Sint32Defaulted != nil {
+		t.Error("New or Reset did not set int32:", *pb.F_Sint32Defaulted)
+	}
+	if pb.F_Sint64Defaulted != nil {
+		t.Error("New or Reset did not set int64:", *pb.F_Sint64Defaulted)
+	}
+}
+
+// Does Reset() reset?
+func TestReset(t *testing.T) {
+	pb := initGoTest(true)
+	// muck with some values
+	pb.F_BoolDefaulted = Bool(false)
+	pb.F_Int32Defaulted = Int32(237)
+	pb.F_Int64Defaulted = Int64(12346)
+	pb.F_Fixed32Defaulted = Uint32(32000)
+	pb.F_Fixed64Defaulted = Uint64(666)
+	pb.F_Uint32Defaulted = Uint32(323232)
+	pb.F_Uint64Defaulted = nil
+	pb.F_FloatDefaulted = nil
+	pb.F_DoubleDefaulted = Float64(0)
+	pb.F_StringDefaulted = String("gotcha")
+	pb.F_BytesDefaulted = []byte("asdfasdf")
+	pb.F_Sint32Defaulted = Int32(123)
+	pb.F_Sint64Defaulted = Int64(789)
+	pb.Reset()
+	checkInitialized(pb, t)
+}
+
+// All required fields set, no defaults provided.
+func TestEncodeDecode1(t *testing.T) {
+	pb := initGoTest(false)
+	overify(t, pb,
+		"0807"+	// field 1, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+	// field 4, encoding 2 (GoTestField)
+			"5001"+	// field 10, encoding 0, value 1
+			"5803"+	// field 11, encoding 0, value 3
+			"6006"+	// field 12, encoding 0, value 6
+			"6d20000000"+	// field 13, encoding 5, value 0x20
+			"714000000000000000"+	// field 14, encoding 1, value 0x40
+			"78a019"+	// field 15, encoding 0, value 0xca0 = 3232
+			"8001c032"+	// field 16, encoding 0, value 0x1940 = 6464
+			"8d0100004a45"+	// field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+	// field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+	// field 19, encoding 2, string "string"
+			"b304"+	// field 70, encoding 3, start group
+			"ba0408"+"7265717569726564"+	// field 71, encoding 2, string "required"
+			"b404"+	// field 70, encoding 4, end group
+			"aa0605"+"6279746573"+	// field 101, encoding 2, string "bytes"
+			"b0063f"+	// field 102, encoding 0, 0x3f zigzag32
+			"b8067f")	// field 103, encoding 0, 0x7f zigzag64
+}
+
+// All required fields set, defaults provided.
+func TestEncodeDecode2(t *testing.T) {
+	pb := initGoTest(true)
+	overify(t, pb,
+		"0807"+	// field 1, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+	// field 4, encoding 2 (GoTestField)
+			"5001"+	// field 10, encoding 0, value 1
+			"5803"+	// field 11, encoding 0, value 3
+			"6006"+	// field 12, encoding 0, value 6
+			"6d20000000"+	// field 13, encoding 5, value 32
+			"714000000000000000"+	// field 14, encoding 1, value 64
+			"78a019"+	// field 15, encoding 0, value 3232
+			"8001c032"+	// field 16, encoding 0, value 6464
+			"8d0100004a45"+	// field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+	// field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+	// field 19, encoding 2 string "string"
+			"c00201"+	// field 40, encoding 0, value 1
+			"c80220"+	// field 41, encoding 0, value 32
+			"d00240"+	// field 42, encoding 0, value 64
+			"dd0240010000"+	// field 43, encoding 5, value 320
+			"e1028002000000000000"+	// field 44, encoding 1, value 640
+			"e8028019"+	// field 45, encoding 0, value 3200
+			"f0028032"+	// field 46, encoding 0, value 6400
+			"fd02e0659948"+	// field 47, encoding 5, value 314159.0
+			"81030000000050971041"+	// field 48, encoding 1, value 271828.0
+			"8a0310"+"68656c6c6f2c2022776f726c6421220a"+	// field 49, encoding 2 string "hello, \"world!\"\n"
+			"b304"+	// start group field 70 level 1
+			"ba0408"+"7265717569726564"+	// field 71, encoding 2, string "required"
+			"b404"+	// end group field 70 level 1
+			"aa0605"+"6279746573"+	// field 101, encoding 2 string "bytes"
+			"b0063f"+	// field 102, encoding 0, 0x3f zigzag32
+			"b8067f"+	// field 103, encoding 0, 0x7f zigzag64
+			"8a1907"+"4269676e6f7365"+	// field 401, encoding 2, string "Bignose"
+			"90193f"+	// field 402, encoding 0, value 63
+			"98197f")	// field 403, encoding 0, value 127
+
+}
+
+// All default fields set to their default value by hand
+func TestEncodeDecode3(t *testing.T) {
+	pb := initGoTest(false)
+	pb.F_BoolDefaulted = Bool(true)
+	pb.F_Int32Defaulted = Int32(32)
+	pb.F_Int64Defaulted = Int64(64)
+	pb.F_Fixed32Defaulted = Uint32(320)
+	pb.F_Fixed64Defaulted = Uint64(640)
+	pb.F_Uint32Defaulted = Uint32(3200)
+	pb.F_Uint64Defaulted = Uint64(6400)
+	pb.F_FloatDefaulted = Float32(314159)
+	pb.F_DoubleDefaulted = Float64(271828)
+	pb.F_StringDefaulted = String("hello, \"world!\"\n")
+	pb.F_BytesDefaulted = []byte("Bignose")
+	pb.F_Sint32Defaulted = Int32(-32)
+	pb.F_Sint64Defaulted = Int64(-64)
+
+	overify(t, pb,
+		"0807"+	// field 1, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+	// field 4, encoding 2 (GoTestField)
+			"5001"+	// field 10, encoding 0, value 1
+			"5803"+	// field 11, encoding 0, value 3
+			"6006"+	// field 12, encoding 0, value 6
+			"6d20000000"+	// field 13, encoding 5, value 32
+			"714000000000000000"+	// field 14, encoding 1, value 64
+			"78a019"+	// field 15, encoding 0, value 3232
+			"8001c032"+	// field 16, encoding 0, value 6464
+			"8d0100004a45"+	// field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+	// field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+	// field 19, encoding 2 string "string"
+			"c00201"+	// field 40, encoding 0, value 1
+			"c80220"+	// field 41, encoding 0, value 32
+			"d00240"+	// field 42, encoding 0, value 64
+			"dd0240010000"+	// field 43, encoding 5, value 320
+			"e1028002000000000000"+	// field 44, encoding 1, value 640
+			"e8028019"+	// field 45, encoding 0, value 3200
+			"f0028032"+	// field 46, encoding 0, value 6400
+			"fd02e0659948"+	// field 47, encoding 5, value 314159.0
+			"81030000000050971041"+	// field 48, encoding 1, value 271828.0
+			"8a0310"+"68656c6c6f2c2022776f726c6421220a"+	// field 49, encoding 2 string "hello, \"world!\"\n"
+			"b304"+	// start group field 70 level 1
+			"ba0408"+"7265717569726564"+	// field 71, encoding 2, string "required"
+			"b404"+	// end group field 70 level 1
+			"aa0605"+"6279746573"+	// field 101, encoding 2 string "bytes"
+			"b0063f"+	// field 102, encoding 0, 0x3f zigzag32
+			"b8067f"+	// field 103, encoding 0, 0x7f zigzag64
+			"8a1907"+"4269676e6f7365"+	// field 401, encoding 2, string "Bignose"
+			"90193f"+	// field 402, encoding 0, value 63
+			"98197f")	// field 403, encoding 0, value 127
+
+}
+
+// All required fields set, defaults provided, all non-defaulted optional fields have values.
+func TestEncodeDecode4(t *testing.T) {
+	pb := initGoTest(true)
+	pb.Table = String("hello")
+	pb.Param = Int32(7)
+	pb.OptionalField = initGoTestField()
+	pb.F_BoolOptional = Bool(true)
+	pb.F_Int32Optional = Int32(32)
+	pb.F_Int64Optional = Int64(64)
+	pb.F_Fixed32Optional = Uint32(3232)
+	pb.F_Fixed64Optional = Uint64(6464)
+	pb.F_Uint32Optional = Uint32(323232)
+	pb.F_Uint64Optional = Uint64(646464)
+	pb.F_FloatOptional = Float32(32.)
+	pb.F_DoubleOptional = Float64(64.)
+	pb.F_StringOptional = String("hello")
+	pb.F_BytesOptional = []byte("Bignose")
+	pb.F_Sint32Optional = Int32(-32)
+	pb.F_Sint64Optional = Int64(-64)
+	pb.Optionalgroup = initGoTest_OptionalGroup()
+
+	overify(t, pb,
+		"0807"+	// field 1, encoding 0, value 7
+			"1205"+"68656c6c6f"+	// field 2, encoding 2, string "hello"
+			"1807"+	// field 3, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+	// field 4, encoding 2 (GoTestField)
+			"320d"+"0a056c6162656c120474797065"+	// field 6, encoding 2 (GoTestField)
+			"5001"+	// field 10, encoding 0, value 1
+			"5803"+	// field 11, encoding 0, value 3
+			"6006"+	// field 12, encoding 0, value 6
+			"6d20000000"+	// field 13, encoding 5, value 32
+			"714000000000000000"+	// field 14, encoding 1, value 64
+			"78a019"+	// field 15, encoding 0, value 3232
+			"8001c032"+	// field 16, encoding 0, value 6464
+			"8d0100004a45"+	// field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+	// field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+	// field 19, encoding 2 string "string"
+			"f00101"+	// field 30, encoding 0, value 1
+			"f80120"+	// field 31, encoding 0, value 32
+			"800240"+	// field 32, encoding 0, value 64
+			"8d02a00c0000"+	// field 33, encoding 5, value 3232
+			"91024019000000000000"+	// field 34, encoding 1, value 6464
+			"9802a0dd13"+	// field 35, encoding 0, value 323232
+			"a002c0ba27"+	// field 36, encoding 0, value 646464
+			"ad0200000042"+	// field 37, encoding 5, value 32.0
+			"b1020000000000005040"+	// field 38, encoding 1, value 64.0
+			"ba0205"+"68656c6c6f"+	// field 39, encoding 2, string "hello"
+			"c00201"+	// field 40, encoding 0, value 1
+			"c80220"+	// field 41, encoding 0, value 32
+			"d00240"+	// field 42, encoding 0, value 64
+			"dd0240010000"+	// field 43, encoding 5, value 320
+			"e1028002000000000000"+	// field 44, encoding 1, value 640
+			"e8028019"+	// field 45, encoding 0, value 3200
+			"f0028032"+	// field 46, encoding 0, value 6400
+			"fd02e0659948"+	// field 47, encoding 5, value 314159.0
+			"81030000000050971041"+	// field 48, encoding 1, value 271828.0
+			"8a0310"+"68656c6c6f2c2022776f726c6421220a"+	// field 49, encoding 2 string "hello, \"world!\"\n"
+			"b304"+	// start group field 70 level 1
+			"ba0408"+"7265717569726564"+	// field 71, encoding 2, string "required"
+			"b404"+	// end group field 70 level 1
+			"d305"+	// start group field 90 level 1
+			"da0508"+"6f7074696f6e616c"+	// field 91, encoding 2, string "optional"
+			"d405"+	// end group field 90 level 1
+			"aa0605"+"6279746573"+	// field 101, encoding 2 string "bytes"
+			"b0063f"+	// field 102, encoding 0, 0x3f zigzag32
+			"b8067f"+	// field 103, encoding 0, 0x7f zigzag64
+			"ea1207"+"4269676e6f7365"+	// field 301, encoding 2, string "Bignose"
+			"f0123f"+	// field 302, encoding 0, value 63
+			"f8127f"+	// field 303, encoding 0, value 127
+			"8a1907"+"4269676e6f7365"+	// field 401, encoding 2, string "Bignose"
+			"90193f"+	// field 402, encoding 0, value 63
+			"98197f")	// field 403, encoding 0, value 127
+
+}
+
+// All required fields set, defaults provided, all repeated fields given two values.
+func TestEncodeDecode5(t *testing.T) {
+	pb := initGoTest(true)
+	pb.RepeatedField = []*GoTestField{initGoTestField(), initGoTestField()}
+	pb.F_BoolRepeated = []bool{false, true}
+	pb.F_Int32Repeated = []int32{32, 33}
+	pb.F_Int64Repeated = []int64{64, 65}
+	pb.F_Fixed32Repeated = []uint32{3232, 3333}
+	pb.F_Fixed64Repeated = []uint64{6464, 6565}
+	pb.F_Uint32Repeated = []uint32{323232, 333333}
+	pb.F_Uint64Repeated = []uint64{646464, 656565}
+	pb.F_FloatRepeated = []float32{32., 33.}
+	pb.F_DoubleRepeated = []float64{64., 65.}
+	pb.F_StringRepeated = []string{"hello", "sailor"}
+	pb.F_BytesRepeated = [][]byte{[]byte("big"), []byte("nose")}
+	pb.F_Sint32Repeated = []int32{32, -32}
+	pb.F_Sint64Repeated = []int64{64, -64}
+	pb.Repeatedgroup = []*GoTest_RepeatedGroup{initGoTest_RepeatedGroup(), initGoTest_RepeatedGroup()}
+
+	overify(t, pb,
+		"0807"+	// field 1, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+	// field 4, encoding 2 (GoTestField)
+			"2a0d"+"0a056c6162656c120474797065"+	// field 5, encoding 2 (GoTestField)
+			"2a0d"+"0a056c6162656c120474797065"+	// field 5, encoding 2 (GoTestField)
+			"5001"+	// field 10, encoding 0, value 1
+			"5803"+	// field 11, encoding 0, value 3
+			"6006"+	// field 12, encoding 0, value 6
+			"6d20000000"+	// field 13, encoding 5, value 32
+			"714000000000000000"+	// field 14, encoding 1, value 64
+			"78a019"+	// field 15, encoding 0, value 3232
+			"8001c032"+	// field 16, encoding 0, value 6464
+			"8d0100004a45"+	// field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+	// field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+	// field 19, encoding 2 string "string"
+			"a00100"+	// field 20, encoding 0, value 0
+			"a00101"+	// field 20, encoding 0, value 1
+			"a80120"+	// field 21, encoding 0, value 32
+			"a80121"+	// field 21, encoding 0, value 33
+			"b00140"+	// field 22, encoding 0, value 64
+			"b00141"+	// field 22, encoding 0, value 65
+			"bd01a00c0000"+	// field 23, encoding 5, value 3232
+			"bd01050d0000"+	// field 23, encoding 5, value 3333
+			"c1014019000000000000"+	// field 24, encoding 1, value 6464
+			"c101a519000000000000"+	// field 24, encoding 1, value 6565
+			"c801a0dd13"+	// field 25, encoding 0, value 323232
+			"c80195ac14"+	// field 25, encoding 0, value 333333
+			"d001c0ba27"+	// field 26, encoding 0, value 646464
+			"d001b58928"+	// field 26, encoding 0, value 656565
+			"dd0100000042"+	// field 27, encoding 5, value 32.0
+			"dd0100000442"+	// field 27, encoding 5, value 33.0
+			"e1010000000000005040"+	// field 28, encoding 1, value 64.0
+			"e1010000000000405040"+	// field 28, encoding 1, value 65.0
+			"ea0105"+"68656c6c6f"+	// field 29, encoding 2, string "hello"
+			"ea0106"+"7361696c6f72"+	// field 29, encoding 2, string "sailor"
+			"c00201"+	// field 40, encoding 0, value 1
+			"c80220"+	// field 41, encoding 0, value 32
+			"d00240"+	// field 42, encoding 0, value 64
+			"dd0240010000"+	// field 43, encoding 5, value 320
+			"e1028002000000000000"+	// field 44, encoding 1, value 640
+			"e8028019"+	// field 45, encoding 0, value 3200
+			"f0028032"+	// field 46, encoding 0, value 6400
+			"fd02e0659948"+	// field 47, encoding 5, value 314159.0
+			"81030000000050971041"+	// field 48, encoding 1, value 271828.0
+			"8a0310"+"68656c6c6f2c2022776f726c6421220a"+	// field 49, encoding 2 string "hello, \"world!\"\n"
+			"b304"+	// start group field 70 level 1
+			"ba0408"+"7265717569726564"+	// field 71, encoding 2, string "required"
+			"b404"+	// end group field 70 level 1
+			"8305"+	// start group field 80 level 1
+			"8a0508"+"7265706561746564"+	// field 81, encoding 2, string "repeated"
+			"8405"+	// end group field 80 level 1
+			"8305"+	// start group field 80 level 1
+			"8a0508"+"7265706561746564"+	// field 81, encoding 2, string "repeated"
+			"8405"+	// end group field 80 level 1
+			"aa0605"+"6279746573"+	// field 101, encoding 2 string "bytes"
+			"b0063f"+	// field 102, encoding 0, 0x3f zigzag32
+			"b8067f"+	// field 103, encoding 0, 0x7f zigzag64
+			"ca0c03"+"626967"+	// field 201, encoding 2, string "big"
+			"ca0c04"+"6e6f7365"+	// field 201, encoding 2, string "nose"
+			"d00c40"+	// field 202, encoding 0, value 32
+			"d00c3f"+	// field 202, encoding 0, value -32
+			"d80c8001"+	// field 203, encoding 0, value 64
+			"d80c7f"+	// field 203, encoding 0, value -64
+			"8a1907"+"4269676e6f7365"+	// field 401, encoding 2, string "Bignose"
+			"90193f"+	// field 402, encoding 0, value 63
+			"98197f")	// field 403, encoding 0, value 127
+
+}
+
+// All required fields set, all packed repeated fields given two values.
+func TestEncodeDecode6(t *testing.T) {
+	pb := initGoTest(false)
+	pb.F_BoolRepeatedPacked = []bool{false, true}
+	pb.F_Int32RepeatedPacked = []int32{32, 33}
+	pb.F_Int64RepeatedPacked = []int64{64, 65}
+	pb.F_Fixed32RepeatedPacked = []uint32{3232, 3333}
+	pb.F_Fixed64RepeatedPacked = []uint64{6464, 6565}
+	pb.F_Uint32RepeatedPacked = []uint32{323232, 333333}
+	pb.F_Uint64RepeatedPacked = []uint64{646464, 656565}
+	pb.F_FloatRepeatedPacked = []float32{32., 33.}
+	pb.F_DoubleRepeatedPacked = []float64{64., 65.}
+	pb.F_Sint32RepeatedPacked = []int32{32, -32}
+	pb.F_Sint64RepeatedPacked = []int64{64, -64}
+
+	overify(t, pb,
+		"0807"+	// field 1, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+	// field 4, encoding 2 (GoTestField)
+			"5001"+	// field 10, encoding 0, value 1
+			"5803"+	// field 11, encoding 0, value 3
+			"6006"+	// field 12, encoding 0, value 6
+			"6d20000000"+	// field 13, encoding 5, value 32
+			"714000000000000000"+	// field 14, encoding 1, value 64
+			"78a019"+	// field 15, encoding 0, value 3232
+			"8001c032"+	// field 16, encoding 0, value 6464
+			"8d0100004a45"+	// field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+	// field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+	// field 19, encoding 2 string "string"
+			"9203020001"+	// field 50, encoding 2, 2 bytes, value 0, value 1
+			"9a03022021"+	// field 51, encoding 2, 2 bytes, value 32, value 33
+			"a203024041"+	// field 52, encoding 2, 2 bytes, value 64, value 65
+			"aa0308"+	// field 53, encoding 2, 8 bytes
+			"a00c0000050d0000"+	// value 3232, value 3333
+			"b20310"+	// field 54, encoding 2, 16 bytes
+			"4019000000000000a519000000000000"+	// value 6464, value 6565
+			"ba0306"+	// field 55, encoding 2, 6 bytes
+			"a0dd1395ac14"+	// value 323232, value 333333
+			"c20306"+	// field 56, encoding 2, 6 bytes
+			"c0ba27b58928"+	// value 646464, value 656565
+			"ca0308"+	// field 57, encoding 2, 8 bytes
+			"0000004200000442"+	// value 32.0, value 33.0
+			"d20310"+	// field 58, encoding 2, 16 bytes
+			"00000000000050400000000000405040"+	// value 64.0, value 65.0
+			"b304"+	// start group field 70 level 1
+			"ba0408"+"7265717569726564"+	// field 71, encoding 2, string "required"
+			"b404"+	// end group field 70 level 1
+			"aa0605"+"6279746573"+	// field 101, encoding 2 string "bytes"
+			"b0063f"+	// field 102, encoding 0, 0x3f zigzag32
+			"b8067f"+	// field 103, encoding 0, 0x7f zigzag64
+			"b21f02"+	// field 502, encoding 2, 2 bytes
+			"403f"+	// value 32, value -32
+			"ba1f03"+	// field 503, encoding 2, 3 bytes
+			"80017f")	// value 64, value -64
+}
+
+// Test that we can encode empty bytes fields.
+func TestEncodeDecodeBytes1(t *testing.T) {
+	pb := initGoTest(false)
+
+	// Create our bytes
+	pb.F_BytesRequired = []byte{}
+	pb.F_BytesRepeated = [][]byte{{}}
+	pb.F_BytesOptional = []byte{}
+
+	d, err := Marshal(pb)
+	if err != nil {
+		t.Error(err)
+	}
+
+	pbd := new(GoTest)
+	if err := Unmarshal(d, pbd); err != nil {
+		t.Error(err)
+	}
+
+	if pbd.F_BytesRequired == nil || len(pbd.F_BytesRequired) != 0 {
+		t.Error("required empty bytes field is incorrect")
+	}
+	if pbd.F_BytesRepeated == nil || len(pbd.F_BytesRepeated) == 1 && pbd.F_BytesRepeated[0] == nil {
+		t.Error("repeated empty bytes field is incorrect")
+	}
+	if pbd.F_BytesOptional == nil || len(pbd.F_BytesOptional) != 0 {
+		t.Error("optional empty bytes field is incorrect")
+	}
+}
+
+// Test that we encode nil-valued fields of a repeated bytes field correctly.
+// Since entries in a repeated field cannot be nil, nil must mean empty value.
+func TestEncodeDecodeBytes2(t *testing.T) {
+	pb := initGoTest(false)
+
+	// Create our bytes
+	pb.F_BytesRepeated = [][]byte{nil}
+
+	d, err := Marshal(pb)
+	if err != nil {
+		t.Error(err)
+	}
+
+	pbd := new(GoTest)
+	if err := Unmarshal(d, pbd); err != nil {
+		t.Error(err)
+	}
+
+	if len(pbd.F_BytesRepeated) != 1 || pbd.F_BytesRepeated[0] == nil {
+		t.Error("Unexpected value for repeated bytes field")
+	}
+}
+
+// All required fields set, defaults provided, all repeated fields given two values.
+func TestSkippingUnrecognizedFields(t *testing.T) {
+	o := old()
+	pb := initGoTestField()
+
+	// Marshal it normally.
+	o.Marshal(pb)
+
+	// Now new a GoSkipTest record.
+	skip := &GoSkipTest{
+		SkipInt32:	Int32(32),
+		SkipFixed32:	Uint32(3232),
+		SkipFixed64:	Uint64(6464),
+		SkipString:	String("skipper"),
+		Skipgroup: &GoSkipTest_SkipGroup{
+			GroupInt32:	Int32(75),
+			GroupString:	String("wxyz"),
+		},
+	}
+
+	// Marshal it into same buffer.
+	o.Marshal(skip)
+
+	pbd := new(GoTestField)
+	o.Unmarshal(pbd)
+
+	// The __unrecognized field should be a marshaling of GoSkipTest
+	skipd := new(GoSkipTest)
+
+	o.SetBuf(pbd.XXX_unrecognized)
+	o.Unmarshal(skipd)
+
+	if *skipd.SkipInt32 != *skip.SkipInt32 {
+		t.Error("skip int32", skipd.SkipInt32)
+	}
+	if *skipd.SkipFixed32 != *skip.SkipFixed32 {
+		t.Error("skip fixed32", skipd.SkipFixed32)
+	}
+	if *skipd.SkipFixed64 != *skip.SkipFixed64 {
+		t.Error("skip fixed64", skipd.SkipFixed64)
+	}
+	if *skipd.SkipString != *skip.SkipString {
+		t.Error("skip string", *skipd.SkipString)
+	}
+	if *skipd.Skipgroup.GroupInt32 != *skip.Skipgroup.GroupInt32 {
+		t.Error("skip group int32", skipd.Skipgroup.GroupInt32)
+	}
+	if *skipd.Skipgroup.GroupString != *skip.Skipgroup.GroupString {
+		t.Error("skip group string", *skipd.Skipgroup.GroupString)
+	}
+}
+
+// Check that unrecognized fields of a submessage are preserved.
+func TestSubmessageUnrecognizedFields(t *testing.T) {
+	nm := &NewMessage{
+		Nested: &NewMessage_Nested{
+			Name:		String("Nigel"),
+			FoodGroup:	String("carbs"),
+		},
+	}
+	b, err := Marshal(nm)
+	if err != nil {
+		t.Fatalf("Marshal of NewMessage: %v", err)
+	}
+
+	// Unmarshal into an OldMessage.
+	om := new(OldMessage)
+	if err := Unmarshal(b, om); err != nil {
+		t.Fatalf("Unmarshal to OldMessage: %v", err)
+	}
+	exp := &OldMessage{
+		Nested: &OldMessage_Nested{
+			Name:	String("Nigel"),
+			// normal protocol buffer users should not do this
+			XXX_unrecognized:	[]byte("\x12\x05carbs"),
+		},
+	}
+	if !Equal(om, exp) {
+		t.Errorf("om = %v, want %v", om, exp)
+	}
+
+	// Clone the OldMessage.
+	om = Clone(om).(*OldMessage)
+	if !Equal(om, exp) {
+		t.Errorf("Clone(om) = %v, want %v", om, exp)
+	}
+
+	// Marshal the OldMessage, then unmarshal it into an empty NewMessage.
+	if b, err = Marshal(om); err != nil {
+		t.Fatalf("Marshal of OldMessage: %v", err)
+	}
+	t.Logf("Marshal(%v) -> %q", om, b)
+	nm2 := new(NewMessage)
+	if err := Unmarshal(b, nm2); err != nil {
+		t.Fatalf("Unmarshal to NewMessage: %v", err)
+	}
+	if !Equal(nm, nm2) {
+		t.Errorf("NewMessage round-trip: %v => %v", nm, nm2)
+	}
+}
+
+// Check that we can grow an array (repeated field) to have many elements.
+// This test doesn't depend only on our encoding; for variety, it makes sure
+// we create, encode, and decode the correct contents explicitly.  It's therefore
+// a bit messier.
+// This test also uses (and hence tests) the Marshal/Unmarshal functions
+// instead of the methods.
+func TestBigRepeated(t *testing.T) {
+	pb := initGoTest(true)
+
+	// Create the arrays
+	const N = 50	// Internally the library starts much smaller.
+	pb.Repeatedgroup = make([]*GoTest_RepeatedGroup, N)
+	pb.F_Sint64Repeated = make([]int64, N)
+	pb.F_Sint32Repeated = make([]int32, N)
+	pb.F_BytesRepeated = make([][]byte, N)
+	pb.F_StringRepeated = make([]string, N)
+	pb.F_DoubleRepeated = make([]float64, N)
+	pb.F_FloatRepeated = make([]float32, N)
+	pb.F_Uint64Repeated = make([]uint64, N)
+	pb.F_Uint32Repeated = make([]uint32, N)
+	pb.F_Fixed64Repeated = make([]uint64, N)
+	pb.F_Fixed32Repeated = make([]uint32, N)
+	pb.F_Int64Repeated = make([]int64, N)
+	pb.F_Int32Repeated = make([]int32, N)
+	pb.F_BoolRepeated = make([]bool, N)
+	pb.RepeatedField = make([]*GoTestField, N)
+
+	// Fill in the arrays with checkable values.
+	igtf := initGoTestField()
+	igtrg := initGoTest_RepeatedGroup()
+	for i := 0; i < N; i++ {
+		pb.Repeatedgroup[i] = igtrg
+		pb.F_Sint64Repeated[i] = int64(i)
+		pb.F_Sint32Repeated[i] = int32(i)
+		s := fmt.Sprint(i)
+		pb.F_BytesRepeated[i] = []byte(s)
+		pb.F_StringRepeated[i] = s
+		pb.F_DoubleRepeated[i] = float64(i)
+		pb.F_FloatRepeated[i] = float32(i)
+		pb.F_Uint64Repeated[i] = uint64(i)
+		pb.F_Uint32Repeated[i] = uint32(i)
+		pb.F_Fixed64Repeated[i] = uint64(i)
+		pb.F_Fixed32Repeated[i] = uint32(i)
+		pb.F_Int64Repeated[i] = int64(i)
+		pb.F_Int32Repeated[i] = int32(i)
+		pb.F_BoolRepeated[i] = i%2 == 0
+		pb.RepeatedField[i] = igtf
+	}
+
+	// Marshal.
+	buf, _ := Marshal(pb)
+
+	// Now test Unmarshal by recreating the original buffer.
+	pbd := new(GoTest)
+	Unmarshal(buf, pbd)
+
+	// Check the checkable values
+	for i := uint64(0); i < N; i++ {
+		if pbd.Repeatedgroup[i] == nil {	// TODO: more checking?
+			t.Error("pbd.Repeatedgroup bad")
+		}
+		var x uint64
+		x = uint64(pbd.F_Sint64Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Sint64Repeated bad", x, i)
+		}
+		x = uint64(pbd.F_Sint32Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Sint32Repeated bad", x, i)
+		}
+		s := fmt.Sprint(i)
+		equalbytes(pbd.F_BytesRepeated[i], []byte(s), t)
+		if pbd.F_StringRepeated[i] != s {
+			t.Error("pbd.F_Sint32Repeated bad", pbd.F_StringRepeated[i], i)
+		}
+		x = uint64(pbd.F_DoubleRepeated[i])
+		if x != i {
+			t.Error("pbd.F_DoubleRepeated bad", x, i)
+		}
+		x = uint64(pbd.F_FloatRepeated[i])
+		if x != i {
+			t.Error("pbd.F_FloatRepeated bad", x, i)
+		}
+		x = pbd.F_Uint64Repeated[i]
+		if x != i {
+			t.Error("pbd.F_Uint64Repeated bad", x, i)
+		}
+		x = uint64(pbd.F_Uint32Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Uint32Repeated bad", x, i)
+		}
+		x = pbd.F_Fixed64Repeated[i]
+		if x != i {
+			t.Error("pbd.F_Fixed64Repeated bad", x, i)
+		}
+		x = uint64(pbd.F_Fixed32Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Fixed32Repeated bad", x, i)
+		}
+		x = uint64(pbd.F_Int64Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Int64Repeated bad", x, i)
+		}
+		x = uint64(pbd.F_Int32Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Int32Repeated bad", x, i)
+		}
+		if pbd.F_BoolRepeated[i] != (i%2 == 0) {
+			t.Error("pbd.F_BoolRepeated bad", x, i)
+		}
+		if pbd.RepeatedField[i] == nil {	// TODO: more checking?
+			t.Error("pbd.RepeatedField bad")
+		}
+	}
+}
+
+// Verify we give a useful message when decoding to the wrong structure type.
+func TestTypeMismatch(t *testing.T) {
+	pb1 := initGoTest(true)
+
+	// Marshal
+	o := old()
+	o.Marshal(pb1)
+
+	// Now Unmarshal it to the wrong type.
+	pb2 := initGoTestField()
+	err := o.Unmarshal(pb2)
+	switch err {
+	case ErrWrongType:
+		// fine
+	case nil:
+		t.Error("expected wrong type error, got no error")
+	default:
+		t.Error("expected wrong type error, got", err)
+	}
+}
+
+func encodeDecode(t *testing.T, in, out Message, msg string) {
+	buf, err := Marshal(in)
+	if err != nil {
+		t.Fatalf("failed marshaling %v: %v", msg, err)
+	}
+	if err := Unmarshal(buf, out); err != nil {
+		t.Fatalf("failed unmarshaling %v: %v", msg, err)
+	}
+}
+
+func TestPackedNonPackedDecoderSwitching(t *testing.T) {
+	np, p := new(NonPackedTest), new(PackedTest)
+
+	// non-packed -> packed
+	np.A = []int32{0, 1, 1, 2, 3, 5}
+	encodeDecode(t, np, p, "non-packed -> packed")
+	if !reflect.DeepEqual(np.A, p.B) {
+		t.Errorf("failed non-packed -> packed; np.A=%+v, p.B=%+v", np.A, p.B)
+	}
+
+	// packed -> non-packed
+	np.Reset()
+	p.B = []int32{3, 1, 4, 1, 5, 9}
+	encodeDecode(t, p, np, "packed -> non-packed")
+	if !reflect.DeepEqual(p.B, np.A) {
+		t.Errorf("failed packed -> non-packed; p.B=%+v, np.A=%+v", p.B, np.A)
+	}
+}
+
+func TestProto1RepeatedGroup(t *testing.T) {
+	pb := &MessageList{
+		Message: []*MessageList_Message{
+			{
+				Name:	String("blah"),
+				Count:	Int32(7),
+			},
+			// NOTE: pb.Message[1] is a nil
+			nil,
+		},
+	}
+
+	o := old()
+	if err := o.Marshal(pb); err != ErrRepeatedHasNil {
+		t.Fatalf("unexpected or no error when marshaling: %v", err)
+	}
+}
+
+// Test that enums work.  Checks for a bug introduced by making enums
+// named types instead of int32: newInt32FromUint64 would crash with
+// a type mismatch in reflect.PointTo.
+func TestEnum(t *testing.T) {
+	pb := new(GoEnum)
+	pb.Foo = FOO_FOO1.Enum()
+	o := old()
+	if err := o.Marshal(pb); err != nil {
+		t.Fatal("error encoding enum:", err)
+	}
+	pb1 := new(GoEnum)
+	if err := o.Unmarshal(pb1); err != nil {
+		t.Fatal("error decoding enum:", err)
+	}
+	if *pb1.Foo != FOO_FOO1 {
+		t.Error("expected 7 but got ", *pb1.Foo)
+	}
+}
+
+// Enum types have String methods. Check that enum fields can be printed.
+// We don't care what the value actually is, just as long as it doesn't crash.
+func TestPrintingNilEnumFields(t *testing.T) {
+	pb := new(GoEnum)
+	fmt.Sprintf("%+v", pb)
+}
+
+// Verify that absent required fields cause Marshal/Unmarshal to return errors.
+func TestRequiredFieldEnforcement(t *testing.T) {
+	pb := new(GoTestField)
+	_, err := Marshal(pb)
+	if err == nil {
+		t.Error("marshal: expected error, got nil")
+	} else if strings.Index(err.Error(), "Label") < 0 {
+		t.Errorf("marshal: bad error type: %v", err)
+	}
+
+	// A slightly sneaky, yet valid, proto. It encodes the same required field twice,
+	// so simply counting the required fields is insufficient.
+	// field 1, encoding 2, value "hi"
+	buf := []byte("\x0A\x02hi\x0A\x02hi")
+	err = Unmarshal(buf, pb)
+	if err == nil {
+		t.Error("unmarshal: expected error, got nil")
+	} else if strings.Index(err.Error(), "{Unknown}") < 0 {
+		t.Errorf("unmarshal: bad error type: %v", err)
+	}
+}
+
+func TestTypedNilMarshal(t *testing.T) {
+	// A typed nil should return ErrNil and not crash.
+	_, err := Marshal((*GoEnum)(nil))
+	if err != ErrNil {
+		t.Errorf("Marshal: got err %v, want ErrNil", err)
+	}
+}
+
+// A type that implements the Marshaler interface, but is not nillable.
+type nonNillableInt uint64
+
+func (nni nonNillableInt) Marshal() ([]byte, error) {
+	return EncodeVarint(uint64(nni)), nil
+}
+
+type NNIMessage struct {
+	nni nonNillableInt
+}
+
+func (*NNIMessage) Reset()		{}
+func (*NNIMessage) String() string	{ return "" }
+func (*NNIMessage) ProtoMessage()	{}
+
+// A type that implements the Marshaler interface and is nillable.
+type nillableMessage struct {
+	x uint64
+}
+
+func (nm *nillableMessage) Marshal() ([]byte, error) {
+	return EncodeVarint(nm.x), nil
+}
+
+type NMMessage struct {
+	nm *nillableMessage
+}
+
+func (*NMMessage) Reset()		{}
+func (*NMMessage) String() string	{ return "" }
+func (*NMMessage) ProtoMessage()	{}
+
+// Verify a type that uses the Marshaler interface, but has a nil pointer.
+func TestNilMarshaler(t *testing.T) {
+	// Try a struct with a Marshaler field that is nil.
+	// It should be directly marshable.
+	nmm := new(NMMessage)
+	if _, err := Marshal(nmm); err != nil {
+		t.Error("unexpected error marshaling nmm: ", err)
+	}
+
+	// Try a struct with a Marshaler field that is not nillable.
+	nnim := new(NNIMessage)
+	nnim.nni = 7
+	var _ Marshaler = nnim.nni	// verify it is truly a Marshaler
+	if _, err := Marshal(nnim); err != nil {
+		t.Error("unexpected error marshaling nnim: ", err)
+	}
+}
+
+func TestAllSetDefaults(t *testing.T) {
+	// Exercise SetDefaults with all scalar field types.
+	m := &Defaults{
+		// NaN != NaN, so override that here.
+		F_Nan: Float32(1.7),
+	}
+	expected := &Defaults{
+		F_Bool:		Bool(true),
+		F_Int32:	Int32(32),
+		F_Int64:	Int64(64),
+		F_Fixed32:	Uint32(320),
+		F_Fixed64:	Uint64(640),
+		F_Uint32:	Uint32(3200),
+		F_Uint64:	Uint64(6400),
+		F_Float:	Float32(314159),
+		F_Double:	Float64(271828),
+		F_String:	String(`hello, "world!"` + "\n"),
+		F_Bytes:	[]byte("Bignose"),
+		F_Sint32:	Int32(-32),
+		F_Sint64:	Int64(-64),
+		F_Enum:		Defaults_GREEN.Enum(),
+		F_Pinf:		Float32(float32(math.Inf(1))),
+		F_Ninf:		Float32(float32(math.Inf(-1))),
+		F_Nan:		Float32(1.7),
+	}
+	SetDefaults(m)
+	if !Equal(m, expected) {
+		t.Errorf(" got %v\nwant %v", m, expected)
+	}
+}
+
+func TestSetDefaultsWithSetField(t *testing.T) {
+	// Check that a set value is not overridden.
+	m := &Defaults{
+		F_Int32: Int32(12),
+	}
+	SetDefaults(m)
+	if v := m.GetF_Int32(); v != 12 {
+		t.Errorf("m.FInt32 = %v, want 12", v)
+	}
+}
+
+func TestSetDefaultsWithSubMessage(t *testing.T) {
+	m := &OtherMessage{
+		Key:	Int64(123),
+		Inner: &InnerMessage{
+			Host: String("gopher"),
+		},
+	}
+	expected := &OtherMessage{
+		Key:	Int64(123),
+		Inner: &InnerMessage{
+			Host:	String("gopher"),
+			Port:	Int32(4000),
+		},
+	}
+	SetDefaults(m)
+	if !Equal(m, expected) {
+		t.Errorf("\n got %v\nwant %v", m, expected)
+	}
+}
+
+func TestSetDefaultsWithRepeatedSubMessage(t *testing.T) {
+	m := &MyMessage{
+		RepInner: []*InnerMessage{{}},
+	}
+	expected := &MyMessage{
+		RepInner: []*InnerMessage{{
+			Port: Int32(4000),
+		}},
+	}
+	SetDefaults(m)
+	if !Equal(m, expected) {
+		t.Errorf("\n got %v\nwant %v", m, expected)
+	}
+}
+
+func TestMaximumTagNumber(t *testing.T) {
+	m := &MaxTag{
+		LastField: String("natural goat essence"),
+	}
+	buf, err := Marshal(m)
+	if err != nil {
+		t.Fatalf("proto.Marshal failed: %v", err)
+	}
+	m2 := new(MaxTag)
+	if err := Unmarshal(buf, m2); err != nil {
+		t.Fatalf("proto.Unmarshal failed: %v", err)
+	}
+	if got, want := m2.GetLastField(), *m.LastField; got != want {
+		t.Errorf("got %q, want %q", got, want)
+	}
+}
+
+func TestJSON(t *testing.T) {
+	m := &MyMessage{
+		Count:	Int32(4),
+		Pet:	[]string{"bunny", "kitty"},
+		Inner: &InnerMessage{
+			Host: String("cauchy"),
+		},
+		Bikeshed:	MyMessage_GREEN.Enum(),
+	}
+	const expected = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":1}`
+
+	b, err := json.Marshal(m)
+	if err != nil {
+		t.Fatalf("json.Marshal failed: %v", err)
+	}
+	s := string(b)
+	if s != expected {
+		t.Errorf("got  %s\nwant %s", s, expected)
+	}
+
+	received := new(MyMessage)
+	if err := json.Unmarshal(b, received); err != nil {
+		t.Fatalf("json.Unmarshal failed: %v", err)
+	}
+	if !Equal(received, m) {
+		t.Fatalf("got %s, want %s", received, m)
+	}
+
+	// Test unmarshalling of JSON with symbolic enum name.
+	const old = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":"GREEN"}`
+	received.Reset()
+	if err := json.Unmarshal([]byte(old), received); err != nil {
+		t.Fatalf("json.Unmarshal failed: %v", err)
+	}
+	if !Equal(received, m) {
+		t.Fatalf("got %s, want %s", received, m)
+	}
+}
+
+func TestBadWireType(t *testing.T) {
+	b := []byte{7<<3 | 6}	// field 7, wire type 6
+	pb := new(OtherMessage)
+	if err := Unmarshal(b, pb); err == nil {
+		t.Errorf("Unmarshal did not fail")
+	} else if !strings.Contains(err.Error(), "unknown wire type") {
+		t.Errorf("wrong error: %v", err)
+	}
+}
+
+func TestBytesWithInvalidLength(t *testing.T) {
+	// If a byte sequence has an invalid (negative) length, Unmarshal should not panic.
+	b := []byte{2<<3 | WireBytes, 0xff, 0xff, 0xff, 0xff, 0xff, 0}
+	Unmarshal(b, new(MyMessage))
+}
+
+func TestLengthOverflow(t *testing.T) {
+	// Overflowing a length should not panic.
+	b := []byte{2<<3 | WireBytes, 1, 1, 3<<3 | WireBytes, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01}
+	Unmarshal(b, new(MyMessage))
+}
+
+func TestVarintOverflow(t *testing.T) {
+	// Overflowing a 64-bit length should not be allowed.
+	b := []byte{1<<3 | WireVarint, 0x01, 3<<3 | WireBytes, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01}
+	if err := Unmarshal(b, new(MyMessage)); err == nil {
+		t.Fatalf("Overflowed uint64 length without error")
+	}
+}
+
+func TestUnmarshalFuzz(t *testing.T) {
+	const N = 1000
+	seed := time.Now().UnixNano()
+	t.Logf("RNG seed is %d", seed)
+	rng := rand.New(rand.NewSource(seed))
+	buf := make([]byte, 20)
+	for i := 0; i < N; i++ {
+		for j := range buf {
+			buf[j] = byte(rng.Intn(256))
+		}
+		fuzzUnmarshal(t, buf)
+	}
+}
+
+func TestMergeMessages(t *testing.T) {
+	pb := &MessageList{Message: []*MessageList_Message{{Name: String("x"), Count: Int32(1)}}}
+	data, err := Marshal(pb)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+
+	pb1 := new(MessageList)
+	if err := Unmarshal(data, pb1); err != nil {
+		t.Fatalf("first Unmarshal: %v", err)
+	}
+	if err := Unmarshal(data, pb1); err != nil {
+		t.Fatalf("second Unmarshal: %v", err)
+	}
+	if len(pb1.Message) != 1 {
+		t.Errorf("two Unmarshals produced %d Messages, want 1", len(pb1.Message))
+	}
+
+	pb2 := new(MessageList)
+	if err := UnmarshalMerge(data, pb2); err != nil {
+		t.Fatalf("first UnmarshalMerge: %v", err)
+	}
+	if err := UnmarshalMerge(data, pb2); err != nil {
+		t.Fatalf("second UnmarshalMerge: %v", err)
+	}
+	if len(pb2.Message) != 2 {
+		t.Errorf("two UnmarshalMerges produced %d Messages, want 2", len(pb2.Message))
+	}
+}
+
+func TestExtensionMarshalOrder(t *testing.T) {
+	m := &MyMessage{Count: Int(123)}
+	if err := SetExtension(m, E_Ext_More, &Ext{Data: String("alpha")}); err != nil {
+		t.Fatalf("SetExtension: %v", err)
+	}
+	if err := SetExtension(m, E_Ext_Text, String("aleph")); err != nil {
+		t.Fatalf("SetExtension: %v", err)
+	}
+	if err := SetExtension(m, E_Ext_Number, Int32(1)); err != nil {
+		t.Fatalf("SetExtension: %v", err)
+	}
+
+	// Serialize m several times, and check we get the same bytes each time.
+	var orig []byte
+	for i := 0; i < 100; i++ {
+		b, err := Marshal(m)
+		if err != nil {
+			t.Fatalf("Marshal: %v", err)
+		}
+		if i == 0 {
+			orig = b
+			continue
+		}
+		if !bytes.Equal(b, orig) {
+			t.Errorf("Bytes differ on attempt #%d", i)
+		}
+	}
+}
+
+// Many extensions, because small maps might not iterate differently on each iteration.
+var exts = []*ExtensionDesc{
+	E_X201,
+	E_X202,
+	E_X203,
+	E_X204,
+	E_X205,
+	E_X206,
+	E_X207,
+	E_X208,
+	E_X209,
+	E_X210,
+	E_X211,
+	E_X212,
+	E_X213,
+	E_X214,
+	E_X215,
+	E_X216,
+	E_X217,
+	E_X218,
+	E_X219,
+	E_X220,
+	E_X221,
+	E_X222,
+	E_X223,
+	E_X224,
+	E_X225,
+	E_X226,
+	E_X227,
+	E_X228,
+	E_X229,
+	E_X230,
+	E_X231,
+	E_X232,
+	E_X233,
+	E_X234,
+	E_X235,
+	E_X236,
+	E_X237,
+	E_X238,
+	E_X239,
+	E_X240,
+	E_X241,
+	E_X242,
+	E_X243,
+	E_X244,
+	E_X245,
+	E_X246,
+	E_X247,
+	E_X248,
+	E_X249,
+	E_X250,
+}
+
+func TestMessageSetMarshalOrder(t *testing.T) {
+	m := &MyMessageSet{}
+	for _, x := range exts {
+		if err := SetExtension(m, x, &Empty{}); err != nil {
+			t.Fatalf("SetExtension: %v", err)
+		}
+	}
+
+	buf, err := Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+
+	// Serialize m several times, and check we get the same bytes each time.
+	for i := 0; i < 10; i++ {
+		b1, err := Marshal(m)
+		if err != nil {
+			t.Fatalf("Marshal: %v", err)
+		}
+		if !bytes.Equal(b1, buf) {
+			t.Errorf("Bytes differ on re-Marshal #%d", i)
+		}
+
+		m2 := &MyMessageSet{}
+		if err := Unmarshal(buf, m2); err != nil {
+			t.Errorf("Unmarshal: %v", err)
+		}
+		b2, err := Marshal(m2)
+		if err != nil {
+			t.Errorf("re-Marshal: %v", err)
+		}
+		if !bytes.Equal(b2, buf) {
+			t.Errorf("Bytes differ on round-trip #%d", i)
+		}
+	}
+}
+
+func TestUnmarshalMergesMessages(t *testing.T) {
+	// If a nested message occurs twice in the input,
+	// the fields should be merged when decoding.
+	a := &OtherMessage{
+		Key:	Int64(123),
+		Inner: &InnerMessage{
+			Host:	String("polhode"),
+			Port:	Int32(1234),
+		},
+	}
+	aData, err := Marshal(a)
+	if err != nil {
+		t.Fatalf("Marshal(a): %v", err)
+	}
+	b := &OtherMessage{
+		Weight:	Float32(1.2),
+		Inner: &InnerMessage{
+			Host:		String("herpolhode"),
+			Connected:	Bool(true),
+		},
+	}
+	bData, err := Marshal(b)
+	if err != nil {
+		t.Fatalf("Marshal(b): %v", err)
+	}
+	want := &OtherMessage{
+		Key:	Int64(123),
+		Weight:	Float32(1.2),
+		Inner: &InnerMessage{
+			Host:		String("herpolhode"),
+			Port:		Int32(1234),
+			Connected:	Bool(true),
+		},
+	}
+	got := new(OtherMessage)
+	if err := Unmarshal(append(aData, bData...), got); err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+	if !Equal(got, want) {
+		t.Errorf("\n got %v\nwant %v", got, want)
+	}
+}
+
+func TestEncodingSizes(t *testing.T) {
+	tests := []struct {
+		m	Message
+		n	int
+	}{
+		{&Defaults{F_Int32: Int32(math.MaxInt32)}, 6},
+		{&Defaults{F_Int32: Int32(math.MinInt32)}, 6},
+		{&Defaults{F_Uint32: Uint32(math.MaxUint32)}, 6},
+	}
+	for _, test := range tests {
+		b, err := Marshal(test.m)
+		if err != nil {
+			t.Errorf("Marshal(%v): %v", test.m, err)
+			continue
+		}
+		if len(b) != test.n {
+			t.Errorf("Marshal(%v) yielded %d bytes, want %d bytes", test.m, len(b), test.n)
+		}
+	}
+}
+
+func TestRequiredNotSetError(t *testing.T) {
+	pb := initGoTest(false)
+	pb.RequiredField.Label = nil
+	pb.F_Int32Required = nil
+	pb.F_Int64Required = nil
+
+	expected := "0807" +	// field 1, encoding 0, value 7
+		"2206" + "120474797065" +	// field 4, encoding 2 (GoTestField)
+		"5001" +	// field 10, encoding 0, value 1
+		"6d20000000" +	// field 13, encoding 5, value 0x20
+		"714000000000000000" +	// field 14, encoding 1, value 0x40
+		"78a019" +	// field 15, encoding 0, value 0xca0 = 3232
+		"8001c032" +	// field 16, encoding 0, value 0x1940 = 6464
+		"8d0100004a45" +	// field 17, encoding 5, value 3232.0
+		"9101000000000040b940" +	// field 18, encoding 1, value 6464.0
+		"9a0106" + "737472696e67" +	// field 19, encoding 2, string "string"
+		"b304" +	// field 70, encoding 3, start group
+		"ba0408" + "7265717569726564" +	// field 71, encoding 2, string "required"
+		"b404" +	// field 70, encoding 4, end group
+		"aa0605" + "6279746573" +	// field 101, encoding 2, string "bytes"
+		"b0063f" +	// field 102, encoding 0, 0x3f zigzag32
+		"b8067f"	// field 103, encoding 0, 0x7f zigzag64
+
+	o := old()
+	bytes, err := Marshal(pb)
+	if _, ok := err.(*RequiredNotSetError); !ok {
+		fmt.Printf("marshal-1 err = %v, want *RequiredNotSetError", err)
+		o.DebugPrint("", bytes)
+		t.Fatalf("expected = %s", expected)
+	}
+	if strings.Index(err.Error(), "RequiredField.Label") < 0 {
+		t.Errorf("marshal-1 wrong err msg: %v", err)
+	}
+	if !equal(bytes, expected, t) {
+		o.DebugPrint("neq 1", bytes)
+		t.Fatalf("expected = %s", expected)
+	}
+
+	// Now test Unmarshal by recreating the original buffer.
+	pbd := new(GoTest)
+	err = Unmarshal(bytes, pbd)
+	if _, ok := err.(*RequiredNotSetError); !ok {
+		t.Fatalf("unmarshal err = %v, want *RequiredNotSetError", err)
+		o.DebugPrint("", bytes)
+		t.Fatalf("string = %s", expected)
+	}
+	if strings.Index(err.Error(), "RequiredField.{Unknown}") < 0 {
+		t.Errorf("unmarshal wrong err msg: %v", err)
+	}
+	bytes, err = Marshal(pbd)
+	if _, ok := err.(*RequiredNotSetError); !ok {
+		t.Errorf("marshal-2 err = %v, want *RequiredNotSetError", err)
+		o.DebugPrint("", bytes)
+		t.Fatalf("string = %s", expected)
+	}
+	if strings.Index(err.Error(), "RequiredField.Label") < 0 {
+		t.Errorf("marshal-2 wrong err msg: %v", err)
+	}
+	if !equal(bytes, expected, t) {
+		o.DebugPrint("neq 2", bytes)
+		t.Fatalf("string = %s", expected)
+	}
+}
+
+func fuzzUnmarshal(t *testing.T, data []byte) {
+	defer func() {
+		if e := recover(); e != nil {
+			t.Errorf("These bytes caused a panic: %+v", data)
+			t.Logf("Stack:\n%s", debug.Stack())
+			t.FailNow()
+		}
+	}()
+
+	pb := new(MyMessage)
+	Unmarshal(data, pb)
+}
+
+// Benchmarks
+
+func testMsg() *GoTest {
+	pb := initGoTest(true)
+	const N = 1000	// Internally the library starts much smaller.
+	pb.F_Int32Repeated = make([]int32, N)
+	pb.F_DoubleRepeated = make([]float64, N)
+	for i := 0; i < N; i++ {
+		pb.F_Int32Repeated[i] = int32(i)
+		pb.F_DoubleRepeated[i] = float64(i)
+	}
+	return pb
+}
+
+func bytesMsg() *GoTest {
+	pb := initGoTest(true)
+	buf := make([]byte, 4000)
+	for i := range buf {
+		buf[i] = byte(i)
+	}
+	pb.F_BytesDefaulted = buf
+	return pb
+}
+
+func benchmarkMarshal(b *testing.B, pb Message, marshal func(Message) ([]byte, error)) {
+	d, _ := marshal(pb)
+	b.SetBytes(int64(len(d)))
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		marshal(pb)
+	}
+}
+
+func benchmarkBufferMarshal(b *testing.B, pb Message) {
+	p := NewBuffer(nil)
+	benchmarkMarshal(b, pb, func(pb0 Message) ([]byte, error) {
+		p.Reset()
+		err := p.Marshal(pb0)
+		return p.Bytes(), err
+	})
+}
+
+func benchmarkSize(b *testing.B, pb Message) {
+	benchmarkMarshal(b, pb, func(pb0 Message) ([]byte, error) {
+		Size(pb)
+		return nil, nil
+	})
+}
+
+func newOf(pb Message) Message {
+	in := reflect.ValueOf(pb)
+	if in.IsNil() {
+		return pb
+	}
+	return reflect.New(in.Type().Elem()).Interface().(Message)
+}
+
+func benchmarkUnmarshal(b *testing.B, pb Message, unmarshal func([]byte, Message) error) {
+	d, _ := Marshal(pb)
+	b.SetBytes(int64(len(d)))
+	pbd := newOf(pb)
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		unmarshal(d, pbd)
+	}
+}
+
+func benchmarkBufferUnmarshal(b *testing.B, pb Message) {
+	p := NewBuffer(nil)
+	benchmarkUnmarshal(b, pb, func(d []byte, pb0 Message) error {
+		p.SetBuf(d)
+		return p.Unmarshal(pb0)
+	})
+}
+
+// Benchmark{Marshal,BufferMarshal,Size,Unmarshal,BufferUnmarshal}{,Bytes}
+
+func BenchmarkMarshal(b *testing.B) {
+	benchmarkMarshal(b, testMsg(), Marshal)
+}
+
+func BenchmarkBufferMarshal(b *testing.B) {
+	benchmarkBufferMarshal(b, testMsg())
+}
+
+func BenchmarkSize(b *testing.B) {
+	benchmarkSize(b, testMsg())
+}
+
+func BenchmarkUnmarshal(b *testing.B) {
+	benchmarkUnmarshal(b, testMsg(), Unmarshal)
+}
+
+func BenchmarkBufferUnmarshal(b *testing.B) {
+	benchmarkBufferUnmarshal(b, testMsg())
+}
+
+func BenchmarkMarshalBytes(b *testing.B) {
+	benchmarkMarshal(b, bytesMsg(), Marshal)
+}
+
+func BenchmarkBufferMarshalBytes(b *testing.B) {
+	benchmarkBufferMarshal(b, bytesMsg())
+}
+
+func BenchmarkSizeBytes(b *testing.B) {
+	benchmarkSize(b, bytesMsg())
+}
+
+func BenchmarkUnmarshalBytes(b *testing.B) {
+	benchmarkUnmarshal(b, bytesMsg(), Unmarshal)
+}
+
+func BenchmarkBufferUnmarshalBytes(b *testing.B) {
+	benchmarkBufferUnmarshal(b, bytesMsg())
+}
+
+func BenchmarkUnmarshalUnrecognizedFields(b *testing.B) {
+	b.StopTimer()
+	pb := initGoTestField()
+	skip := &GoSkipTest{
+		SkipInt32:	Int32(32),
+		SkipFixed32:	Uint32(3232),
+		SkipFixed64:	Uint64(6464),
+		SkipString:	String("skipper"),
+		Skipgroup: &GoSkipTest_SkipGroup{
+			GroupInt32:	Int32(75),
+			GroupString:	String("wxyz"),
+		},
+	}
+
+	pbd := new(GoTestField)
+	p := NewBuffer(nil)
+	p.Marshal(pb)
+	p.Marshal(skip)
+	p2 := NewBuffer(nil)
+
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		p2.SetBuf(p.Bytes())
+		p2.Unmarshal(pbd)
+	}
+}

+ 166 - 0
third_party/code.google.com/p/gogoprotobuf/proto/clone.go

@@ -0,0 +1,166 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  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.
+
+// Protocol buffer deep copy.
+// TODO: MessageSet and RawMessage.
+
+package proto
+
+import (
+	"log"
+	"reflect"
+	"strings"
+)
+
+// Clone returns a deep copy of a protocol buffer.
+func Clone(pb Message) Message {
+	in := reflect.ValueOf(pb)
+	if in.IsNil() {
+		return pb
+	}
+
+	out := reflect.New(in.Type().Elem())
+	// out is empty so a merge is a deep copy.
+	mergeStruct(out.Elem(), in.Elem())
+	return out.Interface().(Message)
+}
+
+// Merge merges src into dst.
+// Required and optional fields that are set in src will be set to that value in dst.
+// Elements of repeated fields will be appended.
+// Merge panics if src and dst are not the same type, or if dst is nil.
+func Merge(dst, src Message) {
+	in := reflect.ValueOf(src)
+	out := reflect.ValueOf(dst)
+	if out.IsNil() {
+		panic("proto: nil destination")
+	}
+	if in.Type() != out.Type() {
+		// Explicit test prior to mergeStruct so that mistyped nils will fail
+		panic("proto: type mismatch")
+	}
+	if in.IsNil() {
+		// Merging nil into non-nil is a quiet no-op
+		return
+	}
+	mergeStruct(out.Elem(), in.Elem())
+}
+
+func mergeStruct(out, in reflect.Value) {
+	for i := 0; i < in.NumField(); i++ {
+		f := in.Type().Field(i)
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+		mergeAny(out.Field(i), in.Field(i))
+	}
+
+	if emIn, ok := in.Addr().Interface().(extendableProto); ok {
+		emOut := out.Addr().Interface().(extendableProto)
+		mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap())
+	}
+
+	uf := in.FieldByName("XXX_unrecognized")
+	if !uf.IsValid() {
+		return
+	}
+	uin := uf.Bytes()
+	if len(uin) > 0 {
+		out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
+	}
+}
+
+func mergeAny(out, in reflect.Value) {
+	if in.Type() == protoMessageType {
+		if !in.IsNil() {
+			if out.IsNil() {
+				out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
+			} else {
+				Merge(out.Interface().(Message), in.Interface().(Message))
+			}
+		}
+		return
+	}
+	switch in.Kind() {
+	case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
+		reflect.String, reflect.Uint32, reflect.Uint64:
+		out.Set(in)
+	case reflect.Ptr:
+		if in.IsNil() {
+			return
+		}
+		if out.IsNil() {
+			out.Set(reflect.New(in.Elem().Type()))
+		}
+		mergeAny(out.Elem(), in.Elem())
+	case reflect.Slice:
+		if in.IsNil() {
+			return
+		}
+		n := in.Len()
+		if out.IsNil() {
+			out.Set(reflect.MakeSlice(in.Type(), 0, n))
+		}
+		switch in.Type().Elem().Kind() {
+		case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
+			reflect.String, reflect.Uint32, reflect.Uint64, reflect.Uint8:
+			out.Set(reflect.AppendSlice(out, in))
+		default:
+			for i := 0; i < n; i++ {
+				x := reflect.Indirect(reflect.New(in.Type().Elem()))
+				mergeAny(x, in.Index(i))
+				out.Set(reflect.Append(out, x))
+			}
+		}
+	case reflect.Struct:
+		mergeStruct(out, in)
+	default:
+		// unknown type, so not a protocol buffer
+		log.Printf("proto: don't know how to copy %v", in)
+	}
+}
+
+func mergeExtension(out, in map[int32]Extension) {
+	for extNum, eIn := range in {
+		eOut := Extension{desc: eIn.desc}
+		if eIn.value != nil {
+			v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
+			mergeAny(v, reflect.ValueOf(eIn.value))
+			eOut.value = v.Interface()
+		}
+		if eIn.enc != nil {
+			eOut.enc = make([]byte, len(eIn.enc))
+			copy(eOut.enc, eIn.enc)
+		}
+
+		out[extNum] = eOut
+	}
+}

+ 180 - 0
third_party/code.google.com/p/gogoprotobuf/proto/clone_test.go

@@ -0,0 +1,180 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  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.
+
+package proto_test
+
+import (
+	"testing"
+
+	"github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+
+	pb "./testdata"
+)
+
+var cloneTestMessage = &pb.MyMessage{
+	Count:	proto.Int32(42),
+	Name:	proto.String("Dave"),
+	Pet:	[]string{"bunny", "kitty", "horsey"},
+	Inner: &pb.InnerMessage{
+		Host:		proto.String("niles"),
+		Port:		proto.Int32(9099),
+		Connected:	proto.Bool(true),
+	},
+	Others: []*pb.OtherMessage{
+		{
+			Value: []byte("some bytes"),
+		},
+	},
+	Somegroup: &pb.MyMessage_SomeGroup{
+		GroupField: proto.Int32(6),
+	},
+	RepBytes:	[][]byte{[]byte("sham"), []byte("wow")},
+}
+
+func init() {
+	ext := &pb.Ext{
+		Data: proto.String("extension"),
+	}
+	if err := proto.SetExtension(cloneTestMessage, pb.E_Ext_More, ext); err != nil {
+		panic("SetExtension: " + err.Error())
+	}
+}
+
+func TestClone(t *testing.T) {
+	m := proto.Clone(cloneTestMessage).(*pb.MyMessage)
+	if !proto.Equal(m, cloneTestMessage) {
+		t.Errorf("Clone(%v) = %v", cloneTestMessage, m)
+	}
+
+	// Verify it was a deep copy.
+	*m.Inner.Port++
+	if proto.Equal(m, cloneTestMessage) {
+		t.Error("Mutating clone changed the original")
+	}
+}
+
+func TestCloneNil(t *testing.T) {
+	var m *pb.MyMessage
+	if c := proto.Clone(m); !proto.Equal(m, c) {
+		t.Errorf("Clone(%v) = %v", m, c)
+	}
+}
+
+var mergeTests = []struct {
+	src, dst, want proto.Message
+}{
+	{
+		src: &pb.MyMessage{
+			Count: proto.Int32(42),
+		},
+		dst: &pb.MyMessage{
+			Name: proto.String("Dave"),
+		},
+		want: &pb.MyMessage{
+			Count:	proto.Int32(42),
+			Name:	proto.String("Dave"),
+		},
+	},
+	{
+		src: &pb.MyMessage{
+			Inner: &pb.InnerMessage{
+				Host:		proto.String("hey"),
+				Connected:	proto.Bool(true),
+			},
+			Pet:	[]string{"horsey"},
+			Others: []*pb.OtherMessage{
+				{
+					Value: []byte("some bytes"),
+				},
+			},
+		},
+		dst: &pb.MyMessage{
+			Inner: &pb.InnerMessage{
+				Host:	proto.String("niles"),
+				Port:	proto.Int32(9099),
+			},
+			Pet:	[]string{"bunny", "kitty"},
+			Others: []*pb.OtherMessage{
+				{
+					Key: proto.Int64(31415926535),
+				},
+				{
+					// Explicitly test a src=nil field
+					Inner: nil,
+				},
+			},
+		},
+		want: &pb.MyMessage{
+			Inner: &pb.InnerMessage{
+				Host:		proto.String("hey"),
+				Connected:	proto.Bool(true),
+				Port:		proto.Int32(9099),
+			},
+			Pet:	[]string{"bunny", "kitty", "horsey"},
+			Others: []*pb.OtherMessage{
+				{
+					Key: proto.Int64(31415926535),
+				},
+				{},
+				{
+					Value: []byte("some bytes"),
+				},
+			},
+		},
+	},
+	{
+		src: &pb.MyMessage{
+			RepBytes: [][]byte{[]byte("wow")},
+		},
+		dst: &pb.MyMessage{
+			Somegroup: &pb.MyMessage_SomeGroup{
+				GroupField: proto.Int32(6),
+			},
+			RepBytes:	[][]byte{[]byte("sham")},
+		},
+		want: &pb.MyMessage{
+			Somegroup: &pb.MyMessage_SomeGroup{
+				GroupField: proto.Int32(6),
+			},
+			RepBytes:	[][]byte{[]byte("sham"), []byte("wow")},
+		},
+	},
+}
+
+func TestMerge(t *testing.T) {
+	for _, m := range mergeTests {
+		got := proto.Clone(m.dst)
+		proto.Merge(got, m.src)
+		if !proto.Equal(got, m.want) {
+			t.Errorf("Merge(%v, %v)\n got %v\nwant %v\n", m.dst, m.src, got, m.want)
+		}
+	}
+}

+ 732 - 0
third_party/code.google.com/p/gogoprotobuf/proto/decode.go

@@ -0,0 +1,732 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+package proto
+
+/*
+ * Routines for decoding protocol buffer data to construct in-memory representations.
+ */
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"reflect"
+)
+
+// ErrWrongType occurs when the wire encoding for the field disagrees with
+// that specified in the type being decoded.  This is usually caused by attempting
+// to convert an encoded protocol buffer into a struct of the wrong type.
+var ErrWrongType = errors.New("proto: field/encoding mismatch: wrong type for field")
+
+// errOverflow is returned when an integer is too large to be represented.
+var errOverflow = errors.New("proto: integer overflow")
+
+// The fundamental decoders that interpret bytes on the wire.
+// Those that take integer types all return uint64 and are
+// therefore of type valueDecoder.
+
+// DecodeVarint reads a varint-encoded integer from the slice.
+// It returns the integer and the number of bytes consumed, or
+// zero if there is not enough.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func DecodeVarint(buf []byte) (x uint64, n int) {
+	// x, n already 0
+	for shift := uint(0); shift < 64; shift += 7 {
+		if n >= len(buf) {
+			return 0, 0
+		}
+		b := uint64(buf[n])
+		n++
+		x |= (b & 0x7F) << shift
+		if (b & 0x80) == 0 {
+			return x, n
+		}
+	}
+
+	// The number is too large to represent in a 64-bit value.
+	return 0, 0
+}
+
+// DecodeVarint reads a varint-encoded integer from the Buffer.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func (p *Buffer) DecodeVarint() (x uint64, err error) {
+	// x, err already 0
+
+	i := p.index
+	l := len(p.buf)
+
+	for shift := uint(0); shift < 64; shift += 7 {
+		if i >= l {
+			err = io.ErrUnexpectedEOF
+			return
+		}
+		b := p.buf[i]
+		i++
+		x |= (uint64(b) & 0x7F) << shift
+		if b < 0x80 {
+			p.index = i
+			return
+		}
+	}
+
+	// The number is too large to represent in a 64-bit value.
+	err = errOverflow
+	return
+}
+
+// DecodeFixed64 reads a 64-bit integer from the Buffer.
+// This is the format for the
+// fixed64, sfixed64, and double protocol buffer types.
+func (p *Buffer) DecodeFixed64() (x uint64, err error) {
+	// x, err already 0
+	i := p.index + 8
+	if i < 0 || i > len(p.buf) {
+		err = io.ErrUnexpectedEOF
+		return
+	}
+	p.index = i
+
+	x = uint64(p.buf[i-8])
+	x |= uint64(p.buf[i-7]) << 8
+	x |= uint64(p.buf[i-6]) << 16
+	x |= uint64(p.buf[i-5]) << 24
+	x |= uint64(p.buf[i-4]) << 32
+	x |= uint64(p.buf[i-3]) << 40
+	x |= uint64(p.buf[i-2]) << 48
+	x |= uint64(p.buf[i-1]) << 56
+	return
+}
+
+// DecodeFixed32 reads a 32-bit integer from the Buffer.
+// This is the format for the
+// fixed32, sfixed32, and float protocol buffer types.
+func (p *Buffer) DecodeFixed32() (x uint64, err error) {
+	// x, err already 0
+	i := p.index + 4
+	if i < 0 || i > len(p.buf) {
+		err = io.ErrUnexpectedEOF
+		return
+	}
+	p.index = i
+
+	x = uint64(p.buf[i-4])
+	x |= uint64(p.buf[i-3]) << 8
+	x |= uint64(p.buf[i-2]) << 16
+	x |= uint64(p.buf[i-1]) << 24
+	return
+}
+
+// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
+// from the Buffer.
+// This is the format used for the sint64 protocol buffer type.
+func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
+	x, err = p.DecodeVarint()
+	if err != nil {
+		return
+	}
+	x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
+	return
+}
+
+// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
+// from  the Buffer.
+// This is the format used for the sint32 protocol buffer type.
+func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
+	x, err = p.DecodeVarint()
+	if err != nil {
+		return
+	}
+	x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
+	return
+}
+
+// These are not ValueDecoders: they produce an array of bytes or a string.
+// bytes, embedded messages
+
+// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
+// This is the format used for the bytes protocol buffer
+// type and for embedded messages.
+func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
+	n, err := p.DecodeVarint()
+	if err != nil {
+		return
+	}
+
+	nb := int(n)
+	if nb < 0 {
+		return nil, fmt.Errorf("proto: bad byte length %d", nb)
+	}
+	end := p.index + nb
+	if end < p.index || end > len(p.buf) {
+		return nil, io.ErrUnexpectedEOF
+	}
+
+	if !alloc {
+		// todo: check if can get more uses of alloc=false
+		buf = p.buf[p.index:end]
+		p.index += nb
+		return
+	}
+
+	buf = make([]byte, nb)
+	copy(buf, p.buf[p.index:])
+	p.index += nb
+	return
+}
+
+// DecodeStringBytes reads an encoded string from the Buffer.
+// This is the format used for the proto2 string type.
+func (p *Buffer) DecodeStringBytes() (s string, err error) {
+	buf, err := p.DecodeRawBytes(false)
+	if err != nil {
+		return
+	}
+	return string(buf), nil
+}
+
+// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
+// If the protocol buffer has extensions, and the field matches, add it as an extension.
+// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
+func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error {
+	oi := o.index
+
+	err := o.skip(t, tag, wire)
+	if err != nil {
+		return err
+	}
+
+	if !unrecField.IsValid() {
+		return nil
+	}
+
+	ptr := structPointer_Bytes(base, unrecField)
+
+	if *ptr == nil {
+		// This is the first skipped element,
+		// allocate a new buffer.
+		*ptr = o.bufalloc()
+	}
+
+	// Add the skipped field to struct field
+	obuf := o.buf
+
+	o.buf = *ptr
+	o.EncodeVarint(uint64(tag<<3 | wire))
+	*ptr = append(o.buf, obuf[oi:o.index]...)
+
+	o.buf = obuf
+
+	return nil
+}
+
+// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
+func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
+
+	var u uint64
+	var err error
+
+	switch wire {
+	case WireVarint:
+		_, err = o.DecodeVarint()
+	case WireFixed64:
+		_, err = o.DecodeFixed64()
+	case WireBytes:
+		_, err = o.DecodeRawBytes(false)
+	case WireFixed32:
+		_, err = o.DecodeFixed32()
+	case WireStartGroup:
+		for {
+			u, err = o.DecodeVarint()
+			if err != nil {
+				break
+			}
+			fwire := int(u & 0x7)
+			if fwire == WireEndGroup {
+				break
+			}
+			ftag := int(u >> 3)
+			err = o.skip(t, ftag, fwire)
+			if err != nil {
+				break
+			}
+		}
+	default:
+		err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
+	}
+	return err
+}
+
+// Unmarshaler is the interface representing objects that can
+// unmarshal themselves.  The method should reset the receiver before
+// decoding starts.  The argument points to data that may be
+// overwritten, so implementations should not keep references to the
+// buffer.
+type Unmarshaler interface {
+	Unmarshal([]byte) error
+}
+
+// Unmarshal parses the protocol buffer representation in buf and places the
+// decoded result in pb.  If the struct underlying pb does not match
+// the data in buf, the results can be unpredictable.
+//
+// Unmarshal resets pb before starting to unmarshal, so any
+// existing data in pb is always removed. Use UnmarshalMerge
+// to preserve and append to existing data.
+func Unmarshal(buf []byte, pb Message) error {
+	pb.Reset()
+	return UnmarshalMerge(buf, pb)
+}
+
+// UnmarshalMerge parses the protocol buffer representation in buf and
+// writes the decoded result to pb.  If the struct underlying pb does not match
+// the data in buf, the results can be unpredictable.
+//
+// UnmarshalMerge merges into existing data in pb.
+// Most code should use Unmarshal instead.
+func UnmarshalMerge(buf []byte, pb Message) error {
+	// If the object can unmarshal itself, let it.
+	if u, ok := pb.(Unmarshaler); ok {
+		return u.Unmarshal(buf)
+	}
+	return NewBuffer(buf).Unmarshal(pb)
+}
+
+// Unmarshal parses the protocol buffer representation in the
+// Buffer and places the decoded result in pb.  If the struct
+// underlying pb does not match the data in the buffer, the results can be
+// unpredictable.
+func (p *Buffer) Unmarshal(pb Message) error {
+	// If the object can unmarshal itself, let it.
+	if u, ok := pb.(Unmarshaler); ok {
+		err := u.Unmarshal(p.buf[p.index:])
+		p.index = len(p.buf)
+		return err
+	}
+
+	typ, base, err := getbase(pb)
+	if err != nil {
+		return err
+	}
+
+	err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
+
+	if collectStats {
+		stats.Decode++
+	}
+
+	return err
+}
+
+// unmarshalType does the work of unmarshaling a structure.
+func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
+	var state errorState
+	required, reqFields := prop.reqCount, uint64(0)
+
+	var err error
+	for err == nil && o.index < len(o.buf) {
+		oi := o.index
+		var u uint64
+		u, err = o.DecodeVarint()
+		if err != nil {
+			break
+		}
+		wire := int(u & 0x7)
+		if wire == WireEndGroup {
+			if is_group {
+				return nil // input is satisfied
+			}
+			return ErrWrongType
+		}
+		tag := int(u >> 3)
+		if tag <= 0 {
+			return fmt.Errorf("proto: illegal tag %d", tag)
+		}
+		fieldnum, ok := prop.decoderTags.get(tag)
+		if !ok {
+			// Maybe it's an extension?
+			if prop.extendable {
+				if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
+					if err = o.skip(st, tag, wire); err == nil {
+						ext := e.ExtensionMap()[int32(tag)] // may be missing
+						ext.enc = append(ext.enc, o.buf[oi:o.index]...)
+						e.ExtensionMap()[int32(tag)] = ext
+					}
+					continue
+				}
+			}
+			err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
+			continue
+		}
+		p := prop.Prop[fieldnum]
+
+		if p.dec == nil {
+			fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
+			continue
+		}
+		dec := p.dec
+		if wire != WireStartGroup && wire != p.WireType {
+			if wire == WireBytes && p.packedDec != nil {
+				// a packable field
+				dec = p.packedDec
+			} else {
+				err = ErrWrongType
+				continue
+			}
+		}
+		decErr := dec(o, p, base)
+		if decErr != nil && !state.shouldContinue(decErr, p) {
+			err = decErr
+		}
+		if err == nil && p.Required {
+			// Successfully decoded a required field.
+			if tag <= 64 {
+				// use bitmap for fields 1-64 to catch field reuse.
+				var mask uint64 = 1 << uint64(tag-1)
+				if reqFields&mask == 0 {
+					// new required field
+					reqFields |= mask
+					required--
+				}
+			} else {
+				// This is imprecise. It can be fooled by a required field
+				// with a tag > 64 that is encoded twice; that's very rare.
+				// A fully correct implementation would require allocating
+				// a data structure, which we would like to avoid.
+				required--
+			}
+		}
+	}
+	if err == nil {
+		if is_group {
+			return io.ErrUnexpectedEOF
+		}
+		if state.err != nil {
+			return state.err
+		}
+		if required > 0 {
+			// Not enough information to determine the exact field. If we use extra
+			// CPU, we could determine the field only if the missing required field
+			// has a tag <= 64 and we check reqFields.
+			return &RequiredNotSetError{"{Unknown}"}
+		}
+	}
+	return err
+}
+
+// Individual type decoders
+// For each,
+//	u is the decoded value,
+//	v is a pointer to the field (pointer) in the struct
+
+// Sizes of the pools to allocate inside the Buffer.
+// The goal is modest amortization and allocation
+// on at least 16-byte boundaries.
+const (
+	boolPoolSize   = 16
+	uint32PoolSize = 8
+	uint64PoolSize = 4
+)
+
+// Decode a bool.
+func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	if len(o.bools) == 0 {
+		o.bools = make([]bool, boolPoolSize)
+	}
+	o.bools[0] = u != 0
+	*structPointer_Bool(base, p.field) = &o.bools[0]
+	o.bools = o.bools[1:]
+	return nil
+}
+
+// Decode an int32.
+func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
+	return nil
+}
+
+// Decode an int64.
+func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word64_Set(structPointer_Word64(base, p.field), o, u)
+	return nil
+}
+
+// Decode a string.
+func (o *Buffer) dec_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	sp := new(string)
+	*sp = s
+	*structPointer_String(base, p.field) = sp
+	return nil
+}
+
+// Decode a slice of bytes ([]byte).
+func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
+	b, err := o.DecodeRawBytes(true)
+	if err != nil {
+		return err
+	}
+	*structPointer_Bytes(base, p.field) = b
+	return nil
+}
+
+// Decode a slice of bools ([]bool).
+func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	v := structPointer_BoolSlice(base, p.field)
+	*v = append(*v, u != 0)
+	return nil
+}
+
+// Decode a slice of bools ([]bool) in packed format.
+func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
+	v := structPointer_BoolSlice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded bools
+
+	y := *v
+	for i := 0; i < nb; i++ {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		y = append(y, u != 0)
+	}
+
+	*v = y
+	return nil
+}
+
+// Decode a slice of int32s ([]int32).
+func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	structPointer_Word32Slice(base, p.field).Append(uint32(u))
+	return nil
+}
+
+// Decode a slice of int32s ([]int32) in packed format.
+func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Slice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded int32s
+
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
+	for o.index < fin {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		v.Append(uint32(u))
+	}
+	return nil
+}
+
+// Decode a slice of int64s ([]int64).
+func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+
+	structPointer_Word64Slice(base, p.field).Append(u)
+	return nil
+}
+
+// Decode a slice of int64s ([]int64) in packed format.
+func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64Slice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded int64s
+
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
+	for o.index < fin {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		v.Append(u)
+	}
+	return nil
+}
+
+// Decode a slice of strings ([]string).
+func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	v := structPointer_StringSlice(base, p.field)
+	*v = append(*v, s)
+	return nil
+}
+
+// Decode a slice of slice of bytes ([][]byte).
+func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
+	b, err := o.DecodeRawBytes(true)
+	if err != nil {
+		return err
+	}
+	v := structPointer_BytesSlice(base, p.field)
+	*v = append(*v, b)
+	return nil
+}
+
+// Decode a group.
+func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
+	bas := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(bas) {
+		// allocate new nested message
+		bas = toStructPointer(reflect.New(p.stype))
+		structPointer_SetStructPointer(base, p.field, bas)
+	}
+	return o.unmarshalType(p.stype, p.sprop, true, bas)
+}
+
+// Decode an embedded message.
+func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
+	raw, e := o.DecodeRawBytes(false)
+	if e != nil {
+		return e
+	}
+
+	bas := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(bas) {
+		// allocate new nested message
+		bas = toStructPointer(reflect.New(p.stype))
+		structPointer_SetStructPointer(base, p.field, bas)
+	}
+
+	// If the object can unmarshal itself, let it.
+	if p.isUnmarshaler {
+		iv := structPointer_Interface(bas, p.stype)
+		return iv.(Unmarshaler).Unmarshal(raw)
+	}
+
+	obuf := o.buf
+	oi := o.index
+	o.buf = raw
+	o.index = 0
+
+	err = o.unmarshalType(p.stype, p.sprop, false, bas)
+	o.buf = obuf
+	o.index = oi
+
+	return err
+}
+
+// Decode a slice of embedded messages.
+func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
+	return o.dec_slice_struct(p, false, base)
+}
+
+// Decode a slice of embedded groups.
+func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
+	return o.dec_slice_struct(p, true, base)
+}
+
+// Decode a slice of structs ([]*struct).
+func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
+	v := reflect.New(p.stype)
+	bas := toStructPointer(v)
+	structPointer_StructPointerSlice(base, p.field).Append(bas)
+
+	if is_group {
+		err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
+		return err
+	}
+
+	raw, err := o.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+
+	// If the object can unmarshal itself, let it.
+	if p.isUnmarshaler {
+		iv := v.Interface()
+		return iv.(Unmarshaler).Unmarshal(raw)
+	}
+
+	obuf := o.buf
+	oi := o.index
+	o.buf = raw
+	o.index = 0
+
+	err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
+
+	o.buf = obuf
+	o.index = oi
+
+	return err
+}

+ 220 - 0
third_party/code.google.com/p/gogoprotobuf/proto/decode_gogo.go

@@ -0,0 +1,220 @@
+// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+// http://code.google.com/p/gogoprotobuf/gogoproto
+//
+// 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.
+//
+// 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.
+
+package proto
+
+import (
+	"reflect"
+)
+
+// Decode a reference to a bool pointer.
+func (o *Buffer) dec_ref_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	if len(o.bools) == 0 {
+		o.bools = make([]bool, boolPoolSize)
+	}
+	o.bools[0] = u != 0
+	*structPointer_RefBool(base, p.field) = o.bools[0]
+	o.bools = o.bools[1:]
+	return nil
+}
+
+// Decode a reference to an int32 pointer.
+func (o *Buffer) dec_ref_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	refWord32_Set(structPointer_RefWord32(base, p.field), o, uint32(u))
+	return nil
+}
+
+// Decode a reference to an int64 pointer.
+func (o *Buffer) dec_ref_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	refWord64_Set(structPointer_RefWord64(base, p.field), o, u)
+	return nil
+}
+
+// Decode a reference to a string pointer.
+func (o *Buffer) dec_ref_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	*structPointer_RefString(base, p.field) = s
+	return nil
+}
+
+// Decode a reference to a struct pointer.
+func (o *Buffer) dec_ref_struct_message(p *Properties, base structPointer) (err error) {
+	raw, e := o.DecodeRawBytes(false)
+	if e != nil {
+		return e
+	}
+
+	// If the object can unmarshal itself, let it.
+	if p.isUnmarshaler {
+		panic("not supported, since this is a pointer receiver")
+	}
+
+	obuf := o.buf
+	oi := o.index
+	o.buf = raw
+	o.index = 0
+
+	bas := structPointer_FieldPointer(base, p.field)
+
+	err = o.unmarshalType(p.stype, p.sprop, false, bas)
+	o.buf = obuf
+	o.index = oi
+
+	return err
+}
+
+// Decode a slice of references to struct pointers ([]struct).
+func (o *Buffer) dec_slice_ref_struct(p *Properties, is_group bool, base structPointer) error {
+	newBas := appendStructPointer(base, p.field, p.sstype)
+
+	if is_group {
+		panic("not supported, maybe in future, if requested.")
+	}
+
+	raw, err := o.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+
+	// If the object can unmarshal itself, let it.
+	if p.isUnmarshaler {
+		panic("not supported, since this is not a pointer receiver.")
+	}
+
+	obuf := o.buf
+	oi := o.index
+	o.buf = raw
+	o.index = 0
+
+	err = o.unmarshalType(p.stype, p.sprop, is_group, newBas)
+
+	o.buf = obuf
+	o.index = oi
+
+	return err
+}
+
+// Decode a slice of references to struct pointers.
+func (o *Buffer) dec_slice_ref_struct_message(p *Properties, base structPointer) error {
+	return o.dec_slice_ref_struct(p, false, base)
+}
+
+func setPtrCustomType(base structPointer, f field, v interface{}) {
+	if v == nil {
+		return
+	}
+	structPointer_SetStructPointer(base, f, structPointer(reflect.ValueOf(v).Pointer()))
+}
+
+func setCustomType(base structPointer, f field, value interface{}) {
+	if value == nil {
+		return
+	}
+	v := reflect.ValueOf(value).Elem()
+	t := reflect.TypeOf(value).Elem()
+	kind := t.Kind()
+	switch kind {
+	case reflect.Slice:
+		slice := reflect.MakeSlice(t, v.Len(), v.Cap())
+		reflect.Copy(slice, v)
+		oldHeader := structPointer_GetSliceHeader(base, f)
+		oldHeader.Data = slice.Pointer()
+		oldHeader.Len = v.Len()
+		oldHeader.Cap = v.Cap()
+	default:
+		l := 1
+		size := reflect.TypeOf(value).Elem().Size()
+		if kind == reflect.Array {
+			l = reflect.TypeOf(value).Elem().Len()
+			size = reflect.TypeOf(value).Size()
+		}
+		total := int(size) * l
+		structPointer_Copy(toStructPointer(reflect.ValueOf(value)), structPointer_Add(base, f), total)
+	}
+}
+
+func (o *Buffer) dec_custom_bytes(p *Properties, base structPointer) error {
+	b, err := o.DecodeRawBytes(true)
+	if err != nil {
+		return err
+	}
+	i := reflect.New(p.ctype.Elem()).Interface()
+	custom := (i).(Unmarshaler)
+	if err := custom.Unmarshal(b); err != nil {
+		return err
+	}
+	setPtrCustomType(base, p.field, custom)
+	return nil
+}
+
+func (o *Buffer) dec_custom_ref_bytes(p *Properties, base structPointer) error {
+	b, err := o.DecodeRawBytes(true)
+	if err != nil {
+		return err
+	}
+	i := reflect.New(p.ctype).Interface()
+	custom := (i).(Unmarshaler)
+	if err := custom.Unmarshal(b); err != nil {
+		return err
+	}
+	if custom != nil {
+		setCustomType(base, p.field, custom)
+	}
+	return nil
+}
+
+// Decode a slice of bytes ([]byte) into a slice of custom types.
+func (o *Buffer) dec_custom_slice_bytes(p *Properties, base structPointer) error {
+	b, err := o.DecodeRawBytes(true)
+	if err != nil {
+		return err
+	}
+	i := reflect.New(p.ctype.Elem()).Interface()
+	custom := (i).(Unmarshaler)
+	if err := custom.Unmarshal(b); err != nil {
+		return err
+	}
+	newBas := appendStructPointer(base, p.field, p.ctype)
+
+	setCustomType(newBas, 0, custom)
+
+	return nil
+}

+ 952 - 0
third_party/code.google.com/p/gogoprotobuf/proto/encode.go

@@ -0,0 +1,952 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+package proto
+
+/*
+ * Routines for encoding data into the wire format for protocol buffers.
+ */
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"sort"
+)
+
+// RequiredNotSetError is the error returned if Marshal is called with
+// a protocol buffer struct whose required fields have not
+// all been initialized. It is also the error returned if Unmarshal is
+// called with an encoded protocol buffer that does not include all the
+// required fields.
+//
+// When printed, RequiredNotSetError reports the first unset required field in a
+// message. If the field cannot be precisely determined, it is reported as
+// "{Unknown}".
+type RequiredNotSetError struct {
+	field string
+}
+
+func (e *RequiredNotSetError) Error() string {
+	return fmt.Sprintf("proto: required field %q not set", e.field)
+}
+
+var (
+	// ErrRepeatedHasNil is the error returned if Marshal is called with
+	// a struct with a repeated field containing a nil element.
+	ErrRepeatedHasNil = errors.New("proto: repeated field has nil element")
+
+	// ErrNil is the error returned if Marshal is called with nil.
+	ErrNil = errors.New("proto: Marshal called with nil")
+)
+
+// The fundamental encoders that put bytes on the wire.
+// Those that take integer types all accept uint64 and are
+// therefore of type valueEncoder.
+
+const maxVarintBytes = 10 // maximum length of a varint
+
+// EncodeVarint returns the varint encoding of x.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+// Not used by the package itself, but helpful to clients
+// wishing to use the same encoding.
+func EncodeVarint(x uint64) []byte {
+	var buf [maxVarintBytes]byte
+	var n int
+	for n = 0; x > 127; n++ {
+		buf[n] = 0x80 | uint8(x&0x7F)
+		x >>= 7
+	}
+	buf[n] = uint8(x)
+	n++
+	return buf[0:n]
+}
+
+// EncodeVarint writes a varint-encoded integer to the Buffer.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func (p *Buffer) EncodeVarint(x uint64) error {
+	for x >= 1<<7 {
+		p.buf = append(p.buf, uint8(x&0x7f|0x80))
+		x >>= 7
+	}
+	p.buf = append(p.buf, uint8(x))
+	return nil
+}
+
+func sizeVarint(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+
+// EncodeFixed64 writes a 64-bit integer to the Buffer.
+// This is the format for the
+// fixed64, sfixed64, and double protocol buffer types.
+func (p *Buffer) EncodeFixed64(x uint64) error {
+	p.buf = append(p.buf,
+		uint8(x),
+		uint8(x>>8),
+		uint8(x>>16),
+		uint8(x>>24),
+		uint8(x>>32),
+		uint8(x>>40),
+		uint8(x>>48),
+		uint8(x>>56))
+	return nil
+}
+
+func sizeFixed64(x uint64) int {
+	return 8
+}
+
+// EncodeFixed32 writes a 32-bit integer to the Buffer.
+// This is the format for the
+// fixed32, sfixed32, and float protocol buffer types.
+func (p *Buffer) EncodeFixed32(x uint64) error {
+	p.buf = append(p.buf,
+		uint8(x),
+		uint8(x>>8),
+		uint8(x>>16),
+		uint8(x>>24))
+	return nil
+}
+
+func sizeFixed32(x uint64) int {
+	return 4
+}
+
+// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
+// to the Buffer.
+// This is the format used for the sint64 protocol buffer type.
+func (p *Buffer) EncodeZigzag64(x uint64) error {
+	// use signed number to get arithmetic right shift.
+	return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+
+func sizeZigzag64(x uint64) int {
+	return sizeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+
+// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
+// to the Buffer.
+// This is the format used for the sint32 protocol buffer type.
+func (p *Buffer) EncodeZigzag32(x uint64) error {
+	// use signed number to get arithmetic right shift.
+	return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
+}
+
+func sizeZigzag32(x uint64) int {
+	return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
+}
+
+// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
+// This is the format used for the bytes protocol buffer
+// type and for embedded messages.
+func (p *Buffer) EncodeRawBytes(b []byte) error {
+	p.EncodeVarint(uint64(len(b)))
+	p.buf = append(p.buf, b...)
+	return nil
+}
+
+func sizeRawBytes(b []byte) int {
+	return sizeVarint(uint64(len(b))) +
+		len(b)
+}
+
+// EncodeStringBytes writes an encoded string to the Buffer.
+// This is the format used for the proto2 string type.
+func (p *Buffer) EncodeStringBytes(s string) error {
+	p.EncodeVarint(uint64(len(s)))
+	p.buf = append(p.buf, s...)
+	return nil
+}
+
+func sizeStringBytes(s string) int {
+	return sizeVarint(uint64(len(s))) +
+		len(s)
+}
+
+// Marshaler is the interface representing objects that can marshal themselves.
+type Marshaler interface {
+	Marshal() ([]byte, error)
+}
+
+// Marshal takes the protocol buffer
+// and encodes it into the wire format, returning the data.
+func Marshal(pb Message) ([]byte, error) {
+	// Can the object marshal itself?
+	if m, ok := pb.(Marshaler); ok {
+		return m.Marshal()
+	}
+	p := NewBuffer(nil)
+	err := p.Marshal(pb)
+	var state errorState
+	if err != nil && !state.shouldContinue(err, nil) {
+		return nil, err
+	}
+	return p.buf, err
+}
+
+// Marshal takes the protocol buffer
+// and encodes it into the wire format, writing the result to the
+// Buffer.
+func (p *Buffer) Marshal(pb Message) error {
+	// Can the object marshal itself?
+	if m, ok := pb.(Marshaler); ok {
+		data, err := m.Marshal()
+		if err != nil {
+			return err
+		}
+		p.buf = append(p.buf, data...)
+		return nil
+	}
+
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return ErrNil
+	}
+	if err == nil {
+		err = p.enc_struct(t.Elem(), GetProperties(t.Elem()), base)
+	}
+
+	if collectStats {
+		stats.Encode++
+	}
+
+	return err
+}
+
+// Size returns the encoded size of a protocol buffer.
+func Size(pb Message) (n int) {
+	// Can the object marshal itself?  If so, Size is slow.
+	// TODO: add Size to Marshaler, or add a Sizer interface.
+	if m, ok := pb.(Marshaler); ok {
+		b, _ := m.Marshal()
+		return len(b)
+	}
+
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return 0
+	}
+	if err == nil {
+		n = size_struct(t.Elem(), GetProperties(t.Elem()), base)
+	}
+
+	if collectStats {
+		stats.Size++
+	}
+
+	return
+}
+
+// Individual type encoders.
+
+// Encode a bool.
+func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
+	v := *structPointer_Bool(base, p.field)
+	if v == nil {
+		return ErrNil
+	}
+	x := 0
+	if *v {
+		x = 1
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func size_bool(p *Properties, base structPointer) int {
+	v := *structPointer_Bool(base, p.field)
+	if v == nil {
+		return 0
+	}
+	return len(p.tagcode) + 1 // each bool takes exactly one byte
+}
+
+// Encode an int32.
+func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return ErrNil
+	}
+	x := word32_Get(v)
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func size_int32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return 0
+	}
+	x := word32_Get(v)
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+// Encode an int64.
+func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64(base, p.field)
+	if word64_IsNil(v) {
+		return ErrNil
+	}
+	x := word64_Get(v)
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, x)
+	return nil
+}
+
+func size_int64(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word64(base, p.field)
+	if word64_IsNil(v) {
+		return 0
+	}
+	x := word64_Get(v)
+	n += len(p.tagcode)
+	n += p.valSize(x)
+	return
+}
+
+// Encode a string.
+func (o *Buffer) enc_string(p *Properties, base structPointer) error {
+	v := *structPointer_String(base, p.field)
+	if v == nil {
+		return ErrNil
+	}
+	x := *v
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeStringBytes(x)
+	return nil
+}
+
+func size_string(p *Properties, base structPointer) (n int) {
+	v := *structPointer_String(base, p.field)
+	if v == nil {
+		return 0
+	}
+	x := *v
+	n += len(p.tagcode)
+	n += sizeStringBytes(x)
+	return
+}
+
+// All protocol buffer fields are nillable, but be careful.
+func isNil(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+		return v.IsNil()
+	}
+	return false
+}
+
+// Encode a message struct.
+func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
+	var state errorState
+	structp := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(structp) {
+		return ErrNil
+	}
+
+	// Can the object marshal itself?
+	if p.isMarshaler {
+		m := structPointer_Interface(structp, p.stype).(Marshaler)
+		data, err := m.Marshal()
+		if err != nil && !state.shouldContinue(err, nil) {
+			return err
+		}
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(data)
+		return nil
+	}
+
+	// need the length before we can write out the message itself,
+	// so marshal into a separate byte buffer first.
+	obuf := o.buf
+	o.buf = o.bufalloc()
+
+	err := o.enc_struct(p.stype, p.sprop, structp)
+
+	nbuf := o.buf
+	o.buf = obuf
+	if err != nil && !state.shouldContinue(err, nil) {
+		o.buffree(nbuf)
+		return err
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeRawBytes(nbuf)
+	o.buffree(nbuf)
+	return state.err
+}
+
+func size_struct_message(p *Properties, base structPointer) int {
+	structp := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(structp) {
+		return 0
+	}
+
+	// Can the object marshal itself?
+	if p.isMarshaler {
+		m := structPointer_Interface(structp, p.stype).(Marshaler)
+		data, _ := m.Marshal()
+		n0 := len(p.tagcode)
+		n1 := sizeRawBytes(data)
+		return n0 + n1
+	}
+
+	n0 := len(p.tagcode)
+	n1 := size_struct(p.stype, p.sprop, structp)
+	n2 := sizeVarint(uint64(n1)) // size of encoded length
+	return n0 + n1 + n2
+}
+
+// Encode a group struct.
+func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
+	var state errorState
+	b := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(b) {
+		return ErrNil
+	}
+
+	o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
+	err := o.enc_struct(p.stype, p.sprop, b)
+	if err != nil && !state.shouldContinue(err, nil) {
+		return err
+	}
+	o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	return state.err
+}
+
+func size_struct_group(p *Properties, base structPointer) (n int) {
+	b := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(b) {
+		return 0
+	}
+
+	n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
+	n += size_struct(p.stype, p.sprop, b)
+	n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	return
+}
+
+// Encode a slice of bools ([]bool).
+func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return ErrNil
+	}
+	for _, x := range s {
+		o.buf = append(o.buf, p.tagcode...)
+		v := uint64(0)
+		if x {
+			v = 1
+		}
+		p.valEnc(o, v)
+	}
+	return nil
+}
+
+func size_slice_bool(p *Properties, base structPointer) int {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return 0
+	}
+	return l * (len(p.tagcode) + 1) // each bool takes exactly one byte
+}
+
+// Encode a slice of bools ([]bool) in packed format.
+func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
+	for _, x := range s {
+		v := uint64(0)
+		if x {
+			v = 1
+		}
+		p.valEnc(o, v)
+	}
+	return nil
+}
+
+func size_slice_packed_bool(p *Properties, base structPointer) (n int) {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(l))
+	n += l // each bool takes exactly one byte
+	return
+}
+
+// Encode a slice of bytes ([]byte).
+func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
+	s := *structPointer_Bytes(base, p.field)
+	if s == nil {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeRawBytes(s)
+	return nil
+}
+
+func size_slice_byte(p *Properties, base structPointer) (n int) {
+	s := *structPointer_Bytes(base, p.field)
+	if s == nil {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeRawBytes(s)
+	return
+}
+
+// Encode a slice of int32s ([]int32).
+func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		x := s.Index(i)
+		p.valEnc(o, uint64(x))
+	}
+	return nil
+}
+
+func size_slice_int32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		x := s.Index(i)
+		n += p.valSize(uint64(x))
+	}
+	return
+}
+
+// Encode a slice of int32s ([]int32) in packed format.
+func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
+		p.valEnc(buf, uint64(s.Index(i)))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		bufSize += p.valSize(uint64(s.Index(i)))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of int64s ([]int64).
+func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		p.valEnc(o, s.Index(i))
+	}
+	return nil
+}
+
+func size_slice_int64(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		n += p.valSize(s.Index(i))
+	}
+	return
+}
+
+// Encode a slice of int64s ([]int64) in packed format.
+func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
+		p.valEnc(buf, s.Index(i))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_int64(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		bufSize += p.valSize(s.Index(i))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of slice of bytes ([][]byte).
+func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
+	ss := *structPointer_BytesSlice(base, p.field)
+	l := len(ss)
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(ss[i])
+	}
+	return nil
+}
+
+func size_slice_slice_byte(p *Properties, base structPointer) (n int) {
+	ss := *structPointer_BytesSlice(base, p.field)
+	l := len(ss)
+	if l == 0 {
+		return 0
+	}
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		n += sizeRawBytes(ss[i])
+	}
+	return
+}
+
+// Encode a slice of strings ([]string).
+func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
+	ss := *structPointer_StringSlice(base, p.field)
+	l := len(ss)
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeStringBytes(ss[i])
+	}
+	return nil
+}
+
+func size_slice_string(p *Properties, base structPointer) (n int) {
+	ss := *structPointer_StringSlice(base, p.field)
+	l := len(ss)
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		n += sizeStringBytes(ss[i])
+	}
+	return
+}
+
+// Encode a slice of message structs ([]*struct).
+func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
+	var state errorState
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	for i := 0; i < l; i++ {
+		structp := s.Index(i)
+		if structPointer_IsNil(structp) {
+			return ErrRepeatedHasNil
+		}
+
+		// Can the object marshal itself?
+		if p.isMarshaler {
+			m := structPointer_Interface(structp, p.stype).(Marshaler)
+			data, err := m.Marshal()
+			if err != nil && !state.shouldContinue(err, nil) {
+				return err
+			}
+			o.buf = append(o.buf, p.tagcode...)
+			o.EncodeRawBytes(data)
+			continue
+		}
+
+		obuf := o.buf
+		o.buf = o.bufalloc()
+
+		err := o.enc_struct(p.stype, p.sprop, structp)
+
+		nbuf := o.buf
+		o.buf = obuf
+		if err != nil && !state.shouldContinue(err, nil) {
+			o.buffree(nbuf)
+			if err == ErrNil {
+				return ErrRepeatedHasNil
+			}
+			return err
+		}
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(nbuf)
+
+		o.buffree(nbuf)
+	}
+	return state.err
+}
+
+func size_slice_struct_message(p *Properties, base structPointer) (n int) {
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		structp := s.Index(i)
+		if structPointer_IsNil(structp) {
+			return // return the size up to this point
+		}
+
+		// Can the object marshal itself?
+		if p.isMarshaler {
+			m := structPointer_Interface(structp, p.stype).(Marshaler)
+			data, _ := m.Marshal()
+			n += len(p.tagcode)
+			n += sizeRawBytes(data)
+			continue
+		}
+
+		n0 := size_struct(p.stype, p.sprop, structp)
+		n1 := sizeVarint(uint64(n0)) // size of encoded length
+		n += n0 + n1
+	}
+	return
+}
+
+// Encode a slice of group structs ([]*struct).
+func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
+	var state errorState
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	for i := 0; i < l; i++ {
+		b := s.Index(i)
+		if structPointer_IsNil(b) {
+			return ErrRepeatedHasNil
+		}
+
+		o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
+
+		err := o.enc_struct(p.stype, p.sprop, b)
+
+		if err != nil && !state.shouldContinue(err, nil) {
+			if err == ErrNil {
+				return ErrRepeatedHasNil
+			}
+			return err
+		}
+
+		o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	}
+	return state.err
+}
+
+func size_slice_struct_group(p *Properties, base structPointer) (n int) {
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup))
+	n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup))
+	for i := 0; i < l; i++ {
+		b := s.Index(i)
+		if structPointer_IsNil(b) {
+			return // return size up to this point
+		}
+
+		n += size_struct(p.stype, p.sprop, b)
+	}
+	return
+}
+
+// Encode an extension map.
+func (o *Buffer) enc_map(p *Properties, base structPointer) error {
+	v := *structPointer_ExtMap(base, p.field)
+	if err := encodeExtensionMap(v); err != nil {
+		return err
+	}
+	// Fast-path for common cases: zero or one extensions.
+	if len(v) <= 1 {
+		for _, e := range v {
+			o.buf = append(o.buf, e.enc...)
+		}
+		return nil
+	}
+
+	// Sort keys to provide a deterministic encoding.
+	keys := make([]int, 0, len(v))
+	for k := range v {
+		keys = append(keys, int(k))
+	}
+	sort.Ints(keys)
+
+	for _, k := range keys {
+		o.buf = append(o.buf, v[int32(k)].enc...)
+	}
+	return nil
+}
+
+func size_map(p *Properties, base structPointer) int {
+	v := *structPointer_ExtMap(base, p.field)
+	return sizeExtensionMap(v)
+}
+
+// Encode a struct.
+func (o *Buffer) enc_struct(t reflect.Type, prop *StructProperties, base structPointer) error {
+	var state errorState
+	// Encode fields in tag order so that decoders may use optimizations
+	// that depend on the ordering.
+	// http://code.google.com/apis/protocolbuffers/docs/encoding.html#order
+	for _, i := range prop.order {
+		p := prop.Prop[i]
+		if p.enc != nil {
+			err := p.enc(o, p, base)
+			if err != nil {
+				if err == ErrNil {
+					if p.Required && state.err == nil {
+						state.err = &RequiredNotSetError{p.Name}
+					}
+				} else if !state.shouldContinue(err, p) {
+					return err
+				}
+			}
+		}
+	}
+
+	// Add unrecognized fields at the end.
+	if prop.unrecField.IsValid() {
+		v := *structPointer_Bytes(base, prop.unrecField)
+		if len(v) > 0 {
+			o.buf = append(o.buf, v...)
+		}
+	}
+
+	return state.err
+}
+
+func size_struct(t reflect.Type, prop *StructProperties, base structPointer) (n int) {
+	for _, i := range prop.order {
+		p := prop.Prop[i]
+		if p.size != nil {
+			n += p.size(p, base)
+		}
+	}
+
+	// Add unrecognized fields at the end.
+	if prop.unrecField.IsValid() {
+		v := *structPointer_Bytes(base, prop.unrecField)
+		n += len(v)
+	}
+
+	return
+}
+
+// errorState maintains the first error that occurs and updates that error
+// with additional context.
+type errorState struct {
+	err error
+}
+
+// shouldContinue reports whether encoding should continue upon encountering the
+// given error. If the error is RequiredNotSetError, shouldContinue returns true
+// and, if this is the first appearance of that error, remembers it for future
+// reporting.
+//
+// If prop is not nil, it may update any error with additional context about the
+// field with the error.
+func (s *errorState) shouldContinue(err error, prop *Properties) bool {
+	// Ignore unset required fields.
+	reqNotSet, ok := err.(*RequiredNotSetError)
+	if !ok {
+		return false
+	}
+	if s.err == nil {
+		if prop != nil {
+			err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field}
+		}
+		s.err = err
+	}
+	return true
+}

+ 367 - 0
third_party/code.google.com/p/gogoprotobuf/proto/encode_gogo.go

@@ -0,0 +1,367 @@
+// Extensions for Protocol Buffers to create more go like structures.
+//
+// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+// http://code.google.com/p/gogoprotobuf/gogoproto
+//
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+package proto
+
+import (
+	"reflect"
+)
+
+type Sizer interface {
+	Size() int
+}
+
+// Encode a reference to bool pointer.
+func (o *Buffer) enc_ref_bool(p *Properties, base structPointer) error {
+	v := structPointer_RefBool(base, p.field)
+	if v == nil {
+		return ErrNil
+	}
+	x := 0
+	if *v {
+		x = 1
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func size_ref_bool(p *Properties, base structPointer) int {
+	v := structPointer_RefBool(base, p.field)
+	if v == nil {
+		return 0
+	}
+	return len(p.tagcode) + 1 // each bool takes exactly one byte
+}
+
+// Encode a reference to int32 pointer.
+func (o *Buffer) enc_ref_int32(p *Properties, base structPointer) error {
+	v := structPointer_RefWord32(base, p.field)
+	if refWord32_IsNil(v) {
+		return ErrNil
+	}
+	x := refWord32_Get(v)
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func size_ref_int32(p *Properties, base structPointer) (n int) {
+	v := structPointer_RefWord32(base, p.field)
+	if refWord32_IsNil(v) {
+		return 0
+	}
+	x := refWord32_Get(v)
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+// Encode a reference to an int64 pointer.
+func (o *Buffer) enc_ref_int64(p *Properties, base structPointer) error {
+	v := structPointer_RefWord64(base, p.field)
+	if refWord64_IsNil(v) {
+		return ErrNil
+	}
+	x := refWord64_Get(v)
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, x)
+	return nil
+}
+
+func size_ref_int64(p *Properties, base structPointer) (n int) {
+	v := structPointer_RefWord64(base, p.field)
+	if refWord64_IsNil(v) {
+		return 0
+	}
+	x := refWord64_Get(v)
+	n += len(p.tagcode)
+	n += p.valSize(x)
+	return
+}
+
+// Encode a reference to a string pointer.
+func (o *Buffer) enc_ref_string(p *Properties, base structPointer) error {
+	v := structPointer_RefString(base, p.field)
+	if v == nil {
+		return ErrNil
+	}
+	x := *v
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeStringBytes(x)
+	return nil
+}
+
+func size_ref_string(p *Properties, base structPointer) (n int) {
+	v := structPointer_RefString(base, p.field)
+	if v == nil {
+		return 0
+	}
+	x := *v
+	n += len(p.tagcode)
+	n += sizeStringBytes(x)
+	return
+}
+
+// Encode a reference to a message struct.
+func (o *Buffer) enc_ref_struct_message(p *Properties, base structPointer) error {
+	var state errorState
+	structp := structPointer_GetRefStructPointer(base, p.field)
+	if structPointer_IsNil(structp) {
+		return ErrNil
+	}
+
+	// Can the object marshal itself?
+	if p.isMarshaler {
+		m := structPointer_Interface(structp, p.stype).(Marshaler)
+		data, err := m.Marshal()
+		if err != nil && !state.shouldContinue(err, nil) {
+			return err
+		}
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(data)
+		return nil
+	}
+
+	// need the length before we can write out the message itself,
+	// so marshal into a separate byte buffer first.
+	obuf := o.buf
+	o.buf = o.bufalloc()
+
+	err := o.enc_struct(p.stype, p.sprop, structp)
+
+	nbuf := o.buf
+	o.buf = obuf
+	if err != nil && !state.shouldContinue(err, nil) {
+		o.buffree(nbuf)
+		return err
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeRawBytes(nbuf)
+	o.buffree(nbuf)
+	return nil
+}
+
+//TODO this is only copied, please fix this
+func size_ref_struct_message(p *Properties, base structPointer) int {
+	structp := structPointer_GetRefStructPointer(base, p.field)
+	if structPointer_IsNil(structp) {
+		return 0
+	}
+
+	// Can the object marshal itself?
+	if p.isMarshaler {
+		m := structPointer_Interface(structp, p.stype).(Marshaler)
+		data, _ := m.Marshal()
+		n0 := len(p.tagcode)
+		n1 := sizeRawBytes(data)
+		return n0 + n1
+	}
+
+	n0 := len(p.tagcode)
+	n1 := size_struct(p.stype, p.sprop, structp)
+	n2 := sizeVarint(uint64(n1)) // size of encoded length
+	return n0 + n1 + n2
+}
+
+// Encode a slice of references to message struct pointers ([]struct).
+func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer) error {
+	var state errorState
+	ss := structPointer_GetStructPointer(base, p.field)
+	ss1 := structPointer_GetRefStructPointer(ss, field(0))
+	size := p.stype.Size()
+	l := structPointer_Len(base, p.field)
+	for i := 0; i < l; i++ {
+		structp := structPointer_Add(ss1, field(uintptr(i)*size))
+		if structPointer_IsNil(structp) {
+			return ErrRepeatedHasNil
+		}
+
+		// Can the object marshal itself?
+		if p.isMarshaler {
+			m := structPointer_Interface(structp, p.stype).(Marshaler)
+			data, err := m.Marshal()
+			if err != nil && !state.shouldContinue(err, nil) {
+				return err
+			}
+			o.buf = append(o.buf, p.tagcode...)
+			o.EncodeRawBytes(data)
+			continue
+		}
+
+		obuf := o.buf
+		o.buf = o.bufalloc()
+
+		err := o.enc_struct(p.stype, p.sprop, structp)
+
+		nbuf := o.buf
+		o.buf = obuf
+		if err != nil && !state.shouldContinue(err, nil) {
+			o.buffree(nbuf)
+			if err == ErrNil {
+				return ErrRepeatedHasNil
+			}
+			return err
+		}
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(nbuf)
+
+		o.buffree(nbuf)
+	}
+	return nil
+}
+
+//TODO this is only copied, please fix this
+func size_slice_ref_struct_message(p *Properties, base structPointer) (n int) {
+	ss := structPointer_GetStructPointer(base, p.field)
+	ss1 := structPointer_GetRefStructPointer(ss, field(0))
+	size := p.stype.Size()
+	l := structPointer_Len(base, p.field)
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		structp := structPointer_Add(ss1, field(uintptr(i)*size))
+		if structPointer_IsNil(structp) {
+			return // return the size up to this point
+		}
+
+		// Can the object marshal itself?
+		if p.isMarshaler {
+			m := structPointer_Interface(structp, p.stype).(Marshaler)
+			data, _ := m.Marshal()
+			n += len(p.tagcode)
+			n += sizeRawBytes(data)
+			continue
+		}
+
+		n0 := size_struct(p.stype, p.sprop, structp)
+		n1 := sizeVarint(uint64(n0)) // size of encoded length
+		n += n0 + n1
+	}
+	return
+}
+
+func (o *Buffer) enc_custom_bytes(p *Properties, base structPointer) error {
+	i := structPointer_InterfaceRef(base, p.field, p.ctype)
+	if i == nil {
+		return ErrNil
+	}
+	custom := i.(Marshaler)
+	data, err := custom.Marshal()
+	if err != nil {
+		return err
+	}
+	if data == nil {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeRawBytes(data)
+	return nil
+}
+
+func size_custom_bytes(p *Properties, base structPointer) (n int) {
+	n += len(p.tagcode)
+	i := structPointer_InterfaceRef(base, p.field, p.ctype)
+	if i == nil {
+		return 0
+	}
+	custom := i.(Marshaler)
+	data, _ := custom.Marshal()
+	n += sizeRawBytes(data)
+	return
+}
+
+func (o *Buffer) enc_custom_ref_bytes(p *Properties, base structPointer) error {
+	custom := structPointer_InterfaceAt(base, p.field, p.ctype).(Marshaler)
+	data, err := custom.Marshal()
+	if err != nil {
+		return err
+	}
+	if data == nil {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeRawBytes(data)
+	return nil
+}
+
+func size_custom_ref_bytes(p *Properties, base structPointer) (n int) {
+	n += len(p.tagcode)
+	i := structPointer_InterfaceAt(base, p.field, p.ctype)
+	if i == nil {
+		return 0
+	}
+	custom := i.(Marshaler)
+	data, _ := custom.Marshal()
+	n += sizeRawBytes(data)
+	return
+}
+
+func (o *Buffer) enc_custom_slice_bytes(p *Properties, base structPointer) error {
+	inter := structPointer_InterfaceRef(base, p.field, p.ctype)
+	if inter == nil {
+		return ErrNil
+	}
+	slice := reflect.ValueOf(inter)
+	l := slice.Len()
+	for i := 0; i < l; i++ {
+		v := slice.Index(i)
+		custom := v.Interface().(Marshaler)
+		data, err := custom.Marshal()
+		if err != nil {
+			return err
+		}
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(data)
+	}
+	return nil
+}
+
+func size_custom_slice_bytes(p *Properties, base structPointer) (n int) {
+	inter := structPointer_InterfaceRef(base, p.field, p.ctype)
+	if inter == nil {
+		return 0
+	}
+	slice := reflect.ValueOf(inter)
+	l := slice.Len()
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		v := slice.Index(i)
+		custom := v.Interface().(Marshaler)
+		data, _ := custom.Marshal()
+		n += sizeRawBytes(data)
+	}
+	return
+}

+ 241 - 0
third_party/code.google.com/p/gogoprotobuf/proto/equal.go

@@ -0,0 +1,241 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  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.
+
+// Protocol buffer comparison.
+// TODO: MessageSet.
+
+package proto
+
+import (
+	"bytes"
+	"log"
+	"reflect"
+	"strings"
+)
+
+/*
+Equal returns true iff protocol buffers a and b are equal.
+The arguments must both be pointers to protocol buffer structs.
+
+Equality is defined in this way:
+  - Two messages are equal iff they are the same type,
+    corresponding fields are equal, unknown field sets
+    are equal, and extensions sets are equal.
+  - Two set scalar fields are equal iff their values are equal.
+    If the fields are of a floating-point type, remember that
+    NaN != x for all x, including NaN.
+  - Two repeated fields are equal iff their lengths are the same,
+    and their corresponding elements are equal (a "bytes" field,
+    although represented by []byte, is not a repeated field)
+  - Two unset fields are equal.
+  - Two unknown field sets are equal if their current
+    encoded state is equal. (TODO)
+  - Two extension sets are equal iff they have corresponding
+    elements that are pairwise equal.
+  - Every other combination of things are not equal.
+
+The return value is undefined if a and b are not protocol buffers.
+*/
+func Equal(a, b Message) bool {
+	if a == nil || b == nil {
+		return a == b
+	}
+	v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b)
+	if v1.Type() != v2.Type() {
+		return false
+	}
+	if v1.Kind() == reflect.Ptr {
+		if v1.IsNil() {
+			return v2.IsNil()
+		}
+		if v2.IsNil() {
+			return false
+		}
+		v1, v2 = v1.Elem(), v2.Elem()
+	}
+	if v1.Kind() != reflect.Struct {
+		return false
+	}
+	return equalStruct(v1, v2)
+}
+
+// v1 and v2 are known to have the same type.
+func equalStruct(v1, v2 reflect.Value) bool {
+	for i := 0; i < v1.NumField(); i++ {
+		f := v1.Type().Field(i)
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+		f1, f2 := v1.Field(i), v2.Field(i)
+		if f.Type.Kind() == reflect.Ptr {
+			if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 {
+				// both unset
+				continue
+			} else if n1 != n2 {
+				// set/unset mismatch
+				return false
+			}
+			b1, ok := f1.Interface().(raw)
+			if ok {
+				b2 := f2.Interface().(raw)
+				// RawMessage
+				if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
+					return false
+				}
+				continue
+			}
+			f1, f2 = f1.Elem(), f2.Elem()
+		}
+		if !equalAny(f1, f2) {
+			return false
+		}
+	}
+
+	if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
+		em2 := v2.FieldByName("XXX_extensions")
+		if !equalExtensions(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
+			return false
+		}
+	}
+
+	uf := v1.FieldByName("XXX_unrecognized")
+	if !uf.IsValid() {
+		return true
+	}
+
+	u1 := uf.Bytes()
+	u2 := v2.FieldByName("XXX_unrecognized").Bytes()
+	if !bytes.Equal(u1, u2) {
+		return false
+	}
+
+	return true
+}
+
+// v1 and v2 are known to have the same type.
+func equalAny(v1, v2 reflect.Value) bool {
+	if v1.Type() == protoMessageType {
+		m1, _ := v1.Interface().(Message)
+		m2, _ := v2.Interface().(Message)
+		return Equal(m1, m2)
+	}
+	switch v1.Kind() {
+	case reflect.Bool:
+		return v1.Bool() == v2.Bool()
+	case reflect.Float32, reflect.Float64:
+		return v1.Float() == v2.Float()
+	case reflect.Int32, reflect.Int64:
+		return v1.Int() == v2.Int()
+	case reflect.Ptr:
+		return equalAny(v1.Elem(), v2.Elem())
+	case reflect.Slice:
+		if v1.Type().Elem().Kind() == reflect.Uint8 {
+			// short circuit: []byte
+			if v1.IsNil() != v2.IsNil() {
+				return false
+			}
+			return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))
+		}
+
+		if v1.Len() != v2.Len() {
+			return false
+		}
+		for i := 0; i < v1.Len(); i++ {
+			if !equalAny(v1.Index(i), v2.Index(i)) {
+				return false
+			}
+		}
+		return true
+	case reflect.String:
+		return v1.Interface().(string) == v2.Interface().(string)
+	case reflect.Struct:
+		return equalStruct(v1, v2)
+	case reflect.Uint32, reflect.Uint64:
+		return v1.Uint() == v2.Uint()
+	}
+
+	// unknown type, so not a protocol buffer
+	log.Printf("proto: don't know how to compare %v", v1)
+	return false
+}
+
+// base is the struct type that the extensions are based on.
+// em1 and em2 are extension maps.
+func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool {
+	if len(em1) != len(em2) {
+		return false
+	}
+
+	for extNum, e1 := range em1 {
+		e2, ok := em2[extNum]
+		if !ok {
+			return false
+		}
+
+		m1, m2 := e1.value, e2.value
+
+		if m1 != nil && m2 != nil {
+			// Both are unencoded.
+			if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) {
+				return false
+			}
+			continue
+		}
+
+		// At least one is encoded. To do a semantically correct comparison
+		// we need to unmarshal them first.
+		var desc *ExtensionDesc
+		if m := extensionMaps[base]; m != nil {
+			desc = m[extNum]
+		}
+		if desc == nil {
+			log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
+			continue
+		}
+		var err error
+		if m1 == nil {
+			m1, err = decodeExtension(e1.enc, desc)
+		}
+		if m2 == nil && err == nil {
+			m2, err = decodeExtension(e2.enc, desc)
+		}
+		if err != nil {
+			// The encoded form is invalid.
+			log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
+			return false
+		}
+		if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) {
+			return false
+		}
+	}
+
+	return true
+}

+ 166 - 0
third_party/code.google.com/p/gogoprotobuf/proto/equal_test.go

@@ -0,0 +1,166 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  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.
+
+package proto_test
+
+import (
+	"testing"
+
+	pb "./testdata"
+	. "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+)
+
+// Four identical base messages.
+// The init function adds extensions to some of them.
+var messageWithoutExtension = &pb.MyMessage{Count: Int32(7)}
+var messageWithExtension1a = &pb.MyMessage{Count: Int32(7)}
+var messageWithExtension1b = &pb.MyMessage{Count: Int32(7)}
+var messageWithExtension2 = &pb.MyMessage{Count: Int32(7)}
+
+// Two messages with non-message extensions.
+var messageWithInt32Extension1 = &pb.MyMessage{Count: Int32(8)}
+var messageWithInt32Extension2 = &pb.MyMessage{Count: Int32(8)}
+
+func init() {
+	ext1 := &pb.Ext{Data: String("Kirk")}
+	ext2 := &pb.Ext{Data: String("Picard")}
+
+	// messageWithExtension1a has ext1, but never marshals it.
+	if err := SetExtension(messageWithExtension1a, pb.E_Ext_More, ext1); err != nil {
+		panic("SetExtension on 1a failed: " + err.Error())
+	}
+
+	// messageWithExtension1b is the unmarshaled form of messageWithExtension1a.
+	if err := SetExtension(messageWithExtension1b, pb.E_Ext_More, ext1); err != nil {
+		panic("SetExtension on 1b failed: " + err.Error())
+	}
+	buf, err := Marshal(messageWithExtension1b)
+	if err != nil {
+		panic("Marshal of 1b failed: " + err.Error())
+	}
+	messageWithExtension1b.Reset()
+	if err := Unmarshal(buf, messageWithExtension1b); err != nil {
+		panic("Unmarshal of 1b failed: " + err.Error())
+	}
+
+	// messageWithExtension2 has ext2.
+	if err := SetExtension(messageWithExtension2, pb.E_Ext_More, ext2); err != nil {
+		panic("SetExtension on 2 failed: " + err.Error())
+	}
+
+	if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(23)); err != nil {
+		panic("SetExtension on Int32-1 failed: " + err.Error())
+	}
+	if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(24)); err != nil {
+		panic("SetExtension on Int32-2 failed: " + err.Error())
+	}
+}
+
+var EqualTests = []struct {
+	desc	string
+	a, b	Message
+	exp	bool
+}{
+	{"different types", &pb.GoEnum{}, &pb.GoTestField{}, false},
+	{"equal empty", &pb.GoEnum{}, &pb.GoEnum{}, true},
+	{"nil vs nil", nil, nil, true},
+	{"typed nil vs typed nil", (*pb.GoEnum)(nil), (*pb.GoEnum)(nil), true},
+	{"typed nil vs empty", (*pb.GoEnum)(nil), &pb.GoEnum{}, false},
+	{"different typed nil", (*pb.GoEnum)(nil), (*pb.GoTestField)(nil), false},
+
+	{"one set field, one unset field", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{}, false},
+	{"one set field zero, one unset field", &pb.GoTest{Param: Int32(0)}, &pb.GoTest{}, false},
+	{"different set fields", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("bar")}, false},
+	{"equal set", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("foo")}, true},
+
+	{"repeated, one set", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{}, false},
+	{"repeated, different length", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{F_Int32Repeated: []int32{2}}, false},
+	{"repeated, different value", &pb.GoTest{F_Int32Repeated: []int32{2}}, &pb.GoTest{F_Int32Repeated: []int32{3}}, false},
+	{"repeated, equal", &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, true},
+	{"repeated, nil equal nil", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: nil}, true},
+	{"repeated, nil equal empty", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: []int32{}}, true},
+	{"repeated, empty equal nil", &pb.GoTest{F_Int32Repeated: []int32{}}, &pb.GoTest{F_Int32Repeated: nil}, true},
+
+	{
+		"nested, different",
+		&pb.GoTest{RequiredField: &pb.GoTestField{Label: String("foo")}},
+		&pb.GoTest{RequiredField: &pb.GoTestField{Label: String("bar")}},
+		false,
+	},
+	{
+		"nested, equal",
+		&pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}},
+		&pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}},
+		true,
+	},
+
+	{"bytes", &pb.OtherMessage{Value: []byte("foo")}, &pb.OtherMessage{Value: []byte("foo")}, true},
+	{"bytes, empty", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: []byte{}}, true},
+	{"bytes, empty vs nil", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: nil}, false},
+	{
+		"repeated bytes",
+		&pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}},
+		&pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}},
+		true,
+	},
+
+	{"extension vs. no extension", messageWithoutExtension, messageWithExtension1a, false},
+	{"extension vs. same extension", messageWithExtension1a, messageWithExtension1b, true},
+	{"extension vs. different extension", messageWithExtension1a, messageWithExtension2, false},
+
+	{"int32 extension vs. itself", messageWithInt32Extension1, messageWithInt32Extension1, true},
+	{"int32 extension vs. a different int32", messageWithInt32Extension1, messageWithInt32Extension2, false},
+
+	{
+		"message with group",
+		&pb.MyMessage{
+			Count:	Int32(1),
+			Somegroup: &pb.MyMessage_SomeGroup{
+				GroupField: Int32(5),
+			},
+		},
+		&pb.MyMessage{
+			Count:	Int32(1),
+			Somegroup: &pb.MyMessage_SomeGroup{
+				GroupField: Int32(5),
+			},
+		},
+		true,
+	},
+}
+
+func TestEqual(t *testing.T) {
+	for _, tc := range EqualTests {
+		if res := Equal(tc.a, tc.b); res != tc.exp {
+			t.Errorf("%v: Equal(%v, %v) = %v, want %v", tc.desc, tc.a, tc.b, res, tc.exp)
+		}
+	}
+}

+ 350 - 0
third_party/code.google.com/p/gogoprotobuf/proto/extensions.go

@@ -0,0 +1,350 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+package proto
+
+/*
+ * Types and routines for supporting protocol buffer extensions.
+ */
+
+import (
+	"errors"
+	"reflect"
+	"strconv"
+	"sync"
+)
+
+// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
+var ErrMissingExtension = errors.New("proto: missing extension")
+
+// ExtensionRange represents a range of message extensions for a protocol buffer.
+// Used in code generated by the protocol compiler.
+type ExtensionRange struct {
+	Start, End int32 // both inclusive
+}
+
+// extendableProto is an interface implemented by any protocol buffer that may be extended.
+type extendableProto interface {
+	Message
+	ExtensionRangeArray() []ExtensionRange
+	ExtensionMap() map[int32]Extension
+}
+
+var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
+
+// ExtensionDesc represents an extension specification.
+// Used in generated code from the protocol compiler.
+type ExtensionDesc struct {
+	ExtendedType  Message     // nil pointer to the type that is being extended
+	ExtensionType interface{} // nil pointer to the extension type
+	Field         int32       // field number
+	Name          string      // fully-qualified name of extension, for text formatting
+	Tag           string      // protobuf tag style
+}
+
+func (ed *ExtensionDesc) repeated() bool {
+	t := reflect.TypeOf(ed.ExtensionType)
+	return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
+}
+
+// Extension represents an extension in a message.
+type Extension struct {
+	// When an extension is stored in a message using SetExtension
+	// only desc and value are set. When the message is marshaled
+	// enc will be set to the encoded form of the message.
+	//
+	// When a message is unmarshaled and contains extensions, each
+	// extension will have only enc set. When such an extension is
+	// accessed using GetExtension (or GetExtensions) desc and value
+	// will be set.
+	desc  *ExtensionDesc
+	value interface{}
+	enc   []byte
+}
+
+// SetRawExtension is for testing only.
+func SetRawExtension(base extendableProto, id int32, b []byte) {
+	base.ExtensionMap()[id] = Extension{enc: b}
+}
+
+// isExtensionField returns true iff the given field number is in an extension range.
+func isExtensionField(pb extendableProto, field int32) bool {
+	for _, er := range pb.ExtensionRangeArray() {
+		if er.Start <= field && field <= er.End {
+			return true
+		}
+	}
+	return false
+}
+
+// checkExtensionTypes checks that the given extension is valid for pb.
+func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
+	// Check the extended type.
+	if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b {
+		return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
+	}
+	// Check the range.
+	if !isExtensionField(pb, extension.Field) {
+		return errors.New("proto: bad extension number; not in declared ranges")
+	}
+	return nil
+}
+
+// extPropKey is sufficient to uniquely identify an extension.
+type extPropKey struct {
+	base  reflect.Type
+	field int32
+}
+
+var extProp = struct {
+	sync.RWMutex
+	m map[extPropKey]*Properties
+}{
+	m: make(map[extPropKey]*Properties),
+}
+
+func extensionProperties(ed *ExtensionDesc) *Properties {
+	key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
+
+	extProp.RLock()
+	if prop, ok := extProp.m[key]; ok {
+		extProp.RUnlock()
+		return prop
+	}
+	extProp.RUnlock()
+
+	extProp.Lock()
+	defer extProp.Unlock()
+	// Check again.
+	if prop, ok := extProp.m[key]; ok {
+		return prop
+	}
+
+	prop := new(Properties)
+	prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
+	extProp.m[key] = prop
+	return prop
+}
+
+// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m.
+func encodeExtensionMap(m map[int32]Extension) error {
+	for k, e := range m {
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		et := reflect.TypeOf(e.desc.ExtensionType)
+		props := extensionProperties(e.desc)
+
+		p := NewBuffer(nil)
+		// If e.value has type T, the encoder expects a *struct{ X T }.
+		// Pass a *T with a zero field and hope it all works out.
+		x := reflect.New(et)
+		x.Elem().Set(reflect.ValueOf(e.value))
+		if err := props.enc(p, props, toStructPointer(x)); err != nil {
+			return err
+		}
+		e.enc = p.buf
+		m[k] = e
+	}
+	return nil
+}
+
+func sizeExtensionMap(m map[int32]Extension) (n int) {
+	for _, e := range m {
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			n += len(e.enc)
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		et := reflect.TypeOf(e.desc.ExtensionType)
+		props := extensionProperties(e.desc)
+
+		// If e.value has type T, the encoder expects a *struct{ X T }.
+		// Pass a *T with a zero field and hope it all works out.
+		x := reflect.New(et)
+		x.Elem().Set(reflect.ValueOf(e.value))
+		n += props.size(props, toStructPointer(x))
+	}
+	return
+}
+
+// HasExtension returns whether the given extension is present in pb.
+func HasExtension(pb extendableProto, extension *ExtensionDesc) bool {
+	// TODO: Check types, field numbers, etc.?
+	_, ok := pb.ExtensionMap()[extension.Field]
+	return ok
+}
+
+// ClearExtension removes the given extension from pb.
+func ClearExtension(pb extendableProto, extension *ExtensionDesc) {
+	// TODO: Check types, field numbers, etc.?
+	delete(pb.ExtensionMap(), extension.Field)
+}
+
+// GetExtension parses and returns the given extension of pb.
+// If the extension is not present it returns ErrMissingExtension.
+// If the returned extension is modified, SetExtension must be called
+// for the modifications to be reflected in pb.
+func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
+	if err := checkExtensionTypes(pb, extension); err != nil {
+		return nil, err
+	}
+
+	e, ok := pb.ExtensionMap()[extension.Field]
+	if !ok {
+		return nil, ErrMissingExtension
+	}
+	if e.value != nil {
+		// Already decoded. Check the descriptor, though.
+		if e.desc != extension {
+			// This shouldn't happen. If it does, it means that
+			// GetExtension was called twice with two different
+			// descriptors with the same field number.
+			return nil, errors.New("proto: descriptor conflict")
+		}
+		return e.value, nil
+	}
+
+	v, err := decodeExtension(e.enc, extension)
+	if err != nil {
+		return nil, err
+	}
+
+	// Remember the decoded version and drop the encoded version.
+	// That way it is safe to mutate what we return.
+	e.value = v
+	e.desc = extension
+	e.enc = nil
+	return e.value, nil
+}
+
+// decodeExtension decodes an extension encoded in b.
+func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
+	o := NewBuffer(b)
+
+	t := reflect.TypeOf(extension.ExtensionType)
+	rep := extension.repeated()
+
+	props := extensionProperties(extension)
+
+	// t is a pointer to a struct, pointer to basic type or a slice.
+	// Allocate a "field" to store the pointer/slice itself; the
+	// pointer/slice will be stored here. We pass
+	// the address of this field to props.dec.
+	// This passes a zero field and a *t and lets props.dec
+	// interpret it as a *struct{ x t }.
+	value := reflect.New(t).Elem()
+
+	for {
+		// Discard wire type and field number varint. It isn't needed.
+		if _, err := o.DecodeVarint(); err != nil {
+			return nil, err
+		}
+
+		if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil {
+			return nil, err
+		}
+
+		if !rep || o.index >= len(o.buf) {
+			break
+		}
+	}
+	return value.Interface(), nil
+}
+
+// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
+// The returned slice has the same length as es; missing extensions will appear as nil elements.
+func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
+	epb, ok := pb.(extendableProto)
+	if !ok {
+		err = errors.New("proto: not an extendable proto")
+		return
+	}
+	extensions = make([]interface{}, len(es))
+	for i, e := range es {
+		extensions[i], err = GetExtension(epb, e)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// SetExtension sets the specified extension of pb to the specified value.
+func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error {
+	if err := checkExtensionTypes(pb, extension); err != nil {
+		return err
+	}
+	typ := reflect.TypeOf(extension.ExtensionType)
+	if typ != reflect.TypeOf(value) {
+		return errors.New("proto: bad extension value type")
+	}
+
+	pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value}
+	return nil
+}
+
+// A global registry of extensions.
+// The generated code will register the generated descriptors by calling RegisterExtension.
+
+var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
+
+// RegisterExtension is called from the generated code.
+func RegisterExtension(desc *ExtensionDesc) {
+	st := reflect.TypeOf(desc.ExtendedType).Elem()
+	m := extensionMaps[st]
+	if m == nil {
+		m = make(map[int32]*ExtensionDesc)
+		extensionMaps[st] = m
+	}
+	if _, ok := m[desc.Field]; ok {
+		panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
+	}
+	m[desc.Field] = desc
+}
+
+// RegisteredExtensions returns a map of the registered extensions of a
+// protocol buffer struct, indexed by the extension number.
+// The argument pb should be a nil pointer to the struct type.
+func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
+	return extensionMaps[reflect.TypeOf(pb).Elem()]
+}

+ 94 - 0
third_party/code.google.com/p/gogoprotobuf/proto/extensions_gogo.go

@@ -0,0 +1,94 @@
+// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+// http://code.google.com/p/gogoprotobuf/gogoproto
+//
+// 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.
+//
+// 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.
+
+package proto
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+	"sort"
+)
+
+func GetBoolExtension(pb extendableProto, extension *ExtensionDesc, ifnotset bool) bool {
+	if reflect.ValueOf(pb).IsNil() {
+		return ifnotset
+	}
+	value, err := GetExtension(pb, extension)
+	if err != nil {
+		return ifnotset
+	}
+	if value == nil {
+		return ifnotset
+	}
+	if value.(*bool) == nil {
+		return ifnotset
+	}
+	return *(value.(*bool))
+}
+
+func (this *Extension) Equal(that *Extension) bool {
+	return bytes.Equal(this.enc, that.enc)
+}
+
+func SizeOfExtensionMap(m map[int32]Extension) (n int) {
+	return sizeExtensionMap(m)
+}
+
+func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) {
+	if err := encodeExtensionMap(m); err != nil {
+		return 0, err
+	}
+	keys := make([]int, 0, len(m))
+	for k := range m {
+		keys = append(keys, int(k))
+	}
+	sort.Ints(keys)
+	for _, k := range keys {
+		n += copy(data[n:], m[int32(k)].enc)
+	}
+	return n, nil
+}
+
+func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) {
+	if m[id].value == nil || m[id].desc == nil {
+		return m[id].enc, nil
+	}
+	if err := encodeExtensionMap(m); err != nil {
+		return nil, err
+	}
+	return m[id].enc, nil
+}
+
+func NewExtension(e []byte) Extension {
+	ee := Extension{enc: make([]byte, len(e))}
+	copy(ee.enc, e)
+	return ee
+}
+
+func (this Extension) GoString() string {
+	return fmt.Sprintf("proto.NewExtension(%#v)", this.enc)
+}

+ 789 - 0
third_party/code.google.com/p/gogoprotobuf/proto/lib.go

@@ -0,0 +1,789 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+/*
+	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:
+
+	  - Names are turned from camel_case to CamelCase for export.
+	  - There are no methods on v to set fields; just treat
+	  	them as structure fields.
+	  - There are getters that return a field's value if set,
+		and return the field's default value if unset.
+		The getters work even if the receiver is a nil message.
+	  - The zero value for a struct is its correct initialization state.
+		All desired fields must be set before marshaling.
+	  - A Reset() method will restore a protobuf struct to its zero state.
+	  - Non-repeated fields are pointers to the values; nil means unset.
+		That is, optional or required field int32 f becomes F *int32.
+	  - Repeated fields are slices.
+	  - Helper functions are available to aid the setting of fields.
+		Helpers for getting values are superseded by the
+		GetFoo methods and their use is deprecated.
+			msg.Foo = proto.String("hello") // set field
+	  - Constants are defined to hold the default values of all fields that
+		have them.  They have the form Default_StructName_FieldName.
+		Because the getter methods handle defaulted values,
+		direct use of these constants should be rare.
+	  - 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_,
+		followed by an underscore-delimited list of the nested messages
+		that contain it (if any) followed by the CamelCased name of the
+		extension field itself.  HasExtension, ClearExtension, GetExtension
+		and SetExtension are functions for manipulating extensions.
+	  - Marshal and Unmarshal are functions to encode and decode the wire format.
+
+	The simplest way to describe this is to see an example.
+	Given file test.proto, containing
+
+		package example;
+
+		enum FOO { X = 17; };
+
+		message Test {
+		  required string label = 1;
+		  optional int32 type = 2 [default=77];
+		  repeated int64 reps = 3;
+		  optional group OptionalGroup = 4 {
+		    required string RequiredField = 5;
+		  }
+		}
+
+	The resulting file, test.pb.go, is:
+
+		package example
+
+		import "code.google.com/p/gogoprotobuf/proto"
+
+		type FOO int32
+		const (
+			FOO_X FOO = 17
+		)
+		var FOO_name = map[int32]string{
+			17: "X",
+		}
+		var FOO_value = map[string]int32{
+			"X": 17,
+		}
+
+		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" 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) String() string { return proto.CompactTextString(this) }
+		const Default_Test_Type int32 = 77
+
+		func (this *Test) GetLabel() string {
+			if this != nil && this.Label != nil {
+				return *this.Label
+			}
+			return ""
+		}
+
+		func (this *Test) GetType() int32 {
+			if this != nil && this.Type != nil {
+				return *this.Type
+			}
+			return Default_Test_Type
+		}
+
+		func (this *Test) GetOptionalgroup() *Test_OptionalGroup {
+			if this != nil {
+				return this.Optionalgroup
+			}
+			return nil
+		}
+
+		type Test_OptionalGroup struct {
+			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) String() string { return proto.CompactTextString(this) }
+
+		func (this *Test_OptionalGroup) GetRequiredField() string {
+			if this != nil && this.RequiredField != nil {
+				return *this.RequiredField
+			}
+			return ""
+		}
+
+		func init() {
+			proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
+		}
+
+	To create and play with a Test object:
+
+		package main
+
+		import (
+			"log"
+
+			"code.google.com/p/gogoprotobuf/proto"
+			"./example.pb"
+		)
+
+		func main() {
+			test := &example.Test{
+				Label: proto.String("hello"),
+				Type:  proto.Int32(17),
+				Optionalgroup: &example.Test_OptionalGroup{
+					RequiredField: proto.String("good bye"),
+				},
+			}
+			data, err := proto.Marshal(test)
+			if err != nil {
+				log.Fatal("marshaling error: ", err)
+			}
+			newTest := new(example.Test)
+			err = proto.Unmarshal(data, newTest)
+			if err != nil {
+				log.Fatal("unmarshaling error: ", err)
+			}
+			// Now test and newTest contain the same data.
+			if test.GetLabel() != newTest.GetLabel() {
+				log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
+			}
+			// etc.
+		}
+*/
+package proto
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"reflect"
+	"strconv"
+	"sync"
+)
+
+// Message is implemented by generated protocol buffer messages.
+type Message interface {
+	Reset()
+	String() string
+	ProtoMessage()
+}
+
+// Stats records allocation details about the protocol buffer encoders
+// and decoders.  Useful for tuning the library itself.
+type Stats struct {
+	Emalloc uint64 // mallocs in encode
+	Dmalloc uint64 // mallocs in decode
+	Encode  uint64 // number of encodes
+	Decode  uint64 // number of decodes
+	Chit    uint64 // number of cache hits
+	Cmiss   uint64 // number of cache misses
+	Size    uint64 // number of sizes
+}
+
+// Set to true to enable stats collection.
+const collectStats = false
+
+var stats Stats
+
+// GetStats returns a copy of the global Stats structure.
+func GetStats() Stats { return stats }
+
+// A Buffer is a buffer manager for marshaling and unmarshaling
+// protocol buffers.  It may be reused between invocations to
+// reduce memory usage.  It is not necessary to use a Buffer;
+// the global functions Marshal and Unmarshal create a
+// temporary Buffer and are fine for most applications.
+type Buffer struct {
+	buf       []byte     // encode/decode byte stream
+	index     int        // write point
+	freelist  [10][]byte // list of available buffers
+	nfreelist int        // number of free buffers
+
+	// pools of basic types to amortize allocation.
+	bools   []bool
+	uint32s []uint32
+	uint64s []uint64
+
+	// extra pools, only used with pointer_reflect.go
+	int32s   []int32
+	int64s   []int64
+	float32s []float32
+	float64s []float64
+}
+
+// NewBuffer allocates a new Buffer and initializes its internal data to
+// the contents of the argument slice.
+func NewBuffer(e []byte) *Buffer {
+	p := new(Buffer)
+	if e == nil {
+		e = p.bufalloc()
+	}
+	p.buf = e
+	p.index = 0
+	return p
+}
+
+// Reset resets the Buffer, ready for marshaling a new protocol buffer.
+func (p *Buffer) Reset() {
+	if p.buf == nil {
+		p.buf = p.bufalloc()
+	}
+	p.buf = p.buf[0:0] // for reading/writing
+	p.index = 0        // for reading
+}
+
+// SetBuf replaces the internal buffer with the slice,
+// ready for unmarshaling the contents of the slice.
+func (p *Buffer) SetBuf(s []byte) {
+	p.buf = s
+	p.index = 0
+}
+
+// Bytes returns the contents of the Buffer.
+func (p *Buffer) Bytes() []byte { return p.buf }
+
+// Allocate a buffer for the Buffer.
+func (p *Buffer) bufalloc() []byte {
+	if p.nfreelist > 0 {
+		// reuse an old one
+		p.nfreelist--
+		s := p.freelist[p.nfreelist]
+		return s[0:0]
+	}
+	// make a new one
+	s := make([]byte, 0, 16)
+	return s
+}
+
+// Free (and remember in freelist) a byte buffer for the Buffer.
+func (p *Buffer) buffree(s []byte) {
+	if p.nfreelist < len(p.freelist) {
+		// Take next slot.
+		p.freelist[p.nfreelist] = s
+		p.nfreelist++
+		return
+	}
+
+	// Find the smallest.
+	besti := -1
+	bestl := len(s)
+	for i, b := range p.freelist {
+		if len(b) < bestl {
+			besti = i
+			bestl = len(b)
+		}
+	}
+
+	// Overwrite the smallest.
+	if besti >= 0 {
+		p.freelist[besti] = s
+	}
+}
+
+/*
+ * Helper routines for simplifying the creation of optional fields of basic type.
+ */
+
+// Bool is a helper routine that allocates a new bool value
+// to store v and returns a pointer to it.
+func Bool(v bool) *bool {
+	return &v
+}
+
+// Int32 is a helper routine that allocates a new int32 value
+// to store v and returns a pointer to it.
+func Int32(v int32) *int32 {
+	return &v
+}
+
+// Int is a helper routine that allocates a new int32 value
+// to store v and returns a pointer to it, but unlike Int32
+// its argument value is an int.
+func Int(v int) *int32 {
+	p := new(int32)
+	*p = int32(v)
+	return p
+}
+
+// Int64 is a helper routine that allocates a new int64 value
+// to store v and returns a pointer to it.
+func Int64(v int64) *int64 {
+	return &v
+}
+
+// Float32 is a helper routine that allocates a new float32 value
+// to store v and returns a pointer to it.
+func Float32(v float32) *float32 {
+	return &v
+}
+
+// Float64 is a helper routine that allocates a new float64 value
+// to store v and returns a pointer to it.
+func Float64(v float64) *float64 {
+	return &v
+}
+
+// Uint32 is a helper routine that allocates a new uint32 value
+// to store v and returns a pointer to it.
+func Uint32(v uint32) *uint32 {
+	p := new(uint32)
+	*p = v
+	return p
+}
+
+// Uint64 is a helper routine that allocates a new uint64 value
+// to store v and returns a pointer to it.
+func Uint64(v uint64) *uint64 {
+	return &v
+}
+
+// String is a helper routine that allocates a new string value
+// to store v and returns a pointer to it.
+func String(v string) *string {
+	return &v
+}
+
+// EnumName is a helper function to simplify printing protocol buffer enums
+// by name.  Given an enum map and a value, it returns a useful string.
+func EnumName(m map[int32]string, v int32) string {
+	s, ok := m[v]
+	if ok {
+		return s
+	}
+	return strconv.Itoa(int(v))
+}
+
+// UnmarshalJSONEnum is a helper function to simplify recovering enum int values
+// from their JSON-encoded representation. Given a map from the enum's symbolic
+// names to its int values, and a byte buffer containing the JSON-encoded
+// value, it returns an int32 that can be cast to the enum type by the caller.
+//
+// The function can deal with both JSON representations, numeric and symbolic.
+func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
+	if data[0] == '"' {
+		// New style: enums are strings.
+		var repr string
+		if err := json.Unmarshal(data, &repr); err != nil {
+			return -1, err
+		}
+		val, ok := m[repr]
+		if !ok {
+			return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
+		}
+		return val, nil
+	}
+	// Old style: enums are ints.
+	var val int32
+	if err := json.Unmarshal(data, &val); err != nil {
+		return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
+	}
+	return val, nil
+}
+
+// DebugPrint dumps the encoded data in b in a debugging format with a header
+// including the string s. Used in testing but made available for general debugging.
+func (o *Buffer) DebugPrint(s string, b []byte) {
+	var u uint64
+
+	obuf := o.buf
+	index := o.index
+	o.buf = b
+	o.index = 0
+	depth := 0
+
+	fmt.Printf("\n--- %s ---\n", s)
+
+out:
+	for {
+		for i := 0; i < depth; i++ {
+			fmt.Print("  ")
+		}
+
+		index := o.index
+		if index == len(o.buf) {
+			break
+		}
+
+		op, err := o.DecodeVarint()
+		if err != nil {
+			fmt.Printf("%3d: fetching op err %v\n", index, err)
+			break out
+		}
+		tag := op >> 3
+		wire := op & 7
+
+		switch wire {
+		default:
+			fmt.Printf("%3d: t=%3d unknown wire=%d\n",
+				index, tag, wire)
+			break out
+
+		case WireBytes:
+			var r []byte
+
+			r, err = o.DecodeRawBytes(false)
+			if err != nil {
+				break out
+			}
+			fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
+			if len(r) <= 6 {
+				for i := 0; i < len(r); i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+			} else {
+				for i := 0; i < 3; i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+				fmt.Printf(" ..")
+				for i := len(r) - 3; i < len(r); i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+			}
+			fmt.Printf("\n")
+
+		case WireFixed32:
+			u, err = o.DecodeFixed32()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
+
+		case WireFixed64:
+			u, err = o.DecodeFixed64()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
+			break
+
+		case WireVarint:
+			u, err = o.DecodeVarint()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
+
+		case WireStartGroup:
+			if err != nil {
+				fmt.Printf("%3d: t=%3d start err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d start\n", index, tag)
+			depth++
+
+		case WireEndGroup:
+			depth--
+			if err != nil {
+				fmt.Printf("%3d: t=%3d end err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d end\n", index, tag)
+		}
+	}
+
+	if depth != 0 {
+		fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth)
+	}
+	fmt.Printf("\n")
+
+	o.buf = obuf
+	o.index = index
+}
+
+// SetDefaults sets unset protocol buffer fields to their default values.
+// It only modifies fields that are both unset and have defined defaults.
+// It recursively sets default values in any non-nil sub-messages.
+func SetDefaults(pb Message) {
+	setDefaults(reflect.ValueOf(pb), true, false)
+}
+
+// v is a pointer to a struct.
+func setDefaults(v reflect.Value, recur, zeros bool) {
+	v = v.Elem()
+
+	defaultMu.RLock()
+	dm, ok := defaults[v.Type()]
+	defaultMu.RUnlock()
+	if !ok {
+		dm = buildDefaultMessage(v.Type())
+		defaultMu.Lock()
+		defaults[v.Type()] = dm
+		defaultMu.Unlock()
+	}
+
+	for _, sf := range dm.scalars {
+		f := v.Field(sf.index)
+		if !f.IsNil() {
+			// field already set
+			continue
+		}
+		dv := sf.value
+		if dv == nil && !zeros {
+			// no explicit default, and don't want to set zeros
+			continue
+		}
+		fptr := f.Addr().Interface() // **T
+		// TODO: Consider batching the allocations we do here.
+		switch sf.kind {
+		case reflect.Bool:
+			b := new(bool)
+			if dv != nil {
+				*b = dv.(bool)
+			}
+			*(fptr.(**bool)) = b
+		case reflect.Float32:
+			f := new(float32)
+			if dv != nil {
+				*f = dv.(float32)
+			}
+			*(fptr.(**float32)) = f
+		case reflect.Float64:
+			f := new(float64)
+			if dv != nil {
+				*f = dv.(float64)
+			}
+			*(fptr.(**float64)) = f
+		case reflect.Int32:
+			// might be an enum
+			if ft := f.Type(); ft != int32PtrType {
+				// enum
+				f.Set(reflect.New(ft.Elem()))
+				if dv != nil {
+					f.Elem().SetInt(int64(dv.(int32)))
+				}
+			} else {
+				// int32 field
+				i := new(int32)
+				if dv != nil {
+					*i = dv.(int32)
+				}
+				*(fptr.(**int32)) = i
+			}
+		case reflect.Int64:
+			i := new(int64)
+			if dv != nil {
+				*i = dv.(int64)
+			}
+			*(fptr.(**int64)) = i
+		case reflect.String:
+			s := new(string)
+			if dv != nil {
+				*s = dv.(string)
+			}
+			*(fptr.(**string)) = s
+		case reflect.Uint8:
+			// exceptional case: []byte
+			var b []byte
+			if dv != nil {
+				db := dv.([]byte)
+				b = make([]byte, len(db))
+				copy(b, db)
+			} else {
+				b = []byte{}
+			}
+			*(fptr.(*[]byte)) = b
+		case reflect.Uint32:
+			u := new(uint32)
+			if dv != nil {
+				*u = dv.(uint32)
+			}
+			*(fptr.(**uint32)) = u
+		case reflect.Uint64:
+			u := new(uint64)
+			if dv != nil {
+				*u = dv.(uint64)
+			}
+			*(fptr.(**uint64)) = u
+		default:
+			log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
+		}
+	}
+
+	for _, ni := range dm.nested {
+		f := v.Field(ni)
+		if f.IsNil() {
+			continue
+		}
+		// f is *T or []*T
+		if f.Kind() == reflect.Ptr {
+			setDefaults(f, recur, zeros)
+		} else {
+			for i := 0; i < f.Len(); i++ {
+				e := f.Index(i)
+				if e.IsNil() {
+					continue
+				}
+				setDefaults(e, recur, zeros)
+			}
+		}
+	}
+}
+
+var (
+	// defaults maps a protocol buffer struct type to a slice of the fields,
+	// with its scalar fields set to their proto-declared non-zero default values.
+	defaultMu sync.RWMutex
+	defaults  = make(map[reflect.Type]defaultMessage)
+
+	int32PtrType = reflect.TypeOf((*int32)(nil))
+)
+
+// defaultMessage represents information about the default values of a message.
+type defaultMessage struct {
+	scalars []scalarField
+	nested  []int // struct field index of nested messages
+}
+
+type scalarField struct {
+	index int          // struct field index
+	kind  reflect.Kind // element type (the T in *T or []T)
+	value interface{}  // the proto-declared default value, or nil
+}
+
+func ptrToStruct(t reflect.Type) bool {
+	return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct
+}
+
+// t is a struct type.
+func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
+	sprop := GetProperties(t)
+	for _, prop := range sprop.Prop {
+		fi, ok := sprop.decoderTags.get(prop.Tag)
+		if !ok {
+			// XXX_unrecognized
+			continue
+		}
+		ft := t.Field(fi).Type
+
+		// nested messages
+		if ptrToStruct(ft) || (ft.Kind() == reflect.Slice && ptrToStruct(ft.Elem())) {
+			dm.nested = append(dm.nested, fi)
+			continue
+		}
+
+		sf := scalarField{
+			index: fi,
+			kind:  ft.Elem().Kind(),
+		}
+
+		// scalar fields without defaults
+		if prop.Default == "" {
+			dm.scalars = append(dm.scalars, sf)
+			continue
+		}
+
+		// a scalar field: either *T or []byte
+		switch ft.Elem().Kind() {
+		case reflect.Bool:
+			x, err := strconv.ParseBool(prop.Default)
+			if err != nil {
+				log.Printf("proto: bad default bool %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = x
+		case reflect.Float32:
+			x, err := strconv.ParseFloat(prop.Default, 32)
+			if err != nil {
+				log.Printf("proto: bad default float32 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = float32(x)
+		case reflect.Float64:
+			x, err := strconv.ParseFloat(prop.Default, 64)
+			if err != nil {
+				log.Printf("proto: bad default float64 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = x
+		case reflect.Int32:
+			x, err := strconv.ParseInt(prop.Default, 10, 32)
+			if err != nil {
+				log.Printf("proto: bad default int32 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = int32(x)
+		case reflect.Int64:
+			x, err := strconv.ParseInt(prop.Default, 10, 64)
+			if err != nil {
+				log.Printf("proto: bad default int64 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = x
+		case reflect.String:
+			sf.value = prop.Default
+		case reflect.Uint8:
+			// []byte (not *uint8)
+			sf.value = []byte(prop.Default)
+		case reflect.Uint32:
+			x, err := strconv.ParseUint(prop.Default, 10, 32)
+			if err != nil {
+				log.Printf("proto: bad default uint32 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = uint32(x)
+		case reflect.Uint64:
+			x, err := strconv.ParseUint(prop.Default, 10, 64)
+			if err != nil {
+				log.Printf("proto: bad default uint64 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = x
+		default:
+			log.Printf("proto: unhandled def kind %v", ft.Elem().Kind())
+			continue
+		}
+
+		dm.scalars = append(dm.scalars, sf)
+	}
+
+	return dm
+}

+ 40 - 0
third_party/code.google.com/p/gogoprotobuf/proto/lib_gogo.go

@@ -0,0 +1,40 @@
+// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+// http://code.google.com/p/gogoprotobuf/gogoproto
+//
+// 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.
+//
+// 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.
+
+package proto
+
+import (
+	"encoding/json"
+	"strconv"
+)
+
+func MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) {
+	s, ok := m[value]
+	if !ok {
+		s = strconv.Itoa(int(value))
+	}
+	return json.Marshal(s)
+}

+ 216 - 0
third_party/code.google.com/p/gogoprotobuf/proto/message_set.go

@@ -0,0 +1,216 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+package proto
+
+/*
+ * Support for message sets.
+ */
+
+import (
+	"errors"
+	"reflect"
+	"sort"
+)
+
+// ErrNoMessageTypeId occurs when a protocol buffer does not have a message type ID.
+// A message type ID is required for storing a protocol buffer in a message set.
+var ErrNoMessageTypeId = errors.New("proto does not have a message type ID")
+
+// The first two types (_MessageSet_Item and MessageSet)
+// model what the protocol compiler produces for the following protocol message:
+//   message MessageSet {
+//     repeated group Item = 1 {
+//       required int32 type_id = 2;
+//       required string message = 3;
+//     };
+//   }
+// That is the MessageSet wire format. We can't use a proto to generate these
+// because that would introduce a circular dependency between it and this package.
+//
+// When a proto1 proto has a field that looks like:
+//   optional message<MessageSet> info = 3;
+// the protocol compiler produces a field in the generated struct that looks like:
+//   Info *_proto_.MessageSet  `protobuf:"bytes,3,opt,name=info"`
+// The package is automatically inserted so there is no need for that proto file to
+// import this package.
+
+type _MessageSet_Item struct {
+	TypeId  *int32 `protobuf:"varint,2,req,name=type_id"`
+	Message []byte `protobuf:"bytes,3,req,name=message"`
+}
+
+type MessageSet struct {
+	Item             []*_MessageSet_Item `protobuf:"group,1,rep"`
+	XXX_unrecognized []byte
+	// TODO: caching?
+}
+
+// Make sure MessageSet is a Message.
+var _ Message = (*MessageSet)(nil)
+
+// messageTypeIder is an interface satisfied by a protocol buffer type
+// that may be stored in a MessageSet.
+type messageTypeIder interface {
+	MessageTypeId() int32
+}
+
+func (ms *MessageSet) find(pb Message) *_MessageSet_Item {
+	mti, ok := pb.(messageTypeIder)
+	if !ok {
+		return nil
+	}
+	id := mti.MessageTypeId()
+	for _, item := range ms.Item {
+		if *item.TypeId == id {
+			return item
+		}
+	}
+	return nil
+}
+
+func (ms *MessageSet) Has(pb Message) bool {
+	if ms.find(pb) != nil {
+		return true
+	}
+	return false
+}
+
+func (ms *MessageSet) Unmarshal(pb Message) error {
+	if item := ms.find(pb); item != nil {
+		return Unmarshal(item.Message, pb)
+	}
+	if _, ok := pb.(messageTypeIder); !ok {
+		return ErrNoMessageTypeId
+	}
+	return nil // TODO: return error instead?
+}
+
+func (ms *MessageSet) Marshal(pb Message) error {
+	msg, err := Marshal(pb)
+	if err != nil {
+		return err
+	}
+	if item := ms.find(pb); item != nil {
+		// reuse existing item
+		item.Message = msg
+		return nil
+	}
+
+	mti, ok := pb.(messageTypeIder)
+	if !ok {
+		return ErrWrongType // TODO: custom error?
+	}
+
+	mtid := mti.MessageTypeId()
+	ms.Item = append(ms.Item, &_MessageSet_Item{
+		TypeId:  &mtid,
+		Message: msg,
+	})
+	return nil
+}
+
+func (ms *MessageSet) Reset()         { *ms = MessageSet{} }
+func (ms *MessageSet) String() string { return CompactTextString(ms) }
+func (*MessageSet) ProtoMessage()     {}
+
+// Support for the message_set_wire_format message option.
+
+func skipVarint(buf []byte) []byte {
+	i := 0
+	for ; buf[i]&0x80 != 0; i++ {
+	}
+	return buf[i+1:]
+}
+
+// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
+// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
+func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
+	if err := encodeExtensionMap(m); err != nil {
+		return nil, err
+	}
+
+	// Sort extension IDs to provide a deterministic encoding.
+	// See also enc_map in encode.go.
+	ids := make([]int, 0, len(m))
+	for id := range m {
+		ids = append(ids, int(id))
+	}
+	sort.Ints(ids)
+
+	ms := &MessageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
+	for _, id := range ids {
+		e := m[int32(id)]
+		// Remove the wire type and field number varint, as well as the length varint.
+		msg := skipVarint(skipVarint(e.enc))
+
+		ms.Item = append(ms.Item, &_MessageSet_Item{
+			TypeId:  Int32(int32(id)),
+			Message: msg,
+		})
+	}
+	return Marshal(ms)
+}
+
+// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
+// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
+func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
+	ms := new(MessageSet)
+	if err := Unmarshal(buf, ms); err != nil {
+		return err
+	}
+	for _, item := range ms.Item {
+		// restore wire type and field number varint, plus length varint.
+		b := EncodeVarint(uint64(*item.TypeId)<<3 | WireBytes)
+		b = append(b, EncodeVarint(uint64(len(item.Message)))...)
+		b = append(b, item.Message...)
+
+		m[*item.TypeId] = Extension{enc: b}
+	}
+	return nil
+}
+
+// A global registry of types that can be used in a MessageSet.
+
+var messageSetMap = make(map[int32]messageSetDesc)
+
+type messageSetDesc struct {
+	t    reflect.Type // pointer to struct
+	name string
+}
+
+// RegisterMessageSetType is called from the generated code.
+func RegisterMessageSetType(i messageTypeIder, name string) {
+	messageSetMap[i.MessageTypeId()] = messageSetDesc{
+		t:    reflect.TypeOf(i),
+		name: name,
+	}
+}

+ 384 - 0
third_party/code.google.com/p/gogoprotobuf/proto/pointer_reflect.go

@@ -0,0 +1,384 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors.  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.
+
+// +build appengine
+
+// This file contains an implementation of proto field accesses using package reflect.
+// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
+// be used on App Engine.
+
+package proto
+
+import (
+	"math"
+	"reflect"
+)
+
+// A structPointer is a pointer to a struct.
+type structPointer struct {
+	v reflect.Value
+}
+
+// toStructPointer returns a structPointer equivalent to the given reflect value.
+// The reflect value must itself be a pointer to a struct.
+func toStructPointer(v reflect.Value) structPointer {
+	return structPointer{v}
+}
+
+// IsNil reports whether p is nil.
+func structPointer_IsNil(p structPointer) bool {
+	return p.v.IsNil()
+}
+
+// Interface returns the struct pointer as an interface value.
+func structPointer_Interface(p structPointer, _ reflect.Type) interface{} {
+	return p.v.Interface()
+}
+
+// A field identifies a field in a struct, accessible from a structPointer.
+// In this implementation, a field is identified by the sequence of field indices
+// passed to reflect's FieldByIndex.
+type field []int
+
+// toField returns a field equivalent to the given reflect field.
+func toField(f *reflect.StructField) field {
+	return f.Index
+}
+
+// invalidField is an invalid field identifier.
+var invalidField = field(nil)
+
+// IsValid reports whether the field identifier is valid.
+func (f field) IsValid() bool { return f != nil }
+
+// field returns the given field in the struct as a reflect value.
+func structPointer_field(p structPointer, f field) reflect.Value {
+	// Special case: an extension map entry with a value of type T
+	// passes a *T to the struct-handling code with a zero field,
+	// expecting that it will be treated as equivalent to *struct{ X T },
+	// which has the same memory layout. We have to handle that case
+	// specially, because reflect will panic if we call FieldByIndex on a
+	// non-struct.
+	if f == nil {
+		return p.v.Elem()
+	}
+
+	return p.v.Elem().FieldByIndex(f)
+}
+
+// ifield returns the given field in the struct as an interface value.
+func structPointer_ifield(p structPointer, f field) interface{} {
+	return structPointer_field(p, f).Addr().Interface()
+}
+
+// Bytes returns the address of a []byte field in the struct.
+func structPointer_Bytes(p structPointer, f field) *[]byte {
+	return structPointer_ifield(p, f).(*[]byte)
+}
+
+// BytesSlice returns the address of a [][]byte field in the struct.
+func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
+	return structPointer_ifield(p, f).(*[][]byte)
+}
+
+// Bool returns the address of a *bool field in the struct.
+func structPointer_Bool(p structPointer, f field) **bool {
+	return structPointer_ifield(p, f).(**bool)
+}
+
+// BoolSlice returns the address of a []bool field in the struct.
+func structPointer_BoolSlice(p structPointer, f field) *[]bool {
+	return structPointer_ifield(p, f).(*[]bool)
+}
+
+// String returns the address of a *string field in the struct.
+func structPointer_String(p structPointer, f field) **string {
+	return structPointer_ifield(p, f).(**string)
+}
+
+// StringSlice returns the address of a []string field in the struct.
+func structPointer_StringSlice(p structPointer, f field) *[]string {
+	return structPointer_ifield(p, f).(*[]string)
+}
+
+// ExtMap returns the address of an extension map field in the struct.
+func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
+	return structPointer_ifield(p, f).(*map[int32]Extension)
+}
+
+// SetStructPointer writes a *struct field in the struct.
+func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
+	structPointer_field(p, f).Set(q.v)
+}
+
+// GetStructPointer reads a *struct field in the struct.
+func structPointer_GetStructPointer(p structPointer, f field) structPointer {
+	return structPointer{structPointer_field(p, f)}
+}
+
+// StructPointerSlice the address of a []*struct field in the struct.
+func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice {
+	return structPointerSlice{structPointer_field(p, f)}
+}
+
+// A structPointerSlice represents the address of a slice of pointers to structs
+// (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
+type structPointerSlice struct {
+	v reflect.Value
+}
+
+func (p structPointerSlice) Len() int                  { return p.v.Len() }
+func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} }
+func (p structPointerSlice) Append(q structPointer) {
+	p.v.Set(reflect.Append(p.v, q.v))
+}
+
+var (
+	int32Type   = reflect.TypeOf(int32(0))
+	uint32Type  = reflect.TypeOf(uint32(0))
+	float32Type = reflect.TypeOf(float32(0))
+	int64Type   = reflect.TypeOf(int64(0))
+	uint64Type  = reflect.TypeOf(uint64(0))
+	float64Type = reflect.TypeOf(float64(0))
+)
+
+// A word32 represents a field of type *int32, *uint32, *float32, or *enum.
+// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable.
+type word32 struct {
+	v reflect.Value
+}
+
+// IsNil reports whether p is nil.
+func word32_IsNil(p word32) bool {
+	return p.v.IsNil()
+}
+
+// Set sets p to point at a newly allocated word with bits set to x.
+func word32_Set(p word32, o *Buffer, x uint32) {
+	t := p.v.Type().Elem()
+	switch t {
+	case int32Type:
+		if len(o.int32s) == 0 {
+			o.int32s = make([]int32, uint32PoolSize)
+		}
+		o.int32s[0] = int32(x)
+		p.v.Set(reflect.ValueOf(&o.int32s[0]))
+		o.int32s = o.int32s[1:]
+		return
+	case uint32Type:
+		if len(o.uint32s) == 0 {
+			o.uint32s = make([]uint32, uint32PoolSize)
+		}
+		o.uint32s[0] = x
+		p.v.Set(reflect.ValueOf(&o.uint32s[0]))
+		o.uint32s = o.uint32s[1:]
+		return
+	case float32Type:
+		if len(o.float32s) == 0 {
+			o.float32s = make([]float32, uint32PoolSize)
+		}
+		o.float32s[0] = math.Float32frombits(x)
+		p.v.Set(reflect.ValueOf(&o.float32s[0]))
+		o.float32s = o.float32s[1:]
+		return
+	}
+
+	// must be enum
+	p.v.Set(reflect.New(t))
+	p.v.Elem().SetInt(int64(int32(x)))
+}
+
+// Get gets the bits pointed at by p, as a uint32.
+func word32_Get(p word32) uint32 {
+	elem := p.v.Elem()
+	switch elem.Kind() {
+	case reflect.Int32:
+		return uint32(elem.Int())
+	case reflect.Uint32:
+		return uint32(elem.Uint())
+	case reflect.Float32:
+		return math.Float32bits(float32(elem.Float()))
+	}
+	panic("unreachable")
+}
+
+// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
+func structPointer_Word32(p structPointer, f field) word32 {
+	return word32{structPointer_field(p, f)}
+}
+
+// A word32Slice is a slice of 32-bit values.
+// That is, v.Type() is []int32, []uint32, []float32, or []enum.
+type word32Slice struct {
+	v reflect.Value
+}
+
+func (p word32Slice) Append(x uint32) {
+	n, m := p.v.Len(), p.v.Cap()
+	if n < m {
+		p.v.SetLen(n + 1)
+	} else {
+		t := p.v.Type().Elem()
+		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
+	}
+	elem := p.v.Index(n)
+	switch elem.Kind() {
+	case reflect.Int32:
+		elem.SetInt(int64(int32(x)))
+	case reflect.Uint32:
+		elem.SetUint(uint64(x))
+	case reflect.Float32:
+		elem.SetFloat(float64(math.Float32frombits(x)))
+	}
+}
+
+func (p word32Slice) Len() int {
+	return p.v.Len()
+}
+
+func (p word32Slice) Index(i int) uint32 {
+	elem := p.v.Index(i)
+	switch elem.Kind() {
+	case reflect.Int32:
+		return uint32(elem.Int())
+	case reflect.Uint32:
+		return uint32(elem.Uint())
+	case reflect.Float32:
+		return math.Float32bits(float32(elem.Float()))
+	}
+	panic("unreachable")
+}
+
+// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
+func structPointer_Word32Slice(p structPointer, f field) word32Slice {
+	return word32Slice{structPointer_field(p, f)}
+}
+
+// word64 is like word32 but for 64-bit values.
+type word64 struct {
+	v reflect.Value
+}
+
+func word64_Set(p word64, o *Buffer, x uint64) {
+	t := p.v.Type().Elem()
+	switch t {
+	case int64Type:
+		if len(o.int64s) == 0 {
+			o.int64s = make([]int64, uint64PoolSize)
+		}
+		o.int64s[0] = int64(x)
+		p.v.Set(reflect.ValueOf(&o.int64s[0]))
+		o.int64s = o.int64s[1:]
+		return
+	case uint64Type:
+		if len(o.uint64s) == 0 {
+			o.uint64s = make([]uint64, uint64PoolSize)
+		}
+		o.uint64s[0] = x
+		p.v.Set(reflect.ValueOf(&o.uint64s[0]))
+		o.uint64s = o.uint64s[1:]
+		return
+	case float64Type:
+		if len(o.float64s) == 0 {
+			o.float64s = make([]float64, uint64PoolSize)
+		}
+		o.float64s[0] = math.Float64frombits(x)
+		p.v.Set(reflect.ValueOf(&o.float64s[0]))
+		o.float64s = o.float64s[1:]
+		return
+	}
+	panic("unreachable")
+}
+
+func word64_IsNil(p word64) bool {
+	return p.v.IsNil()
+}
+
+func word64_Get(p word64) uint64 {
+	elem := p.v.Elem()
+	switch elem.Kind() {
+	case reflect.Int64:
+		return uint64(elem.Int())
+	case reflect.Uint64:
+		return elem.Uint()
+	case reflect.Float64:
+		return math.Float64bits(elem.Float())
+	}
+	panic("unreachable")
+}
+
+func structPointer_Word64(p structPointer, f field) word64 {
+	return word64{structPointer_field(p, f)}
+}
+
+type word64Slice struct {
+	v reflect.Value
+}
+
+func (p word64Slice) Append(x uint64) {
+	n, m := p.v.Len(), p.v.Cap()
+	if n < m {
+		p.v.SetLen(n + 1)
+	} else {
+		t := p.v.Type().Elem()
+		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
+	}
+	elem := p.v.Index(n)
+	switch elem.Kind() {
+	case reflect.Int64:
+		elem.SetInt(int64(int64(x)))
+	case reflect.Uint64:
+		elem.SetUint(uint64(x))
+	case reflect.Float64:
+		elem.SetFloat(float64(math.Float64frombits(x)))
+	}
+}
+
+func (p word64Slice) Len() int {
+	return p.v.Len()
+}
+
+func (p word64Slice) Index(i int) uint64 {
+	elem := p.v.Index(i)
+	switch elem.Kind() {
+	case reflect.Int64:
+		return uint64(elem.Int())
+	case reflect.Uint64:
+		return uint64(elem.Uint())
+	case reflect.Float64:
+		return math.Float64bits(float64(elem.Float()))
+	}
+	panic("unreachable")
+}
+
+func structPointer_Word64Slice(p structPointer, f field) word64Slice {
+	return word64Slice{structPointer_field(p, f)}
+}

+ 218 - 0
third_party/code.google.com/p/gogoprotobuf/proto/pointer_unsafe.go

@@ -0,0 +1,218 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors.  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.
+
+// +build !appengine
+
+// This file contains the implementation of the proto field accesses using package unsafe.
+
+package proto
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+// NOTE: These type_Foo functions would more idiomatically be methods,
+// but Go does not allow methods on pointer types, and we must preserve
+// some pointer type for the garbage collector. We use these
+// funcs with clunky names as our poor approximation to methods.
+//
+// An alternative would be
+//	type structPointer struct { p unsafe.Pointer }
+// but that does not registerize as well.
+
+// A structPointer is a pointer to a struct.
+type structPointer unsafe.Pointer
+
+// toStructPointer returns a structPointer equivalent to the given reflect value.
+func toStructPointer(v reflect.Value) structPointer {
+	return structPointer(unsafe.Pointer(v.Pointer()))
+}
+
+// IsNil reports whether p is nil.
+func structPointer_IsNil(p structPointer) bool {
+	return p == nil
+}
+
+// Interface returns the struct pointer, assumed to have element type t,
+// as an interface value.
+func structPointer_Interface(p structPointer, t reflect.Type) interface{} {
+	return reflect.NewAt(t, unsafe.Pointer(p)).Interface()
+}
+
+// A field identifies a field in a struct, accessible from a structPointer.
+// In this implementation, a field is identified by its byte offset from the start of the struct.
+type field uintptr
+
+// toField returns a field equivalent to the given reflect field.
+func toField(f *reflect.StructField) field {
+	return field(f.Offset)
+}
+
+// invalidField is an invalid field identifier.
+const invalidField = ^field(0)
+
+// IsValid reports whether the field identifier is valid.
+func (f field) IsValid() bool {
+	return f != ^field(0)
+}
+
+// Bytes returns the address of a []byte field in the struct.
+func structPointer_Bytes(p structPointer, f field) *[]byte {
+	return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// BytesSlice returns the address of a [][]byte field in the struct.
+func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
+	return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// Bool returns the address of a *bool field in the struct.
+func structPointer_Bool(p structPointer, f field) **bool {
+	return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// BoolSlice returns the address of a []bool field in the struct.
+func structPointer_BoolSlice(p structPointer, f field) *[]bool {
+	return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// String returns the address of a *string field in the struct.
+func structPointer_String(p structPointer, f field) **string {
+	return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// StringSlice returns the address of a []string field in the struct.
+func structPointer_StringSlice(p structPointer, f field) *[]string {
+	return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// ExtMap returns the address of an extension map field in the struct.
+func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
+	return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// SetStructPointer writes a *struct field in the struct.
+func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
+	*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
+}
+
+// GetStructPointer reads a *struct field in the struct.
+func structPointer_GetStructPointer(p structPointer, f field) structPointer {
+	return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// StructPointerSlice the address of a []*struct field in the struct.
+func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice {
+	return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups).
+type structPointerSlice []structPointer
+
+func (v *structPointerSlice) Len() int                  { return len(*v) }
+func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] }
+func (v *structPointerSlice) Append(p structPointer)    { *v = append(*v, p) }
+
+// A word32 is the address of a "pointer to 32-bit value" field.
+type word32 **uint32
+
+// IsNil reports whether *v is nil.
+func word32_IsNil(p word32) bool {
+	return *p == nil
+}
+
+// Set sets *v to point at a newly allocated word set to x.
+func word32_Set(p word32, o *Buffer, x uint32) {
+	if len(o.uint32s) == 0 {
+		o.uint32s = make([]uint32, uint32PoolSize)
+	}
+	o.uint32s[0] = x
+	*p = &o.uint32s[0]
+	o.uint32s = o.uint32s[1:]
+}
+
+// Get gets the value pointed at by *v.
+func word32_Get(p word32) uint32 {
+	return **p
+}
+
+// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
+func structPointer_Word32(p structPointer, f field) word32 {
+	return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+}
+
+// A word32Slice is a slice of 32-bit values.
+type word32Slice []uint32
+
+func (v *word32Slice) Append(x uint32)    { *v = append(*v, x) }
+func (v *word32Slice) Len() int           { return len(*v) }
+func (v *word32Slice) Index(i int) uint32 { return (*v)[i] }
+
+// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct.
+func structPointer_Word32Slice(p structPointer, f field) *word32Slice {
+	return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// word64 is like word32 but for 64-bit values.
+type word64 **uint64
+
+func word64_Set(p word64, o *Buffer, x uint64) {
+	if len(o.uint64s) == 0 {
+		o.uint64s = make([]uint64, uint64PoolSize)
+	}
+	o.uint64s[0] = x
+	*p = &o.uint64s[0]
+	o.uint64s = o.uint64s[1:]
+}
+
+func word64_IsNil(p word64) bool {
+	return *p == nil
+}
+
+func word64_Get(p word64) uint64 {
+	return **p
+}
+
+func structPointer_Word64(p structPointer, f field) word64 {
+	return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+}
+
+// word64Slice is like word32Slice but for 64-bit values.
+type word64Slice []uint64
+
+func (v *word64Slice) Append(x uint64)    { *v = append(*v, x) }
+func (v *word64Slice) Len() int           { return len(*v) }
+func (v *word64Slice) Index(i int) uint64 { return (*v)[i] }
+
+func structPointer_Word64Slice(p structPointer, f field) *word64Slice {
+	return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}

+ 159 - 0
third_party/code.google.com/p/gogoprotobuf/proto/pointer_unsafe_gogo.go

@@ -0,0 +1,159 @@
+// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+// http://code.google.com/p/gogoprotobuf/gogoproto
+//
+// 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.
+//
+// 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.
+
+// +build !appengine
+
+// This file contains the implementation of the proto field accesses using package unsafe.
+
+package proto
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+func structPointer_InterfaceAt(p structPointer, f field, t reflect.Type) interface{} {
+	point := unsafe.Pointer(uintptr(p) + uintptr(f))
+	r := reflect.NewAt(t, point)
+	return r.Interface()
+}
+
+func structPointer_InterfaceRef(p structPointer, f field, t reflect.Type) interface{} {
+	point := unsafe.Pointer(uintptr(p) + uintptr(f))
+	r := reflect.NewAt(t, point)
+	if r.Elem().IsNil() {
+		return nil
+	}
+	return r.Elem().Interface()
+}
+
+func copyUintPtr(oldptr, newptr uintptr, size int) {
+	for j := 0; j < size; j++ {
+		oldb := (*byte)(unsafe.Pointer(oldptr + uintptr(j)))
+		*(*byte)(unsafe.Pointer(newptr + uintptr(j))) = *oldb
+	}
+}
+
+func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) {
+	copyUintPtr(uintptr(oldptr), uintptr(newptr), size)
+}
+
+func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer {
+	size := typ.Elem().Size()
+	oldHeader := structPointer_GetSliceHeader(base, f)
+	newLen := oldHeader.Len + 1
+	slice := reflect.MakeSlice(typ, newLen, newLen)
+	bas := toStructPointer(slice)
+	for i := 0; i < oldHeader.Len; i++ {
+		newElemptr := uintptr(bas) + uintptr(i)*size
+		oldElemptr := oldHeader.Data + uintptr(i)*size
+		copyUintPtr(oldElemptr, newElemptr, int(size))
+	}
+
+	oldHeader.Data = uintptr(bas)
+	oldHeader.Len = newLen
+	oldHeader.Cap = newLen
+
+	return structPointer(unsafe.Pointer(uintptr(unsafe.Pointer(bas)) + uintptr(uintptr(newLen-1)*size)))
+}
+
+// RefBool returns a *bool field in the struct.
+func structPointer_RefBool(p structPointer, f field) *bool {
+	return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// RefString returns the address of a string field in the struct.
+func structPointer_RefString(p structPointer, f field) *string {
+	return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+func structPointer_FieldPointer(p structPointer, f field) structPointer {
+	return structPointer(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+func structPointer_GetRefStructPointer(p structPointer, f field) structPointer {
+	return structPointer((*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+}
+
+func structPointer_GetSliceHeader(p structPointer, f field) *reflect.SliceHeader {
+	return (*reflect.SliceHeader)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+func structPointer_Add(p structPointer, size field) structPointer {
+	return structPointer(unsafe.Pointer(uintptr(p) + uintptr(size)))
+}
+
+func structPointer_Len(p structPointer, f field) int {
+	return len(*(*[]interface{})(unsafe.Pointer(structPointer_GetRefStructPointer(p, f))))
+}
+
+// refWord32 is the address of a 32-bit value field.
+type refWord32 *uint32
+
+func refWord32_IsNil(p refWord32) bool {
+	return p == nil
+}
+
+func refWord32_Set(p refWord32, o *Buffer, x uint32) {
+	if len(o.uint32s) == 0 {
+		o.uint32s = make([]uint32, uint32PoolSize)
+	}
+	o.uint32s[0] = x
+	*p = o.uint32s[0]
+	o.uint32s = o.uint32s[1:]
+}
+
+func refWord32_Get(p refWord32) uint32 {
+	return *p
+}
+
+func structPointer_RefWord32(p structPointer, f field) refWord32 {
+	return refWord32((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+}
+
+// refWord64 is like refWord32 but for 32-bit values.
+type refWord64 *uint64
+
+func refWord64_Set(p refWord64, o *Buffer, x uint64) {
+	if len(o.uint64s) == 0 {
+		o.uint64s = make([]uint64, uint64PoolSize)
+	}
+	o.uint64s[0] = x
+	*p = o.uint64s[0]
+	o.uint64s = o.uint64s[1:]
+}
+
+func refWord64_IsNil(p refWord64) bool {
+	return p == nil
+}
+
+func refWord64_Get(p refWord64) uint64 {
+	return *p
+}
+
+func structPointer_RefWord64(p structPointer, f field) refWord64 {
+	return refWord64((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+}

+ 664 - 0
third_party/code.google.com/p/gogoprotobuf/proto/properties.go

@@ -0,0 +1,664 @@
+// Extensions for Protocol Buffers to create more go like structures.
+//
+// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+// http://code.google.com/p/gogoprotobuf/gogoproto
+//
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+package proto
+
+/*
+ * Routines for encoding data into the wire format for protocol buffers.
+ */
+
+import (
+	"fmt"
+	"os"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+)
+
+const debug bool = false
+
+// Constants that identify the encoding of a value on the wire.
+const (
+	WireVarint     = 0
+	WireFixed64    = 1
+	WireBytes      = 2
+	WireStartGroup = 3
+	WireEndGroup   = 4
+	WireFixed32    = 5
+)
+
+const startSize = 10 // initial slice/string sizes
+
+// Encoders are defined in encode.go
+// An encoder outputs the full representation of a field, including its
+// tag and encoder type.
+type encoder func(p *Buffer, prop *Properties, base structPointer) error
+
+// A valueEncoder encodes a single integer in a particular encoding.
+type valueEncoder func(o *Buffer, x uint64) error
+
+// Sizers are defined in encode.go
+// A sizer returns the encoded size of a field, including its tag and encoder
+// type.
+type sizer func(prop *Properties, base structPointer) int
+
+// A valueSizer returns the encoded size of a single integer in a particular
+// encoding.
+type valueSizer func(x uint64) int
+
+// Decoders are defined in decode.go
+// A decoder creates a value from its wire representation.
+// Unrecognized subelements are saved in unrec.
+type decoder func(p *Buffer, prop *Properties, base structPointer) error
+
+// A valueDecoder decodes a single integer in a particular encoding.
+type valueDecoder func(o *Buffer) (x uint64, err error)
+
+// tagMap is an optimization over map[int]int for typical protocol buffer
+// use-cases. Encoded protocol buffers are often in tag order with small tag
+// numbers.
+type tagMap struct {
+	fastTags []int
+	slowTags map[int]int
+}
+
+// tagMapFastLimit is the upper bound on the tag number that will be stored in
+// the tagMap slice rather than its map.
+const tagMapFastLimit = 1024
+
+func (p *tagMap) get(t int) (int, bool) {
+	if t > 0 && t < tagMapFastLimit {
+		if t >= len(p.fastTags) {
+			return 0, false
+		}
+		fi := p.fastTags[t]
+		return fi, fi >= 0
+	}
+	fi, ok := p.slowTags[t]
+	return fi, ok
+}
+
+func (p *tagMap) put(t int, fi int) {
+	if t > 0 && t < tagMapFastLimit {
+		for len(p.fastTags) < t+1 {
+			p.fastTags = append(p.fastTags, -1)
+		}
+		p.fastTags[t] = fi
+		return
+	}
+	if p.slowTags == nil {
+		p.slowTags = make(map[int]int)
+	}
+	p.slowTags[t] = fi
+}
+
+// StructProperties represents properties for all the fields of a struct.
+// decoderTags and decoderOrigNames should only be used by the decoder.
+type StructProperties struct {
+	Prop             []*Properties  // properties for each field
+	reqCount         int            // required count
+	decoderTags      tagMap         // map from proto tag to struct field number
+	decoderOrigNames map[string]int // map from original name to struct field number
+	order            []int          // list of struct field numbers in tag order
+	unrecField       field          // field id of the XXX_unrecognized []byte field
+	extendable       bool           // is this an extendable proto
+}
+
+// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
+// See encode.go, (*Buffer).enc_struct.
+
+func (sp *StructProperties) Len() int { return len(sp.order) }
+func (sp *StructProperties) Less(i, j int) bool {
+	return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
+}
+func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
+
+// Properties represents the protocol-specific behavior of a single struct field.
+type Properties struct {
+	Name       string // name of the field, for error messages
+	OrigName   string // original name before protocol compiler (always set)
+	Wire       string
+	WireType   int
+	Tag        int
+	Required   bool
+	Optional   bool
+	Repeated   bool
+	Packed     bool   // relevant for repeated primitives only
+	Enum       string // set for enum types only
+	Default    string // default value
+	CustomType string
+	def_uint64 uint64
+
+	enc           encoder
+	valEnc        valueEncoder // set for bool and numeric types only
+	field         field
+	tagcode       []byte // encoding of EncodeVarint((Tag<<3)|WireType)
+	tagbuf        [8]byte
+	stype         reflect.Type      // set for struct types only
+	sstype        reflect.Type      // set for slices of structs types only
+	ctype         reflect.Type      // set for custom types only
+	sprop         *StructProperties // set for struct types only
+	isMarshaler   bool
+	isUnmarshaler bool
+
+	size    sizer
+	valSize valueSizer // set for bool and numeric types only
+
+	dec    decoder
+	valDec valueDecoder // set for bool and numeric types only
+
+	// If this is a packable field, this will be the decoder for the packed version of the field.
+	packedDec decoder
+}
+
+// String formats the properties in the protobuf struct field tag style.
+func (p *Properties) String() string {
+	s := p.Wire
+	s = ","
+	s += strconv.Itoa(p.Tag)
+	if p.Required {
+		s += ",req"
+	}
+	if p.Optional {
+		s += ",opt"
+	}
+	if p.Repeated {
+		s += ",rep"
+	}
+	if p.Packed {
+		s += ",packed"
+	}
+	if p.OrigName != p.Name {
+		s += ",name=" + p.OrigName
+	}
+	if len(p.Enum) > 0 {
+		s += ",enum=" + p.Enum
+	}
+	if len(p.Default) > 0 {
+		s += ",def=" + p.Default
+	}
+	return s
+}
+
+// Parse populates p by parsing a string in the protobuf struct field tag style.
+func (p *Properties) Parse(s string) {
+	// "bytes,49,opt,name=foo,def=hello!"
+	fields := strings.Split(s, ",") // breaks def=, but handled below.
+	if len(fields) < 2 {
+		fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
+		return
+	}
+
+	p.Wire = fields[0]
+	switch p.Wire {
+	case "varint":
+		p.WireType = WireVarint
+		p.valEnc = (*Buffer).EncodeVarint
+		p.valDec = (*Buffer).DecodeVarint
+		p.valSize = sizeVarint
+	case "fixed32":
+		p.WireType = WireFixed32
+		p.valEnc = (*Buffer).EncodeFixed32
+		p.valDec = (*Buffer).DecodeFixed32
+		p.valSize = sizeFixed32
+	case "fixed64":
+		p.WireType = WireFixed64
+		p.valEnc = (*Buffer).EncodeFixed64
+		p.valDec = (*Buffer).DecodeFixed64
+		p.valSize = sizeFixed64
+	case "zigzag32":
+		p.WireType = WireVarint
+		p.valEnc = (*Buffer).EncodeZigzag32
+		p.valDec = (*Buffer).DecodeZigzag32
+		p.valSize = sizeZigzag32
+	case "zigzag64":
+		p.WireType = WireVarint
+		p.valEnc = (*Buffer).EncodeZigzag64
+		p.valDec = (*Buffer).DecodeZigzag64
+		p.valSize = sizeZigzag64
+	case "bytes", "group":
+		p.WireType = WireBytes
+		// no numeric converter for non-numeric types
+	default:
+		fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
+		return
+	}
+
+	var err error
+	p.Tag, err = strconv.Atoi(fields[1])
+	if err != nil {
+		return
+	}
+
+	for i := 2; i < len(fields); i++ {
+		f := fields[i]
+		switch {
+		case f == "req":
+			p.Required = true
+		case f == "opt":
+			p.Optional = true
+		case f == "rep":
+			p.Repeated = true
+		case f == "packed":
+			p.Packed = true
+		case strings.HasPrefix(f, "name="):
+			p.OrigName = f[5:]
+		case strings.HasPrefix(f, "enum="):
+			p.Enum = f[5:]
+		case strings.HasPrefix(f, "def="):
+			p.Default = f[4:] // rest of string
+			if i+1 < len(fields) {
+				// Commas aren't escaped, and def is always last.
+				p.Default += "," + strings.Join(fields[i+1:], ",")
+				break
+			}
+		case strings.HasPrefix(f, "embedded="):
+			p.OrigName = strings.Split(f, "=")[1]
+		case strings.HasPrefix(f, "customtype="):
+			p.CustomType = strings.Split(f, "=")[1]
+		}
+	}
+}
+
+func logNoSliceEnc(t1, t2 reflect.Type) {
+	fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
+}
+
+var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
+
+// Initialize the fields for encoding and decoding.
+func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
+	p.enc = nil
+	p.dec = nil
+	p.size = nil
+	if len(p.CustomType) > 0 {
+		p.setCustomEncAndDec(typ)
+		p.setTag(lockGetProp)
+		return
+	}
+	switch t1 := typ; t1.Kind() {
+	default:
+		if !p.setNonNullableEncAndDec(t1) {
+			fmt.Fprintf(os.Stderr, "proto: no coders for %T\n", t1)
+		}
+	case reflect.Ptr:
+		switch t2 := t1.Elem(); t2.Kind() {
+		default:
+			fmt.Fprintf(os.Stderr, "proto: no encoder function for %T -> %T\n", t1, t2)
+			break
+		case reflect.Bool:
+			p.enc = (*Buffer).enc_bool
+			p.dec = (*Buffer).dec_bool
+			p.size = size_bool
+		case reflect.Int32, reflect.Uint32:
+			p.enc = (*Buffer).enc_int32
+			p.dec = (*Buffer).dec_int32
+			p.size = size_int32
+		case reflect.Int64, reflect.Uint64:
+			p.enc = (*Buffer).enc_int64
+			p.dec = (*Buffer).dec_int64
+			p.size = size_int64
+		case reflect.Float32:
+			p.enc = (*Buffer).enc_int32 // can just treat them as bits
+			p.dec = (*Buffer).dec_int32
+			p.size = size_int32
+		case reflect.Float64:
+			p.enc = (*Buffer).enc_int64 // can just treat them as bits
+			p.dec = (*Buffer).dec_int64
+			p.size = size_int64
+		case reflect.String:
+			p.enc = (*Buffer).enc_string
+			p.dec = (*Buffer).dec_string
+			p.size = size_string
+		case reflect.Struct:
+			p.stype = t1.Elem()
+			p.isMarshaler = isMarshaler(t1)
+			p.isUnmarshaler = isUnmarshaler(t1)
+			if p.Wire == "bytes" {
+				p.enc = (*Buffer).enc_struct_message
+				p.dec = (*Buffer).dec_struct_message
+				p.size = size_struct_message
+			} else {
+				p.enc = (*Buffer).enc_struct_group
+				p.dec = (*Buffer).dec_struct_group
+				p.size = size_struct_group
+			}
+		}
+
+	case reflect.Slice:
+		switch t2 := t1.Elem(); t2.Kind() {
+		default:
+			logNoSliceEnc(t1, t2)
+			break
+		case reflect.Bool:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_bool
+				p.size = size_slice_packed_bool
+			} else {
+				p.enc = (*Buffer).enc_slice_bool
+				p.size = size_slice_bool
+			}
+			p.dec = (*Buffer).dec_slice_bool
+			p.packedDec = (*Buffer).dec_slice_packed_bool
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+			switch t2.Bits() {
+			case 32:
+				if p.Packed {
+					p.enc = (*Buffer).enc_slice_packed_int32
+					p.size = size_slice_packed_int32
+				} else {
+					p.enc = (*Buffer).enc_slice_int32
+					p.size = size_slice_int32
+				}
+				p.dec = (*Buffer).dec_slice_int32
+				p.packedDec = (*Buffer).dec_slice_packed_int32
+			case 64:
+				if p.Packed {
+					p.enc = (*Buffer).enc_slice_packed_int64
+					p.size = size_slice_packed_int64
+				} else {
+					p.enc = (*Buffer).enc_slice_int64
+					p.size = size_slice_int64
+				}
+				p.dec = (*Buffer).dec_slice_int64
+				p.packedDec = (*Buffer).dec_slice_packed_int64
+			case 8:
+				if t2.Kind() == reflect.Uint8 {
+					p.enc = (*Buffer).enc_slice_byte
+					p.dec = (*Buffer).dec_slice_byte
+					p.size = size_slice_byte
+				}
+			default:
+				logNoSliceEnc(t1, t2)
+				break
+			}
+		case reflect.Float32, reflect.Float64:
+			switch t2.Bits() {
+			case 32:
+				// can just treat them as bits
+				if p.Packed {
+					p.enc = (*Buffer).enc_slice_packed_int32
+					p.size = size_slice_packed_int32
+				} else {
+					p.enc = (*Buffer).enc_slice_int32
+					p.size = size_slice_int32
+				}
+				p.dec = (*Buffer).dec_slice_int32
+				p.packedDec = (*Buffer).dec_slice_packed_int32
+			case 64:
+				// can just treat them as bits
+				if p.Packed {
+					p.enc = (*Buffer).enc_slice_packed_int64
+					p.size = size_slice_packed_int64
+				} else {
+					p.enc = (*Buffer).enc_slice_int64
+					p.size = size_slice_int64
+				}
+				p.dec = (*Buffer).dec_slice_int64
+				p.packedDec = (*Buffer).dec_slice_packed_int64
+			default:
+				logNoSliceEnc(t1, t2)
+				break
+			}
+		case reflect.String:
+			p.enc = (*Buffer).enc_slice_string
+			p.dec = (*Buffer).dec_slice_string
+			p.size = size_slice_string
+		case reflect.Ptr:
+			switch t3 := t2.Elem(); t3.Kind() {
+			default:
+				fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
+				break
+			case reflect.Struct:
+				p.stype = t2.Elem()
+				p.isMarshaler = isMarshaler(t2)
+				p.isUnmarshaler = isUnmarshaler(t2)
+				if p.Wire == "bytes" {
+					p.enc = (*Buffer).enc_slice_struct_message
+					p.dec = (*Buffer).dec_slice_struct_message
+					p.size = size_slice_struct_message
+				} else {
+					p.enc = (*Buffer).enc_slice_struct_group
+					p.dec = (*Buffer).dec_slice_struct_group
+					p.size = size_slice_struct_group
+				}
+			}
+		case reflect.Slice:
+			switch t2.Elem().Kind() {
+			default:
+				fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
+				break
+			case reflect.Uint8:
+				p.enc = (*Buffer).enc_slice_slice_byte
+				p.dec = (*Buffer).dec_slice_slice_byte
+				p.size = size_slice_slice_byte
+			}
+		case reflect.Struct:
+			p.setSliceOfNonPointerStructs(t1)
+		}
+	}
+	p.setTag(lockGetProp)
+}
+
+func (p *Properties) setTag(lockGetProp bool) {
+	// precalculate tag code
+	wire := p.WireType
+	if p.Packed {
+		wire = WireBytes
+	}
+	x := uint32(p.Tag)<<3 | uint32(wire)
+	i := 0
+	for i = 0; x > 127; i++ {
+		p.tagbuf[i] = 0x80 | uint8(x&0x7F)
+		x >>= 7
+	}
+	p.tagbuf[i] = uint8(x)
+	p.tagcode = p.tagbuf[0 : i+1]
+
+	if p.stype != nil {
+		if lockGetProp {
+			p.sprop = GetProperties(p.stype)
+		} else {
+			p.sprop = getPropertiesLocked(p.stype)
+		}
+	}
+}
+
+var (
+	marshalerType   = reflect.TypeOf((*Marshaler)(nil)).Elem()
+	unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
+)
+
+// isMarshaler reports whether type t implements Marshaler.
+func isMarshaler(t reflect.Type) bool {
+	return t.Implements(marshalerType)
+}
+
+// isUnmarshaler reports whether type t implements Unmarshaler.
+func isUnmarshaler(t reflect.Type) bool {
+	return t.Implements(unmarshalerType)
+}
+
+// Init populates the properties from a protocol buffer struct tag.
+func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
+	p.init(typ, name, tag, f, true)
+}
+
+func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
+	// "bytes,49,opt,def=hello!"
+	p.Name = name
+	p.OrigName = name
+	if f != nil {
+		p.field = toField(f)
+	}
+	if tag == "" {
+		return
+	}
+	p.Parse(tag)
+	p.setEncAndDec(typ, lockGetProp)
+}
+
+var (
+	mutex         sync.Mutex
+	propertiesMap = make(map[reflect.Type]*StructProperties)
+)
+
+// GetProperties returns the list of properties for the type represented by t.
+func GetProperties(t reflect.Type) *StructProperties {
+	mutex.Lock()
+	sprop := getPropertiesLocked(t)
+	mutex.Unlock()
+	return sprop
+}
+
+// getPropertiesLocked requires that mutex is held.
+func getPropertiesLocked(t reflect.Type) *StructProperties {
+	if prop, ok := propertiesMap[t]; ok {
+		if collectStats {
+			stats.Chit++
+		}
+		return prop
+	}
+	if collectStats {
+		stats.Cmiss++
+	}
+
+	prop := new(StructProperties)
+	// in case of recursive protos, fill this in now.
+	propertiesMap[t] = prop
+
+	// build properties
+	prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType)
+	prop.unrecField = invalidField
+	prop.Prop = make([]*Properties, t.NumField())
+	prop.order = make([]int, t.NumField())
+
+	for i := 0; i < t.NumField(); i++ {
+		f := t.Field(i)
+		p := new(Properties)
+		name := f.Name
+		p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
+
+		if f.Name == "XXX_extensions" { // special case
+			p.enc = (*Buffer).enc_map
+			p.dec = nil // not needed
+			p.size = size_map
+		}
+		if f.Name == "XXX_unrecognized" { // special case
+			prop.unrecField = toField(&f)
+		}
+		prop.Prop[i] = p
+		prop.order[i] = i
+		if debug {
+			print(i, " ", f.Name, " ", t.String(), " ")
+			if p.Tag > 0 {
+				print(p.String())
+			}
+			print("\n")
+		}
+		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") {
+			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
+		}
+	}
+
+	// Re-order prop.order.
+	sort.Sort(prop)
+
+	// build required counts
+	// build tags
+	reqCount := 0
+	prop.decoderOrigNames = make(map[string]int)
+	for i, p := range prop.Prop {
+		if strings.HasPrefix(p.Name, "XXX_") {
+			// Internal fields should not appear in tags/origNames maps.
+			// They are handled specially when encoding and decoding.
+			continue
+		}
+		if p.Required {
+			reqCount++
+		}
+		prop.decoderTags.put(p.Tag, i)
+		prop.decoderOrigNames[p.OrigName] = i
+	}
+	prop.reqCount = reqCount
+
+	return prop
+}
+
+// Return the Properties object for the x[0]'th field of the structure.
+func propByIndex(t reflect.Type, x []int) *Properties {
+	if len(x) != 1 {
+		fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
+		return nil
+	}
+	prop := GetProperties(t)
+	return prop.Prop[x[0]]
+}
+
+// Get the address and type of a pointer to a struct from an interface.
+func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
+	if pb == nil {
+		err = ErrNil
+		return
+	}
+	// get the reflect type of the pointer to the struct.
+	t = reflect.TypeOf(pb)
+	// get the address of the struct.
+	value := reflect.ValueOf(pb)
+	b = toStructPointer(value)
+	return
+}
+
+// A global registry of enum types.
+// The generated code will register the generated maps by calling RegisterEnum.
+
+var enumValueMaps = make(map[string]map[string]int32)
+var enumStringMaps = make(map[string]map[int32]string)
+
+// RegisterEnum is called from the generated code to install the enum descriptor
+// maps into the global table to aid parsing text format protocol buffers.
+func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
+	if _, ok := enumValueMaps[typeName]; ok {
+		panic("proto: duplicate enum registered: " + typeName)
+	}
+	enumValueMaps[typeName] = valueMap
+	if _, ok := enumStringMaps[typeName]; ok {
+		panic("proto: duplicate enum registered: " + typeName)
+	}
+	enumStringMaps[typeName] = unusedNameMap
+}

+ 107 - 0
third_party/code.google.com/p/gogoprotobuf/proto/properties_gogo.go

@@ -0,0 +1,107 @@
+// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+// http://code.google.com/p/gogoprotobuf/gogoproto
+//
+// 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.
+//
+// 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.
+
+package proto
+
+import (
+	"fmt"
+	"os"
+	"reflect"
+)
+
+func (p *Properties) setCustomEncAndDec(typ reflect.Type) {
+	p.ctype = typ
+	if p.Repeated {
+		p.enc = (*Buffer).enc_custom_slice_bytes
+		p.dec = (*Buffer).dec_custom_slice_bytes
+		p.size = size_custom_slice_bytes
+	} else if typ.Kind() == reflect.Ptr {
+		p.enc = (*Buffer).enc_custom_bytes
+		p.dec = (*Buffer).dec_custom_bytes
+		p.size = size_custom_bytes
+	} else {
+		p.enc = (*Buffer).enc_custom_ref_bytes
+		p.dec = (*Buffer).dec_custom_ref_bytes
+		p.size = size_custom_ref_bytes
+	}
+}
+
+func (p *Properties) setNonNullableEncAndDec(typ reflect.Type) bool {
+	switch typ.Kind() {
+	case reflect.Bool:
+		p.enc = (*Buffer).enc_ref_bool
+		p.dec = (*Buffer).dec_ref_bool
+		p.size = size_ref_bool
+	case reflect.Int32, reflect.Uint32:
+		p.enc = (*Buffer).enc_ref_int32
+		p.dec = (*Buffer).dec_ref_int32
+		p.size = size_ref_int32
+	case reflect.Int64, reflect.Uint64:
+		p.enc = (*Buffer).enc_ref_int64
+		p.dec = (*Buffer).dec_ref_int64
+		p.size = size_ref_int64
+	case reflect.Float32:
+		p.enc = (*Buffer).enc_ref_int32 // can just treat them as bits
+		p.dec = (*Buffer).dec_ref_int32
+		p.size = size_ref_int32
+	case reflect.Float64:
+		p.enc = (*Buffer).enc_ref_int64 // can just treat them as bits
+		p.dec = (*Buffer).dec_ref_int64
+		p.size = size_ref_int64
+	case reflect.String:
+		p.dec = (*Buffer).dec_ref_string
+		p.enc = (*Buffer).enc_ref_string
+		p.size = size_ref_string
+	case reflect.Struct:
+		p.stype = typ
+		p.isMarshaler = isMarshaler(typ)
+		p.isUnmarshaler = isUnmarshaler(typ)
+		if p.Wire == "bytes" {
+			p.enc = (*Buffer).enc_ref_struct_message
+			p.dec = (*Buffer).dec_ref_struct_message
+			p.size = size_ref_struct_message
+		} else {
+			fmt.Fprintf(os.Stderr, "proto: no coders for struct %T\n", typ)
+		}
+	default:
+		return false
+	}
+	return true
+}
+
+func (p *Properties) setSliceOfNonPointerStructs(typ reflect.Type) {
+	t2 := typ.Elem()
+	p.sstype = typ
+	p.stype = t2
+	p.isMarshaler = isMarshaler(t2)
+	p.isUnmarshaler = isUnmarshaler(t2)
+	p.enc = (*Buffer).enc_slice_ref_struct_message
+	p.dec = (*Buffer).dec_slice_ref_struct_message
+	p.size = size_slice_ref_struct_message
+	if p.Wire != "bytes" {
+		fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T \n", typ, t2)
+	}
+}

+ 63 - 0
third_party/code.google.com/p/gogoprotobuf/proto/size2_test.go

@@ -0,0 +1,63 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors.  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.
+
+package proto
+
+import (
+	"testing"
+)
+
+// This is a separate file and package from size_test.go because that one uses
+// generated messages and thus may not be in package proto without having a circular
+// dependency, whereas this file tests unexported details of size.go.
+
+func TestVarintSize(t *testing.T) {
+	// Check the edge cases carefully.
+	testCases := []struct {
+		n    uint64
+		size int
+	}{
+		{0, 1},
+		{1, 1},
+		{127, 1},
+		{128, 2},
+		{16383, 2},
+		{16384, 3},
+		{1<<63 - 1, 9},
+		{1 << 63, 10},
+	}
+	for _, tc := range testCases {
+		size := sizeVarint(tc.n)
+		if size != tc.size {
+			t.Errorf("sizeVarint(%d) = %d, want %d", tc.n, size, tc.size)
+		}
+	}
+}

+ 118 - 0
third_party/code.google.com/p/gogoprotobuf/proto/size_test.go

@@ -0,0 +1,118 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors.  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.
+
+package proto_test
+
+import (
+	"log"
+	"testing"
+
+	pb "./testdata"
+	. "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+)
+
+var messageWithExtension1 = &pb.MyMessage{Count: Int32(7)}
+
+// messageWithExtension2 is in equal_test.go.
+var messageWithExtension3 = &pb.MyMessage{Count: Int32(8)}
+
+func init() {
+	if err := SetExtension(messageWithExtension1, pb.E_Ext_More, &pb.Ext{Data: String("Abbott")}); err != nil {
+		log.Panicf("SetExtension: %v", err)
+	}
+	if err := SetExtension(messageWithExtension3, pb.E_Ext_More, &pb.Ext{Data: String("Costello")}); err != nil {
+		log.Panicf("SetExtension: %v", err)
+	}
+
+	// Force messageWithExtension3 to have the extension encoded.
+	Marshal(messageWithExtension3)
+
+}
+
+var SizeTests = []struct {
+	desc	string
+	pb	Message
+}{
+	{"empty", &pb.OtherMessage{}},
+	// Basic types.
+	{"bool", &pb.Defaults{F_Bool: Bool(true)}},
+	{"int32", &pb.Defaults{F_Int32: Int32(12)}},
+	{"small int64", &pb.Defaults{F_Int64: Int64(1)}},
+	{"big int64", &pb.Defaults{F_Int64: Int64(1 << 20)}},
+	{"fixed32", &pb.Defaults{F_Fixed32: Uint32(71)}},
+	{"fixed64", &pb.Defaults{F_Fixed64: Uint64(72)}},
+	{"uint32", &pb.Defaults{F_Uint32: Uint32(123)}},
+	{"uint64", &pb.Defaults{F_Uint64: Uint64(124)}},
+	{"float", &pb.Defaults{F_Float: Float32(12.6)}},
+	{"double", &pb.Defaults{F_Double: Float64(13.9)}},
+	{"string", &pb.Defaults{F_String: String("niles")}},
+	{"bytes", &pb.Defaults{F_Bytes: []byte("wowsa")}},
+	{"bytes, empty", &pb.Defaults{F_Bytes: []byte{}}},
+	{"sint32", &pb.Defaults{F_Sint32: Int32(65)}},
+	{"sint64", &pb.Defaults{F_Sint64: Int64(67)}},
+	{"enum", &pb.Defaults{F_Enum: pb.Defaults_BLUE.Enum()}},
+	// Repeated.
+	{"empty repeated bool", &pb.MoreRepeated{Bools: []bool{}}},
+	{"repeated bool", &pb.MoreRepeated{Bools: []bool{false, true, true, false}}},
+	{"packed repeated bool", &pb.MoreRepeated{BoolsPacked: []bool{false, true, true, false, true, true, true}}},
+	{"repeated int32", &pb.MoreRepeated{Ints: []int32{1, 12203, 1729}}},
+	{"repeated int32 packed", &pb.MoreRepeated{IntsPacked: []int32{1, 12203, 1729}}},
+	{"repeated int64 packed", &pb.MoreRepeated{Int64SPacked: []int64{
+		// Need enough large numbers to verify that the header is counting the number of bytes
+		// for the field, not the number of elements.
+		1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62,
+		1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62,
+	}}},
+	{"repeated string", &pb.MoreRepeated{Strings: []string{"r", "ken", "gri"}}},
+	{"repeated fixed", &pb.MoreRepeated{Fixeds: []uint32{1, 2, 3, 4}}},
+	// Nested.
+	{"nested", &pb.OldMessage{Nested: &pb.OldMessage_Nested{Name: String("whatever")}}},
+	{"group", &pb.GroupOld{G: &pb.GroupOld_G{X: Int32(12345)}}},
+	// Other things.
+	{"unrecognized", &pb.MoreRepeated{XXX_unrecognized: []byte{13<<3 | 0, 4}}},
+	{"extension (unencoded)", messageWithExtension1},
+	{"extension (encoded)", messageWithExtension3},
+}
+
+func TestSize(t *testing.T) {
+	for _, tc := range SizeTests {
+		size := Size(tc.pb)
+		b, err := Marshal(tc.pb)
+		if err != nil {
+			t.Errorf("%v: Marshal failed: %v", tc.desc, err)
+			continue
+		}
+		if size != len(b) {
+			t.Errorf("%v: Size(%v) = %d, want %d", tc.desc, tc.pb, size, len(b))
+			t.Logf("%v: bytes: %#v", tc.desc, b)
+		}
+	}
+}

+ 116 - 0
third_party/code.google.com/p/gogoprotobuf/proto/skip_gogo.go

@@ -0,0 +1,116 @@
+// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+// http://code.google.com/p/gogoprotobuf/gogoproto
+//
+// 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.
+//
+// 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.
+
+package proto
+
+import (
+	"io"
+)
+
+func Skip(data []byte) (n int, err error) {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for {
+				if index >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				index++
+				if data[index-1] < 0x80 {
+					break
+				}
+			}
+			return index, nil
+		case 1:
+			index += 8
+			return index, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			index += length
+			return index, nil
+		case 3:
+			for {
+				var wire uint64
+				var start int = index
+				for shift := uint(0); ; shift += 7 {
+					if index >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := data[index]
+					index++
+					wire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				wireType := int(wire & 0x7)
+				if wireType == 4 {
+					break
+				}
+				next, err := Skip(data[start:])
+				if err != nil {
+					return 0, err
+				}
+				index = start + next
+			}
+			return index, nil
+		case 4:
+			return index, nil
+		case 5:
+			index += 4
+			return index, nil
+		default:
+			return 0, ErrWrongType
+		}
+	}
+	panic("unreachable")
+}

+ 47 - 0
third_party/code.google.com/p/gogoprotobuf/proto/testdata/Makefile

@@ -0,0 +1,47 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 The Go Authors.  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.
+
+all:	regenerate
+
+regenerate:
+	rm -f test.pb.go
+	protoc --gogo_out=. test.proto
+	
+# The following rules are just aids to development. Not needed for typical testing.
+
+diff:	regenerate
+	hg diff test.pb.go
+
+restore:
+	cp test.pb.go.golden test.pb.go
+
+preserve:
+	cp test.pb.go test.pb.go.golden

+ 86 - 0
third_party/code.google.com/p/gogoprotobuf/proto/testdata/golden_test.go

@@ -0,0 +1,86 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors.  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.
+
+// Verify that the compiler output for test.proto is unchanged.
+
+package testdata
+
+import (
+	"crypto/sha1"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"testing"
+)
+
+// sum returns in string form (for easy comparison) the SHA-1 hash of the named file.
+func sum(t *testing.T, name string) string {
+	data, err := ioutil.ReadFile(name)
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Logf("sum(%q): length is %d", name, len(data))
+	hash := sha1.New()
+	_, err = hash.Write(data)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return fmt.Sprintf("% x", hash.Sum(nil))
+}
+
+func run(t *testing.T, name string, args ...string) {
+	cmd := exec.Command(name, args...)
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	err := cmd.Run()
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestGolden(t *testing.T) {
+	// Compute the original checksum.
+	goldenSum := sum(t, "test.pb.go")
+	// Run the proto compiler.
+	run(t, "protoc", "--gogo_out="+os.TempDir(), "test.proto")
+	newFile := filepath.Join(os.TempDir(), "test.pb.go")
+	defer os.Remove(newFile)
+	// Compute the new checksum.
+	newSum := sum(t, newFile)
+	// Verify
+	if newSum != goldenSum {
+		run(t, "diff", "-u", "test.pb.go", newFile)
+		t.Fatal("Code generated by protoc-gen-go has changed; update test.pb.go")
+	}
+}

+ 2294 - 0
third_party/code.google.com/p/gogoprotobuf/proto/testdata/test.pb.go

@@ -0,0 +1,2294 @@
+// Code generated by protoc-gen-gogo.
+// source: test.proto
+// DO NOT EDIT!
+
+package testdata
+
+import proto "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+import json "encoding/json"
+import math "math"
+
+// Reference proto, json, and math imports to suppress error if they are not otherwise used.
+var _ = proto.Marshal
+var _ = &json.SyntaxError{}
+var _ = math.Inf
+
+type FOO int32
+
+const (
+	FOO_FOO1 FOO = 1
+)
+
+var FOO_name = map[int32]string{
+	1: "FOO1",
+}
+var FOO_value = map[string]int32{
+	"FOO1": 1,
+}
+
+func (x FOO) Enum() *FOO {
+	p := new(FOO)
+	*p = x
+	return p
+}
+func (x FOO) String() string {
+	return proto.EnumName(FOO_name, int32(x))
+}
+func (x *FOO) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(FOO_value, data, "FOO")
+	if err != nil {
+		return err
+	}
+	*x = FOO(value)
+	return nil
+}
+
+// An enum, for completeness.
+type GoTest_KIND int32
+
+const (
+	GoTest_VOID	GoTest_KIND	= 0
+	// Basic types
+	GoTest_BOOL		GoTest_KIND	= 1
+	GoTest_BYTES		GoTest_KIND	= 2
+	GoTest_FINGERPRINT	GoTest_KIND	= 3
+	GoTest_FLOAT		GoTest_KIND	= 4
+	GoTest_INT		GoTest_KIND	= 5
+	GoTest_STRING		GoTest_KIND	= 6
+	GoTest_TIME		GoTest_KIND	= 7
+	// 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{
+	0:	"VOID",
+	1:	"BOOL",
+	2:	"BYTES",
+	3:	"FINGERPRINT",
+	4:	"FLOAT",
+	5:	"INT",
+	6:	"STRING",
+	7:	"TIME",
+	8:	"TUPLE",
+	9:	"ARRAY",
+	10:	"MAP",
+	11:	"TABLE",
+	12:	"FUNCTION",
+}
+var GoTest_KIND_value = map[string]int32{
+	"VOID":		0,
+	"BOOL":		1,
+	"BYTES":	2,
+	"FINGERPRINT":	3,
+	"FLOAT":	4,
+	"INT":		5,
+	"STRING":	6,
+	"TIME":		7,
+	"TUPLE":	8,
+	"ARRAY":	9,
+	"MAP":		10,
+	"TABLE":	11,
+	"FUNCTION":	12,
+}
+
+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))
+}
+func (x *GoTest_KIND) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(GoTest_KIND_value, data, "GoTest_KIND")
+	if err != nil {
+		return err
+	}
+	*x = GoTest_KIND(value)
+	return nil
+}
+
+type MyMessage_Color int32
+
+const (
+	MyMessage_RED	MyMessage_Color	= 0
+	MyMessage_GREEN	MyMessage_Color	= 1
+	MyMessage_BLUE	MyMessage_Color	= 2
+)
+
+var MyMessage_Color_name = map[int32]string{
+	0:	"RED",
+	1:	"GREEN",
+	2:	"BLUE",
+}
+var MyMessage_Color_value = map[string]int32{
+	"RED":		0,
+	"GREEN":	1,
+	"BLUE":		2,
+}
+
+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))
+}
+func (x *MyMessage_Color) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(MyMessage_Color_value, data, "MyMessage_Color")
+	if err != nil {
+		return err
+	}
+	*x = MyMessage_Color(value)
+	return nil
+}
+
+type Defaults_Color int32
+
+const (
+	Defaults_RED	Defaults_Color	= 0
+	Defaults_GREEN	Defaults_Color	= 1
+	Defaults_BLUE	Defaults_Color	= 2
+)
+
+var Defaults_Color_name = map[int32]string{
+	0:	"RED",
+	1:	"GREEN",
+	2:	"BLUE",
+}
+var Defaults_Color_value = map[string]int32{
+	"RED":		0,
+	"GREEN":	1,
+	"BLUE":		2,
+}
+
+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))
+}
+func (x *Defaults_Color) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(Defaults_Color_value, data, "Defaults_Color")
+	if err != nil {
+		return err
+	}
+	*x = Defaults_Color(value)
+	return nil
+}
+
+type RepeatedEnum_Color int32
+
+const (
+	RepeatedEnum_RED RepeatedEnum_Color = 1
+)
+
+var RepeatedEnum_Color_name = map[int32]string{
+	1: "RED",
+}
+var RepeatedEnum_Color_value = map[string]int32{
+	"RED": 1,
+}
+
+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))
+}
+func (x *RepeatedEnum_Color) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(RepeatedEnum_Color_value, data, "RepeatedEnum_Color")
+	if err != nil {
+		return err
+	}
+	*x = RepeatedEnum_Color(value)
+	return nil
+}
+
+type GoEnum struct {
+	Foo			*FOO	`protobuf:"varint,1,req,name=foo,enum=testdata.FOO" json:"foo,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *GoEnum) Reset()		{ *m = GoEnum{} }
+func (m *GoEnum) String() string	{ return proto.CompactTextString(m) }
+func (*GoEnum) ProtoMessage()		{}
+
+func (m *GoEnum) GetFoo() FOO {
+	if m != nil && m.Foo != nil {
+		return *m.Foo
+	}
+	return FOO_FOO1
+}
+
+type GoTestField struct {
+	Label			*string	`protobuf:"bytes,1,req" json:"Label,omitempty"`
+	Type			*string	`protobuf:"bytes,2,req" json:"Type,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *GoTestField) Reset()		{ *m = GoTestField{} }
+func (m *GoTestField) String() string	{ return proto.CompactTextString(m) }
+func (*GoTestField) ProtoMessage()	{}
+
+func (m *GoTestField) GetLabel() string {
+	if m != nil && m.Label != nil {
+		return *m.Label
+	}
+	return ""
+}
+
+func (m *GoTestField) GetType() string {
+	if m != nil && m.Type != nil {
+		return *m.Type
+	}
+	return ""
+}
+
+type GoTest struct {
+	// Some typical parameters
+	Kind	*GoTest_KIND	`protobuf:"varint,1,req,enum=testdata.GoTest_KIND" json:"Kind,omitempty"`
+	Table	*string		`protobuf:"bytes,2,opt" json:"Table,omitempty"`
+	Param	*int32		`protobuf:"varint,3,opt" json:"Param,omitempty"`
+	// 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"`
+	F_Fixed32RepeatedPacked	[]uint32		`protobuf:"fixed32,53,rep,packed,name=F_Fixed32_repeated_packed" json:"F_Fixed32_repeated_packed,omitempty"`
+	F_Fixed64RepeatedPacked	[]uint64		`protobuf:"fixed64,54,rep,packed,name=F_Fixed64_repeated_packed" json:"F_Fixed64_repeated_packed,omitempty"`
+	F_Uint32RepeatedPacked	[]uint32		`protobuf:"varint,55,rep,packed,name=F_Uint32_repeated_packed" json:"F_Uint32_repeated_packed,omitempty"`
+	F_Uint64RepeatedPacked	[]uint64		`protobuf:"varint,56,rep,packed,name=F_Uint64_repeated_packed" json:"F_Uint64_repeated_packed,omitempty"`
+	F_FloatRepeatedPacked	[]float32		`protobuf:"fixed32,57,rep,packed,name=F_Float_repeated_packed" json:"F_Float_repeated_packed,omitempty"`
+	F_DoubleRepeatedPacked	[]float64		`protobuf:"fixed64,58,rep,packed,name=F_Double_repeated_packed" json:"F_Double_repeated_packed,omitempty"`
+	F_Sint32RepeatedPacked	[]int32			`protobuf:"zigzag32,502,rep,packed,name=F_Sint32_repeated_packed" json:"F_Sint32_repeated_packed,omitempty"`
+	F_Sint64RepeatedPacked	[]int64			`protobuf:"zigzag64,503,rep,packed,name=F_Sint64_repeated_packed" json:"F_Sint64_repeated_packed,omitempty"`
+	Requiredgroup		*GoTest_RequiredGroup	`protobuf:"group,70,req,name=RequiredGroup" json:"requiredgroup,omitempty"`
+	Repeatedgroup		[]*GoTest_RepeatedGroup	`protobuf:"group,80,rep,name=RepeatedGroup" json:"repeatedgroup,omitempty"`
+	Optionalgroup		*GoTest_OptionalGroup	`protobuf:"group,90,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
+	XXX_unrecognized	[]byte			`json:"-"`
+}
+
+func (m *GoTest) Reset()		{ *m = GoTest{} }
+func (m *GoTest) String() string	{ return proto.CompactTextString(m) }
+func (*GoTest) ProtoMessage()		{}
+
+const Default_GoTest_F_BoolDefaulted bool = true
+const Default_GoTest_F_Int32Defaulted int32 = 32
+const Default_GoTest_F_Int64Defaulted int64 = 64
+const Default_GoTest_F_Fixed32Defaulted uint32 = 320
+const Default_GoTest_F_Fixed64Defaulted uint64 = 640
+const Default_GoTest_F_Uint32Defaulted uint32 = 3200
+const Default_GoTest_F_Uint64Defaulted uint64 = 6400
+const Default_GoTest_F_FloatDefaulted float32 = 314159
+const Default_GoTest_F_DoubleDefaulted float64 = 271828
+const Default_GoTest_F_StringDefaulted string = "hello, \"world!\"\n"
+
+var Default_GoTest_F_BytesDefaulted []byte = []byte("Bignose")
+
+const Default_GoTest_F_Sint32Defaulted int32 = -32
+const Default_GoTest_F_Sint64Defaulted int64 = -64
+
+func (m *GoTest) GetKind() GoTest_KIND {
+	if m != nil && m.Kind != nil {
+		return *m.Kind
+	}
+	return GoTest_VOID
+}
+
+func (m *GoTest) GetTable() string {
+	if m != nil && m.Table != nil {
+		return *m.Table
+	}
+	return ""
+}
+
+func (m *GoTest) GetParam() int32 {
+	if m != nil && m.Param != nil {
+		return *m.Param
+	}
+	return 0
+}
+
+func (m *GoTest) GetRequiredField() *GoTestField {
+	if m != nil {
+		return m.RequiredField
+	}
+	return nil
+}
+
+func (m *GoTest) GetRepeatedField() []*GoTestField {
+	if m != nil {
+		return m.RepeatedField
+	}
+	return nil
+}
+
+func (m *GoTest) GetOptionalField() *GoTestField {
+	if m != nil {
+		return m.OptionalField
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_BoolRequired() bool {
+	if m != nil && m.F_BoolRequired != nil {
+		return *m.F_BoolRequired
+	}
+	return false
+}
+
+func (m *GoTest) GetF_Int32Required() int32 {
+	if m != nil && m.F_Int32Required != nil {
+		return *m.F_Int32Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Int64Required() int64 {
+	if m != nil && m.F_Int64Required != nil {
+		return *m.F_Int64Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Fixed32Required() uint32 {
+	if m != nil && m.F_Fixed32Required != nil {
+		return *m.F_Fixed32Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Fixed64Required() uint64 {
+	if m != nil && m.F_Fixed64Required != nil {
+		return *m.F_Fixed64Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Uint32Required() uint32 {
+	if m != nil && m.F_Uint32Required != nil {
+		return *m.F_Uint32Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Uint64Required() uint64 {
+	if m != nil && m.F_Uint64Required != nil {
+		return *m.F_Uint64Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_FloatRequired() float32 {
+	if m != nil && m.F_FloatRequired != nil {
+		return *m.F_FloatRequired
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_DoubleRequired() float64 {
+	if m != nil && m.F_DoubleRequired != nil {
+		return *m.F_DoubleRequired
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_StringRequired() string {
+	if m != nil && m.F_StringRequired != nil {
+		return *m.F_StringRequired
+	}
+	return ""
+}
+
+func (m *GoTest) GetF_BytesRequired() []byte {
+	if m != nil {
+		return m.F_BytesRequired
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint32Required() int32 {
+	if m != nil && m.F_Sint32Required != nil {
+		return *m.F_Sint32Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Sint64Required() int64 {
+	if m != nil && m.F_Sint64Required != nil {
+		return *m.F_Sint64Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_BoolRepeated() []bool {
+	if m != nil {
+		return m.F_BoolRepeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Int32Repeated() []int32 {
+	if m != nil {
+		return m.F_Int32Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Int64Repeated() []int64 {
+	if m != nil {
+		return m.F_Int64Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Fixed32Repeated() []uint32 {
+	if m != nil {
+		return m.F_Fixed32Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Fixed64Repeated() []uint64 {
+	if m != nil {
+		return m.F_Fixed64Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Uint32Repeated() []uint32 {
+	if m != nil {
+		return m.F_Uint32Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Uint64Repeated() []uint64 {
+	if m != nil {
+		return m.F_Uint64Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_FloatRepeated() []float32 {
+	if m != nil {
+		return m.F_FloatRepeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_DoubleRepeated() []float64 {
+	if m != nil {
+		return m.F_DoubleRepeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_StringRepeated() []string {
+	if m != nil {
+		return m.F_StringRepeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_BytesRepeated() [][]byte {
+	if m != nil {
+		return m.F_BytesRepeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint32Repeated() []int32 {
+	if m != nil {
+		return m.F_Sint32Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint64Repeated() []int64 {
+	if m != nil {
+		return m.F_Sint64Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_BoolOptional() bool {
+	if m != nil && m.F_BoolOptional != nil {
+		return *m.F_BoolOptional
+	}
+	return false
+}
+
+func (m *GoTest) GetF_Int32Optional() int32 {
+	if m != nil && m.F_Int32Optional != nil {
+		return *m.F_Int32Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Int64Optional() int64 {
+	if m != nil && m.F_Int64Optional != nil {
+		return *m.F_Int64Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Fixed32Optional() uint32 {
+	if m != nil && m.F_Fixed32Optional != nil {
+		return *m.F_Fixed32Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Fixed64Optional() uint64 {
+	if m != nil && m.F_Fixed64Optional != nil {
+		return *m.F_Fixed64Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Uint32Optional() uint32 {
+	if m != nil && m.F_Uint32Optional != nil {
+		return *m.F_Uint32Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Uint64Optional() uint64 {
+	if m != nil && m.F_Uint64Optional != nil {
+		return *m.F_Uint64Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_FloatOptional() float32 {
+	if m != nil && m.F_FloatOptional != nil {
+		return *m.F_FloatOptional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_DoubleOptional() float64 {
+	if m != nil && m.F_DoubleOptional != nil {
+		return *m.F_DoubleOptional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_StringOptional() string {
+	if m != nil && m.F_StringOptional != nil {
+		return *m.F_StringOptional
+	}
+	return ""
+}
+
+func (m *GoTest) GetF_BytesOptional() []byte {
+	if m != nil {
+		return m.F_BytesOptional
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint32Optional() int32 {
+	if m != nil && m.F_Sint32Optional != nil {
+		return *m.F_Sint32Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Sint64Optional() int64 {
+	if m != nil && m.F_Sint64Optional != nil {
+		return *m.F_Sint64Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_BoolDefaulted() bool {
+	if m != nil && m.F_BoolDefaulted != nil {
+		return *m.F_BoolDefaulted
+	}
+	return Default_GoTest_F_BoolDefaulted
+}
+
+func (m *GoTest) GetF_Int32Defaulted() int32 {
+	if m != nil && m.F_Int32Defaulted != nil {
+		return *m.F_Int32Defaulted
+	}
+	return Default_GoTest_F_Int32Defaulted
+}
+
+func (m *GoTest) GetF_Int64Defaulted() int64 {
+	if m != nil && m.F_Int64Defaulted != nil {
+		return *m.F_Int64Defaulted
+	}
+	return Default_GoTest_F_Int64Defaulted
+}
+
+func (m *GoTest) GetF_Fixed32Defaulted() uint32 {
+	if m != nil && m.F_Fixed32Defaulted != nil {
+		return *m.F_Fixed32Defaulted
+	}
+	return Default_GoTest_F_Fixed32Defaulted
+}
+
+func (m *GoTest) GetF_Fixed64Defaulted() uint64 {
+	if m != nil && m.F_Fixed64Defaulted != nil {
+		return *m.F_Fixed64Defaulted
+	}
+	return Default_GoTest_F_Fixed64Defaulted
+}
+
+func (m *GoTest) GetF_Uint32Defaulted() uint32 {
+	if m != nil && m.F_Uint32Defaulted != nil {
+		return *m.F_Uint32Defaulted
+	}
+	return Default_GoTest_F_Uint32Defaulted
+}
+
+func (m *GoTest) GetF_Uint64Defaulted() uint64 {
+	if m != nil && m.F_Uint64Defaulted != nil {
+		return *m.F_Uint64Defaulted
+	}
+	return Default_GoTest_F_Uint64Defaulted
+}
+
+func (m *GoTest) GetF_FloatDefaulted() float32 {
+	if m != nil && m.F_FloatDefaulted != nil {
+		return *m.F_FloatDefaulted
+	}
+	return Default_GoTest_F_FloatDefaulted
+}
+
+func (m *GoTest) GetF_DoubleDefaulted() float64 {
+	if m != nil && m.F_DoubleDefaulted != nil {
+		return *m.F_DoubleDefaulted
+	}
+	return Default_GoTest_F_DoubleDefaulted
+}
+
+func (m *GoTest) GetF_StringDefaulted() string {
+	if m != nil && m.F_StringDefaulted != nil {
+		return *m.F_StringDefaulted
+	}
+	return Default_GoTest_F_StringDefaulted
+}
+
+func (m *GoTest) GetF_BytesDefaulted() []byte {
+	if m != nil && m.F_BytesDefaulted != nil {
+		return m.F_BytesDefaulted
+	}
+	return append([]byte(nil), Default_GoTest_F_BytesDefaulted...)
+}
+
+func (m *GoTest) GetF_Sint32Defaulted() int32 {
+	if m != nil && m.F_Sint32Defaulted != nil {
+		return *m.F_Sint32Defaulted
+	}
+	return Default_GoTest_F_Sint32Defaulted
+}
+
+func (m *GoTest) GetF_Sint64Defaulted() int64 {
+	if m != nil && m.F_Sint64Defaulted != nil {
+		return *m.F_Sint64Defaulted
+	}
+	return Default_GoTest_F_Sint64Defaulted
+}
+
+func (m *GoTest) GetF_BoolRepeatedPacked() []bool {
+	if m != nil {
+		return m.F_BoolRepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Int32RepeatedPacked() []int32 {
+	if m != nil {
+		return m.F_Int32RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Int64RepeatedPacked() []int64 {
+	if m != nil {
+		return m.F_Int64RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Fixed32RepeatedPacked() []uint32 {
+	if m != nil {
+		return m.F_Fixed32RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Fixed64RepeatedPacked() []uint64 {
+	if m != nil {
+		return m.F_Fixed64RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Uint32RepeatedPacked() []uint32 {
+	if m != nil {
+		return m.F_Uint32RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Uint64RepeatedPacked() []uint64 {
+	if m != nil {
+		return m.F_Uint64RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_FloatRepeatedPacked() []float32 {
+	if m != nil {
+		return m.F_FloatRepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_DoubleRepeatedPacked() []float64 {
+	if m != nil {
+		return m.F_DoubleRepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint32RepeatedPacked() []int32 {
+	if m != nil {
+		return m.F_Sint32RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint64RepeatedPacked() []int64 {
+	if m != nil {
+		return m.F_Sint64RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetRequiredgroup() *GoTest_RequiredGroup {
+	if m != nil {
+		return m.Requiredgroup
+	}
+	return nil
+}
+
+func (m *GoTest) GetRepeatedgroup() []*GoTest_RepeatedGroup {
+	if m != nil {
+		return m.Repeatedgroup
+	}
+	return nil
+}
+
+func (m *GoTest) GetOptionalgroup() *GoTest_OptionalGroup {
+	if m != nil {
+		return m.Optionalgroup
+	}
+	return nil
+}
+
+// Required, repeated, and optional groups.
+type GoTest_RequiredGroup struct {
+	RequiredField		*string	`protobuf:"bytes,71,req" json:"RequiredField,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *GoTest_RequiredGroup) Reset()		{ *m = GoTest_RequiredGroup{} }
+func (m *GoTest_RequiredGroup) String() string	{ return proto.CompactTextString(m) }
+func (*GoTest_RequiredGroup) ProtoMessage()	{}
+
+func (m *GoTest_RequiredGroup) GetRequiredField() string {
+	if m != nil && m.RequiredField != nil {
+		return *m.RequiredField
+	}
+	return ""
+}
+
+type GoTest_RepeatedGroup struct {
+	RequiredField		*string	`protobuf:"bytes,81,req" json:"RequiredField,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *GoTest_RepeatedGroup) Reset()		{ *m = GoTest_RepeatedGroup{} }
+func (m *GoTest_RepeatedGroup) String() string	{ return proto.CompactTextString(m) }
+func (*GoTest_RepeatedGroup) ProtoMessage()	{}
+
+func (m *GoTest_RepeatedGroup) GetRequiredField() string {
+	if m != nil && m.RequiredField != nil {
+		return *m.RequiredField
+	}
+	return ""
+}
+
+type GoTest_OptionalGroup struct {
+	RequiredField		*string	`protobuf:"bytes,91,req" json:"RequiredField,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *GoTest_OptionalGroup) Reset()		{ *m = GoTest_OptionalGroup{} }
+func (m *GoTest_OptionalGroup) String() string	{ return proto.CompactTextString(m) }
+func (*GoTest_OptionalGroup) ProtoMessage()	{}
+
+func (m *GoTest_OptionalGroup) GetRequiredField() string {
+	if m != nil && m.RequiredField != nil {
+		return *m.RequiredField
+	}
+	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"`
+	SkipFixed64		*uint64			`protobuf:"fixed64,13,req,name=skip_fixed64" json:"skip_fixed64,omitempty"`
+	SkipString		*string			`protobuf:"bytes,14,req,name=skip_string" json:"skip_string,omitempty"`
+	Skipgroup		*GoSkipTest_SkipGroup	`protobuf:"group,15,req,name=SkipGroup" json:"skipgroup,omitempty"`
+	XXX_unrecognized	[]byte			`json:"-"`
+}
+
+func (m *GoSkipTest) Reset()		{ *m = GoSkipTest{} }
+func (m *GoSkipTest) String() string	{ return proto.CompactTextString(m) }
+func (*GoSkipTest) ProtoMessage()	{}
+
+func (m *GoSkipTest) GetSkipInt32() int32 {
+	if m != nil && m.SkipInt32 != nil {
+		return *m.SkipInt32
+	}
+	return 0
+}
+
+func (m *GoSkipTest) GetSkipFixed32() uint32 {
+	if m != nil && m.SkipFixed32 != nil {
+		return *m.SkipFixed32
+	}
+	return 0
+}
+
+func (m *GoSkipTest) GetSkipFixed64() uint64 {
+	if m != nil && m.SkipFixed64 != nil {
+		return *m.SkipFixed64
+	}
+	return 0
+}
+
+func (m *GoSkipTest) GetSkipString() string {
+	if m != nil && m.SkipString != nil {
+		return *m.SkipString
+	}
+	return ""
+}
+
+func (m *GoSkipTest) GetSkipgroup() *GoSkipTest_SkipGroup {
+	if m != nil {
+		return m.Skipgroup
+	}
+	return nil
+}
+
+type GoSkipTest_SkipGroup struct {
+	GroupInt32		*int32	`protobuf:"varint,16,req,name=group_int32" json:"group_int32,omitempty"`
+	GroupString		*string	`protobuf:"bytes,17,req,name=group_string" json:"group_string,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *GoSkipTest_SkipGroup) Reset()		{ *m = GoSkipTest_SkipGroup{} }
+func (m *GoSkipTest_SkipGroup) String() string	{ return proto.CompactTextString(m) }
+func (*GoSkipTest_SkipGroup) ProtoMessage()	{}
+
+func (m *GoSkipTest_SkipGroup) GetGroupInt32() int32 {
+	if m != nil && m.GroupInt32 != nil {
+		return *m.GroupInt32
+	}
+	return 0
+}
+
+func (m *GoSkipTest_SkipGroup) GetGroupString() string {
+	if m != nil && m.GroupString != nil {
+		return *m.GroupString
+	}
+	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:"-"`
+}
+
+func (m *NonPackedTest) Reset()		{ *m = NonPackedTest{} }
+func (m *NonPackedTest) String() string	{ return proto.CompactTextString(m) }
+func (*NonPackedTest) ProtoMessage()	{}
+
+func (m *NonPackedTest) GetA() []int32 {
+	if m != nil {
+		return m.A
+	}
+	return nil
+}
+
+type PackedTest struct {
+	B			[]int32	`protobuf:"varint,1,rep,packed,name=b" json:"b,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *PackedTest) Reset()		{ *m = PackedTest{} }
+func (m *PackedTest) String() string	{ return proto.CompactTextString(m) }
+func (*PackedTest) ProtoMessage()	{}
+
+func (m *PackedTest) GetB() []int32 {
+	if m != nil {
+		return m.B
+	}
+	return nil
+}
+
+type MaxTag struct {
+	// Maximum possible tag number.
+	LastField		*string	`protobuf:"bytes,536870911,opt,name=last_field" json:"last_field,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *MaxTag) Reset()		{ *m = MaxTag{} }
+func (m *MaxTag) String() string	{ return proto.CompactTextString(m) }
+func (*MaxTag) ProtoMessage()		{}
+
+func (m *MaxTag) GetLastField() string {
+	if m != nil && m.LastField != nil {
+		return *m.LastField
+	}
+	return ""
+}
+
+type OldMessage struct {
+	Nested			*OldMessage_Nested	`protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"`
+	XXX_unrecognized	[]byte			`json:"-"`
+}
+
+func (m *OldMessage) Reset()		{ *m = OldMessage{} }
+func (m *OldMessage) String() string	{ return proto.CompactTextString(m) }
+func (*OldMessage) ProtoMessage()	{}
+
+func (m *OldMessage) GetNested() *OldMessage_Nested {
+	if m != nil {
+		return m.Nested
+	}
+	return nil
+}
+
+type OldMessage_Nested struct {
+	Name			*string	`protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *OldMessage_Nested) Reset()		{ *m = OldMessage_Nested{} }
+func (m *OldMessage_Nested) String() string	{ return proto.CompactTextString(m) }
+func (*OldMessage_Nested) ProtoMessage()	{}
+
+func (m *OldMessage_Nested) GetName() string {
+	if m != nil && m.Name != nil {
+		return *m.Name
+	}
+	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:"-"`
+}
+
+func (m *NewMessage) Reset()		{ *m = NewMessage{} }
+func (m *NewMessage) String() string	{ return proto.CompactTextString(m) }
+func (*NewMessage) ProtoMessage()	{}
+
+func (m *NewMessage) GetNested() *NewMessage_Nested {
+	if m != nil {
+		return m.Nested
+	}
+	return nil
+}
+
+type NewMessage_Nested struct {
+	Name			*string	`protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	FoodGroup		*string	`protobuf:"bytes,2,opt,name=food_group" json:"food_group,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *NewMessage_Nested) Reset()		{ *m = NewMessage_Nested{} }
+func (m *NewMessage_Nested) String() string	{ return proto.CompactTextString(m) }
+func (*NewMessage_Nested) ProtoMessage()	{}
+
+func (m *NewMessage_Nested) GetName() string {
+	if m != nil && m.Name != nil {
+		return *m.Name
+	}
+	return ""
+}
+
+func (m *NewMessage_Nested) GetFoodGroup() string {
+	if m != nil && m.FoodGroup != nil {
+		return *m.FoodGroup
+	}
+	return ""
+}
+
+type InnerMessage struct {
+	Host			*string	`protobuf:"bytes,1,req,name=host" json:"host,omitempty"`
+	Port			*int32	`protobuf:"varint,2,opt,name=port,def=4000" json:"port,omitempty"`
+	Connected		*bool	`protobuf:"varint,3,opt,name=connected" json:"connected,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *InnerMessage) Reset()		{ *m = InnerMessage{} }
+func (m *InnerMessage) String() string	{ return proto.CompactTextString(m) }
+func (*InnerMessage) ProtoMessage()	{}
+
+const Default_InnerMessage_Port int32 = 4000
+
+func (m *InnerMessage) GetHost() string {
+	if m != nil && m.Host != nil {
+		return *m.Host
+	}
+	return ""
+}
+
+func (m *InnerMessage) GetPort() int32 {
+	if m != nil && m.Port != nil {
+		return *m.Port
+	}
+	return Default_InnerMessage_Port
+}
+
+func (m *InnerMessage) GetConnected() bool {
+	if m != nil && m.Connected != nil {
+		return *m.Connected
+	}
+	return false
+}
+
+type OtherMessage struct {
+	Key			*int64		`protobuf:"varint,1,opt,name=key" json:"key,omitempty"`
+	Value			[]byte		`protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
+	Weight			*float32	`protobuf:"fixed32,3,opt,name=weight" json:"weight,omitempty"`
+	Inner			*InnerMessage	`protobuf:"bytes,4,opt,name=inner" json:"inner,omitempty"`
+	XXX_unrecognized	[]byte		`json:"-"`
+}
+
+func (m *OtherMessage) Reset()		{ *m = OtherMessage{} }
+func (m *OtherMessage) String() string	{ return proto.CompactTextString(m) }
+func (*OtherMessage) ProtoMessage()	{}
+
+func (m *OtherMessage) GetKey() int64 {
+	if m != nil && m.Key != nil {
+		return *m.Key
+	}
+	return 0
+}
+
+func (m *OtherMessage) GetValue() []byte {
+	if m != nil {
+		return m.Value
+	}
+	return nil
+}
+
+func (m *OtherMessage) GetWeight() float32 {
+	if m != nil && m.Weight != nil {
+		return *m.Weight
+	}
+	return 0
+}
+
+func (m *OtherMessage) GetInner() *InnerMessage {
+	if m != nil {
+		return m.Inner
+	}
+	return nil
+}
+
+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"`
+	// 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:"-"`
+	XXX_unrecognized	[]byte				`json:"-"`
+}
+
+func (m *MyMessage) Reset()		{ *m = MyMessage{} }
+func (m *MyMessage) String() string	{ return proto.CompactTextString(m) }
+func (*MyMessage) ProtoMessage()	{}
+
+var extRange_MyMessage = []proto.ExtensionRange{
+	{100, 536870911},
+}
+
+func (*MyMessage) ExtensionRangeArray() []proto.ExtensionRange {
+	return extRange_MyMessage
+}
+func (m *MyMessage) ExtensionMap() map[int32]proto.Extension {
+	if m.XXX_extensions == nil {
+		m.XXX_extensions = make(map[int32]proto.Extension)
+	}
+	return m.XXX_extensions
+}
+
+func (m *MyMessage) GetCount() int32 {
+	if m != nil && m.Count != nil {
+		return *m.Count
+	}
+	return 0
+}
+
+func (m *MyMessage) GetName() string {
+	if m != nil && m.Name != nil {
+		return *m.Name
+	}
+	return ""
+}
+
+func (m *MyMessage) GetQuote() string {
+	if m != nil && m.Quote != nil {
+		return *m.Quote
+	}
+	return ""
+}
+
+func (m *MyMessage) GetPet() []string {
+	if m != nil {
+		return m.Pet
+	}
+	return nil
+}
+
+func (m *MyMessage) GetInner() *InnerMessage {
+	if m != nil {
+		return m.Inner
+	}
+	return nil
+}
+
+func (m *MyMessage) GetOthers() []*OtherMessage {
+	if m != nil {
+		return m.Others
+	}
+	return nil
+}
+
+func (m *MyMessage) GetRepInner() []*InnerMessage {
+	if m != nil {
+		return m.RepInner
+	}
+	return nil
+}
+
+func (m *MyMessage) GetBikeshed() MyMessage_Color {
+	if m != nil && m.Bikeshed != nil {
+		return *m.Bikeshed
+	}
+	return MyMessage_RED
+}
+
+func (m *MyMessage) GetSomegroup() *MyMessage_SomeGroup {
+	if m != nil {
+		return m.Somegroup
+	}
+	return nil
+}
+
+func (m *MyMessage) GetRepBytes() [][]byte {
+	if m != nil {
+		return m.RepBytes
+	}
+	return nil
+}
+
+func (m *MyMessage) GetBigfloat() float64 {
+	if m != nil && m.Bigfloat != nil {
+		return *m.Bigfloat
+	}
+	return 0
+}
+
+type MyMessage_SomeGroup struct {
+	GroupField		*int32	`protobuf:"varint,9,opt,name=group_field" json:"group_field,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *MyMessage_SomeGroup) Reset()		{ *m = MyMessage_SomeGroup{} }
+func (m *MyMessage_SomeGroup) String() string	{ return proto.CompactTextString(m) }
+func (*MyMessage_SomeGroup) ProtoMessage()	{}
+
+func (m *MyMessage_SomeGroup) GetGroupField() int32 {
+	if m != nil && m.GroupField != nil {
+		return *m.GroupField
+	}
+	return 0
+}
+
+type Ext struct {
+	Data			*string	`protobuf:"bytes,1,opt,name=data" json:"data,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *Ext) Reset()		{ *m = Ext{} }
+func (m *Ext) String() string	{ return proto.CompactTextString(m) }
+func (*Ext) ProtoMessage()	{}
+
+func (m *Ext) GetData() string {
+	if m != nil && m.Data != nil {
+		return *m.Data
+	}
+	return ""
+}
+
+var E_Ext_More = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessage)(nil),
+	ExtensionType:	(*Ext)(nil),
+	Field:		103,
+	Name:		"testdata.Ext.more",
+	Tag:		"bytes,103,opt,name=more",
+}
+
+var E_Ext_Text = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessage)(nil),
+	ExtensionType:	(*string)(nil),
+	Field:		104,
+	Name:		"testdata.Ext.text",
+	Tag:		"bytes,104,opt,name=text",
+}
+
+var E_Ext_Number = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessage)(nil),
+	ExtensionType:	(*int32)(nil),
+	Field:		105,
+	Name:		"testdata.Ext.number",
+	Tag:		"varint,105,opt,name=number",
+}
+
+type MyMessageSet struct {
+	XXX_extensions		map[int32]proto.Extension	`json:"-"`
+	XXX_unrecognized	[]byte				`json:"-"`
+}
+
+func (m *MyMessageSet) Reset()		{ *m = MyMessageSet{} }
+func (m *MyMessageSet) String() string	{ return proto.CompactTextString(m) }
+func (*MyMessageSet) ProtoMessage()	{}
+
+func (m *MyMessageSet) Marshal() ([]byte, error) {
+	return proto.MarshalMessageSet(m.ExtensionMap())
+}
+func (m *MyMessageSet) Unmarshal(buf []byte) error {
+	return proto.UnmarshalMessageSet(buf, m.ExtensionMap())
+}
+
+// ensure MyMessageSet satisfies proto.Marshaler and proto.Unmarshaler
+var _ proto.Marshaler = (*MyMessageSet)(nil)
+var _ proto.Unmarshaler = (*MyMessageSet)(nil)
+
+var extRange_MyMessageSet = []proto.ExtensionRange{
+	{100, 2147483646},
+}
+
+func (*MyMessageSet) ExtensionRangeArray() []proto.ExtensionRange {
+	return extRange_MyMessageSet
+}
+func (m *MyMessageSet) ExtensionMap() map[int32]proto.Extension {
+	if m.XXX_extensions == nil {
+		m.XXX_extensions = make(map[int32]proto.Extension)
+	}
+	return m.XXX_extensions
+}
+
+type Empty struct {
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *Empty) Reset()		{ *m = Empty{} }
+func (m *Empty) String() string	{ return proto.CompactTextString(m) }
+func (*Empty) ProtoMessage()	{}
+
+type MessageList struct {
+	Message			[]*MessageList_Message	`protobuf:"group,1,rep" json:"message,omitempty"`
+	XXX_unrecognized	[]byte			`json:"-"`
+}
+
+func (m *MessageList) Reset()		{ *m = MessageList{} }
+func (m *MessageList) String() string	{ return proto.CompactTextString(m) }
+func (*MessageList) ProtoMessage()	{}
+
+func (m *MessageList) GetMessage() []*MessageList_Message {
+	if m != nil {
+		return m.Message
+	}
+	return nil
+}
+
+type MessageList_Message struct {
+	Name			*string	`protobuf:"bytes,2,req,name=name" json:"name,omitempty"`
+	Count			*int32	`protobuf:"varint,3,req,name=count" json:"count,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *MessageList_Message) Reset()		{ *m = MessageList_Message{} }
+func (m *MessageList_Message) String() string	{ return proto.CompactTextString(m) }
+func (*MessageList_Message) ProtoMessage()	{}
+
+func (m *MessageList_Message) GetName() string {
+	if m != nil && m.Name != nil {
+		return *m.Name
+	}
+	return ""
+}
+
+func (m *MessageList_Message) GetCount() int32 {
+	if m != nil && m.Count != nil {
+		return *m.Count
+	}
+	return 0
+}
+
+type Strings struct {
+	StringField		*string	`protobuf:"bytes,1,opt,name=string_field" json:"string_field,omitempty"`
+	BytesField		[]byte	`protobuf:"bytes,2,opt,name=bytes_field" json:"bytes_field,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *Strings) Reset()		{ *m = Strings{} }
+func (m *Strings) String() string	{ return proto.CompactTextString(m) }
+func (*Strings) ProtoMessage()		{}
+
+func (m *Strings) GetStringField() string {
+	if m != nil && m.StringField != nil {
+		return *m.StringField
+	}
+	return ""
+}
+
+func (m *Strings) GetBytesField() []byte {
+	if m != nil {
+		return m.BytesField
+	}
+	return nil
+}
+
+type Defaults struct {
+	// Default-valued fields of all basic types.
+	// Same as GoTest, but copied here to make testing easier.
+	F_Bool		*bool		`protobuf:"varint,1,opt,def=1" json:"F_Bool,omitempty"`
+	F_Int32		*int32		`protobuf:"varint,2,opt,def=32" json:"F_Int32,omitempty"`
+	F_Int64		*int64		`protobuf:"varint,3,opt,def=64" json:"F_Int64,omitempty"`
+	F_Fixed32	*uint32		`protobuf:"fixed32,4,opt,def=320" json:"F_Fixed32,omitempty"`
+	F_Fixed64	*uint64		`protobuf:"fixed64,5,opt,def=640" json:"F_Fixed64,omitempty"`
+	F_Uint32	*uint32		`protobuf:"varint,6,opt,def=3200" json:"F_Uint32,omitempty"`
+	F_Uint64	*uint64		`protobuf:"varint,7,opt,def=6400" json:"F_Uint64,omitempty"`
+	F_Float		*float32	`protobuf:"fixed32,8,opt,def=314159" json:"F_Float,omitempty"`
+	F_Double	*float64	`protobuf:"fixed64,9,opt,def=271828" json:"F_Double,omitempty"`
+	F_String	*string		`protobuf:"bytes,10,opt,def=hello, \"world!\"\n" json:"F_String,omitempty"`
+	F_Bytes		[]byte		`protobuf:"bytes,11,opt,def=Bignose" json:"F_Bytes,omitempty"`
+	F_Sint32	*int32		`protobuf:"zigzag32,12,opt,def=-32" json:"F_Sint32,omitempty"`
+	F_Sint64	*int64		`protobuf:"zigzag64,13,opt,def=-64" json:"F_Sint64,omitempty"`
+	F_Enum		*Defaults_Color	`protobuf:"varint,14,opt,enum=testdata.Defaults_Color,def=1" json:"F_Enum,omitempty"`
+	// 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{} }
+func (m *Defaults) String() string	{ return proto.CompactTextString(m) }
+func (*Defaults) ProtoMessage()		{}
+
+const Default_Defaults_F_Bool bool = true
+const Default_Defaults_F_Int32 int32 = 32
+const Default_Defaults_F_Int64 int64 = 64
+const Default_Defaults_F_Fixed32 uint32 = 320
+const Default_Defaults_F_Fixed64 uint64 = 640
+const Default_Defaults_F_Uint32 uint32 = 3200
+const Default_Defaults_F_Uint64 uint64 = 6400
+const Default_Defaults_F_Float float32 = 314159
+const Default_Defaults_F_Double float64 = 271828
+const Default_Defaults_F_String string = "hello, \"world!\"\n"
+
+var Default_Defaults_F_Bytes []byte = []byte("Bignose")
+
+const Default_Defaults_F_Sint32 int32 = -32
+const Default_Defaults_F_Sint64 int64 = -64
+const Default_Defaults_F_Enum Defaults_Color = Defaults_GREEN
+
+var Default_Defaults_F_Pinf float32 = float32(math.Inf(1))
+var Default_Defaults_F_Ninf float32 = float32(math.Inf(-1))
+var Default_Defaults_F_Nan float32 = float32(math.NaN())
+
+func (m *Defaults) GetF_Bool() bool {
+	if m != nil && m.F_Bool != nil {
+		return *m.F_Bool
+	}
+	return Default_Defaults_F_Bool
+}
+
+func (m *Defaults) GetF_Int32() int32 {
+	if m != nil && m.F_Int32 != nil {
+		return *m.F_Int32
+	}
+	return Default_Defaults_F_Int32
+}
+
+func (m *Defaults) GetF_Int64() int64 {
+	if m != nil && m.F_Int64 != nil {
+		return *m.F_Int64
+	}
+	return Default_Defaults_F_Int64
+}
+
+func (m *Defaults) GetF_Fixed32() uint32 {
+	if m != nil && m.F_Fixed32 != nil {
+		return *m.F_Fixed32
+	}
+	return Default_Defaults_F_Fixed32
+}
+
+func (m *Defaults) GetF_Fixed64() uint64 {
+	if m != nil && m.F_Fixed64 != nil {
+		return *m.F_Fixed64
+	}
+	return Default_Defaults_F_Fixed64
+}
+
+func (m *Defaults) GetF_Uint32() uint32 {
+	if m != nil && m.F_Uint32 != nil {
+		return *m.F_Uint32
+	}
+	return Default_Defaults_F_Uint32
+}
+
+func (m *Defaults) GetF_Uint64() uint64 {
+	if m != nil && m.F_Uint64 != nil {
+		return *m.F_Uint64
+	}
+	return Default_Defaults_F_Uint64
+}
+
+func (m *Defaults) GetF_Float() float32 {
+	if m != nil && m.F_Float != nil {
+		return *m.F_Float
+	}
+	return Default_Defaults_F_Float
+}
+
+func (m *Defaults) GetF_Double() float64 {
+	if m != nil && m.F_Double != nil {
+		return *m.F_Double
+	}
+	return Default_Defaults_F_Double
+}
+
+func (m *Defaults) GetF_String() string {
+	if m != nil && m.F_String != nil {
+		return *m.F_String
+	}
+	return Default_Defaults_F_String
+}
+
+func (m *Defaults) GetF_Bytes() []byte {
+	if m != nil && m.F_Bytes != nil {
+		return m.F_Bytes
+	}
+	return append([]byte(nil), Default_Defaults_F_Bytes...)
+}
+
+func (m *Defaults) GetF_Sint32() int32 {
+	if m != nil && m.F_Sint32 != nil {
+		return *m.F_Sint32
+	}
+	return Default_Defaults_F_Sint32
+}
+
+func (m *Defaults) GetF_Sint64() int64 {
+	if m != nil && m.F_Sint64 != nil {
+		return *m.F_Sint64
+	}
+	return Default_Defaults_F_Sint64
+}
+
+func (m *Defaults) GetF_Enum() Defaults_Color {
+	if m != nil && m.F_Enum != nil {
+		return *m.F_Enum
+	}
+	return Default_Defaults_F_Enum
+}
+
+func (m *Defaults) GetF_Pinf() float32 {
+	if m != nil && m.F_Pinf != nil {
+		return *m.F_Pinf
+	}
+	return Default_Defaults_F_Pinf
+}
+
+func (m *Defaults) GetF_Ninf() float32 {
+	if m != nil && m.F_Ninf != nil {
+		return *m.F_Ninf
+	}
+	return Default_Defaults_F_Ninf
+}
+
+func (m *Defaults) GetF_Nan() float32 {
+	if m != nil && m.F_Nan != nil {
+		return *m.F_Nan
+	}
+	return Default_Defaults_F_Nan
+}
+
+func (m *Defaults) GetSub() *SubDefaults {
+	if m != nil {
+		return m.Sub
+	}
+	return nil
+}
+
+type SubDefaults struct {
+	N			*int64	`protobuf:"varint,1,opt,name=n,def=7" json:"n,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *SubDefaults) Reset()		{ *m = SubDefaults{} }
+func (m *SubDefaults) String() string	{ return proto.CompactTextString(m) }
+func (*SubDefaults) ProtoMessage()	{}
+
+const Default_SubDefaults_N int64 = 7
+
+func (m *SubDefaults) GetN() int64 {
+	if m != nil && m.N != nil {
+		return *m.N
+	}
+	return Default_SubDefaults_N
+}
+
+type RepeatedEnum struct {
+	Color			[]RepeatedEnum_Color	`protobuf:"varint,1,rep,name=color,enum=testdata.RepeatedEnum_Color" json:"color,omitempty"`
+	XXX_unrecognized	[]byte			`json:"-"`
+}
+
+func (m *RepeatedEnum) Reset()		{ *m = RepeatedEnum{} }
+func (m *RepeatedEnum) String() string	{ return proto.CompactTextString(m) }
+func (*RepeatedEnum) ProtoMessage()	{}
+
+func (m *RepeatedEnum) GetColor() []RepeatedEnum_Color {
+	if m != nil {
+		return m.Color
+	}
+	return nil
+}
+
+type MoreRepeated struct {
+	Bools			[]bool		`protobuf:"varint,1,rep,name=bools" json:"bools,omitempty"`
+	BoolsPacked		[]bool		`protobuf:"varint,2,rep,packed,name=bools_packed" json:"bools_packed,omitempty"`
+	Ints			[]int32		`protobuf:"varint,3,rep,name=ints" json:"ints,omitempty"`
+	IntsPacked		[]int32		`protobuf:"varint,4,rep,packed,name=ints_packed" json:"ints_packed,omitempty"`
+	Int64SPacked		[]int64		`protobuf:"varint,7,rep,packed,name=int64s_packed" json:"int64s_packed,omitempty"`
+	Strings			[]string	`protobuf:"bytes,5,rep,name=strings" json:"strings,omitempty"`
+	Fixeds			[]uint32	`protobuf:"fixed32,6,rep,name=fixeds" json:"fixeds,omitempty"`
+	XXX_unrecognized	[]byte		`json:"-"`
+}
+
+func (m *MoreRepeated) Reset()		{ *m = MoreRepeated{} }
+func (m *MoreRepeated) String() string	{ return proto.CompactTextString(m) }
+func (*MoreRepeated) ProtoMessage()	{}
+
+func (m *MoreRepeated) GetBools() []bool {
+	if m != nil {
+		return m.Bools
+	}
+	return nil
+}
+
+func (m *MoreRepeated) GetBoolsPacked() []bool {
+	if m != nil {
+		return m.BoolsPacked
+	}
+	return nil
+}
+
+func (m *MoreRepeated) GetInts() []int32 {
+	if m != nil {
+		return m.Ints
+	}
+	return nil
+}
+
+func (m *MoreRepeated) GetIntsPacked() []int32 {
+	if m != nil {
+		return m.IntsPacked
+	}
+	return nil
+}
+
+func (m *MoreRepeated) GetInt64SPacked() []int64 {
+	if m != nil {
+		return m.Int64SPacked
+	}
+	return nil
+}
+
+func (m *MoreRepeated) GetStrings() []string {
+	if m != nil {
+		return m.Strings
+	}
+	return nil
+}
+
+func (m *MoreRepeated) GetFixeds() []uint32 {
+	if m != nil {
+		return m.Fixeds
+	}
+	return nil
+}
+
+type GroupOld struct {
+	G			*GroupOld_G	`protobuf:"group,101,opt" json:"g,omitempty"`
+	XXX_unrecognized	[]byte		`json:"-"`
+}
+
+func (m *GroupOld) Reset()		{ *m = GroupOld{} }
+func (m *GroupOld) String() string	{ return proto.CompactTextString(m) }
+func (*GroupOld) ProtoMessage()		{}
+
+func (m *GroupOld) GetG() *GroupOld_G {
+	if m != nil {
+		return m.G
+	}
+	return nil
+}
+
+type GroupOld_G struct {
+	X			*int32	`protobuf:"varint,2,opt,name=x" json:"x,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *GroupOld_G) Reset()		{ *m = GroupOld_G{} }
+func (m *GroupOld_G) String() string	{ return proto.CompactTextString(m) }
+func (*GroupOld_G) ProtoMessage()	{}
+
+func (m *GroupOld_G) GetX() int32 {
+	if m != nil && m.X != nil {
+		return *m.X
+	}
+	return 0
+}
+
+type GroupNew struct {
+	G			*GroupNew_G	`protobuf:"group,101,opt" json:"g,omitempty"`
+	XXX_unrecognized	[]byte		`json:"-"`
+}
+
+func (m *GroupNew) Reset()		{ *m = GroupNew{} }
+func (m *GroupNew) String() string	{ return proto.CompactTextString(m) }
+func (*GroupNew) ProtoMessage()		{}
+
+func (m *GroupNew) GetG() *GroupNew_G {
+	if m != nil {
+		return m.G
+	}
+	return nil
+}
+
+type GroupNew_G struct {
+	X			*int32	`protobuf:"varint,2,opt,name=x" json:"x,omitempty"`
+	Y			*int32	`protobuf:"varint,3,opt,name=y" json:"y,omitempty"`
+	XXX_unrecognized	[]byte	`json:"-"`
+}
+
+func (m *GroupNew_G) Reset()		{ *m = GroupNew_G{} }
+func (m *GroupNew_G) String() string	{ return proto.CompactTextString(m) }
+func (*GroupNew_G) ProtoMessage()	{}
+
+func (m *GroupNew_G) GetX() int32 {
+	if m != nil && m.X != nil {
+		return *m.X
+	}
+	return 0
+}
+
+func (m *GroupNew_G) GetY() int32 {
+	if m != nil && m.Y != nil {
+		return *m.Y
+	}
+	return 0
+}
+
+type FloatingPoint struct {
+	F			*float64	`protobuf:"fixed64,1,req,name=f" json:"f,omitempty"`
+	XXX_unrecognized	[]byte		`json:"-"`
+}
+
+func (m *FloatingPoint) Reset()		{ *m = FloatingPoint{} }
+func (m *FloatingPoint) String() string	{ return proto.CompactTextString(m) }
+func (*FloatingPoint) ProtoMessage()	{}
+
+func (m *FloatingPoint) GetF() float64 {
+	if m != nil && m.F != nil {
+		return *m.F
+	}
+	return 0
+}
+
+var E_Greeting = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessage)(nil),
+	ExtensionType:	([]string)(nil),
+	Field:		106,
+	Name:		"testdata.greeting",
+	Tag:		"bytes,106,rep,name=greeting",
+}
+
+var E_X201 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		201,
+	Name:		"testdata.x201",
+	Tag:		"bytes,201,opt,name=x201",
+}
+
+var E_X202 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		202,
+	Name:		"testdata.x202",
+	Tag:		"bytes,202,opt,name=x202",
+}
+
+var E_X203 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		203,
+	Name:		"testdata.x203",
+	Tag:		"bytes,203,opt,name=x203",
+}
+
+var E_X204 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		204,
+	Name:		"testdata.x204",
+	Tag:		"bytes,204,opt,name=x204",
+}
+
+var E_X205 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		205,
+	Name:		"testdata.x205",
+	Tag:		"bytes,205,opt,name=x205",
+}
+
+var E_X206 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		206,
+	Name:		"testdata.x206",
+	Tag:		"bytes,206,opt,name=x206",
+}
+
+var E_X207 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		207,
+	Name:		"testdata.x207",
+	Tag:		"bytes,207,opt,name=x207",
+}
+
+var E_X208 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		208,
+	Name:		"testdata.x208",
+	Tag:		"bytes,208,opt,name=x208",
+}
+
+var E_X209 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		209,
+	Name:		"testdata.x209",
+	Tag:		"bytes,209,opt,name=x209",
+}
+
+var E_X210 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		210,
+	Name:		"testdata.x210",
+	Tag:		"bytes,210,opt,name=x210",
+}
+
+var E_X211 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		211,
+	Name:		"testdata.x211",
+	Tag:		"bytes,211,opt,name=x211",
+}
+
+var E_X212 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		212,
+	Name:		"testdata.x212",
+	Tag:		"bytes,212,opt,name=x212",
+}
+
+var E_X213 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		213,
+	Name:		"testdata.x213",
+	Tag:		"bytes,213,opt,name=x213",
+}
+
+var E_X214 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		214,
+	Name:		"testdata.x214",
+	Tag:		"bytes,214,opt,name=x214",
+}
+
+var E_X215 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		215,
+	Name:		"testdata.x215",
+	Tag:		"bytes,215,opt,name=x215",
+}
+
+var E_X216 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		216,
+	Name:		"testdata.x216",
+	Tag:		"bytes,216,opt,name=x216",
+}
+
+var E_X217 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		217,
+	Name:		"testdata.x217",
+	Tag:		"bytes,217,opt,name=x217",
+}
+
+var E_X218 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		218,
+	Name:		"testdata.x218",
+	Tag:		"bytes,218,opt,name=x218",
+}
+
+var E_X219 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		219,
+	Name:		"testdata.x219",
+	Tag:		"bytes,219,opt,name=x219",
+}
+
+var E_X220 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		220,
+	Name:		"testdata.x220",
+	Tag:		"bytes,220,opt,name=x220",
+}
+
+var E_X221 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		221,
+	Name:		"testdata.x221",
+	Tag:		"bytes,221,opt,name=x221",
+}
+
+var E_X222 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		222,
+	Name:		"testdata.x222",
+	Tag:		"bytes,222,opt,name=x222",
+}
+
+var E_X223 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		223,
+	Name:		"testdata.x223",
+	Tag:		"bytes,223,opt,name=x223",
+}
+
+var E_X224 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		224,
+	Name:		"testdata.x224",
+	Tag:		"bytes,224,opt,name=x224",
+}
+
+var E_X225 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		225,
+	Name:		"testdata.x225",
+	Tag:		"bytes,225,opt,name=x225",
+}
+
+var E_X226 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		226,
+	Name:		"testdata.x226",
+	Tag:		"bytes,226,opt,name=x226",
+}
+
+var E_X227 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		227,
+	Name:		"testdata.x227",
+	Tag:		"bytes,227,opt,name=x227",
+}
+
+var E_X228 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		228,
+	Name:		"testdata.x228",
+	Tag:		"bytes,228,opt,name=x228",
+}
+
+var E_X229 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		229,
+	Name:		"testdata.x229",
+	Tag:		"bytes,229,opt,name=x229",
+}
+
+var E_X230 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		230,
+	Name:		"testdata.x230",
+	Tag:		"bytes,230,opt,name=x230",
+}
+
+var E_X231 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		231,
+	Name:		"testdata.x231",
+	Tag:		"bytes,231,opt,name=x231",
+}
+
+var E_X232 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		232,
+	Name:		"testdata.x232",
+	Tag:		"bytes,232,opt,name=x232",
+}
+
+var E_X233 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		233,
+	Name:		"testdata.x233",
+	Tag:		"bytes,233,opt,name=x233",
+}
+
+var E_X234 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		234,
+	Name:		"testdata.x234",
+	Tag:		"bytes,234,opt,name=x234",
+}
+
+var E_X235 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		235,
+	Name:		"testdata.x235",
+	Tag:		"bytes,235,opt,name=x235",
+}
+
+var E_X236 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		236,
+	Name:		"testdata.x236",
+	Tag:		"bytes,236,opt,name=x236",
+}
+
+var E_X237 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		237,
+	Name:		"testdata.x237",
+	Tag:		"bytes,237,opt,name=x237",
+}
+
+var E_X238 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		238,
+	Name:		"testdata.x238",
+	Tag:		"bytes,238,opt,name=x238",
+}
+
+var E_X239 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		239,
+	Name:		"testdata.x239",
+	Tag:		"bytes,239,opt,name=x239",
+}
+
+var E_X240 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		240,
+	Name:		"testdata.x240",
+	Tag:		"bytes,240,opt,name=x240",
+}
+
+var E_X241 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		241,
+	Name:		"testdata.x241",
+	Tag:		"bytes,241,opt,name=x241",
+}
+
+var E_X242 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		242,
+	Name:		"testdata.x242",
+	Tag:		"bytes,242,opt,name=x242",
+}
+
+var E_X243 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		243,
+	Name:		"testdata.x243",
+	Tag:		"bytes,243,opt,name=x243",
+}
+
+var E_X244 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		244,
+	Name:		"testdata.x244",
+	Tag:		"bytes,244,opt,name=x244",
+}
+
+var E_X245 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		245,
+	Name:		"testdata.x245",
+	Tag:		"bytes,245,opt,name=x245",
+}
+
+var E_X246 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		246,
+	Name:		"testdata.x246",
+	Tag:		"bytes,246,opt,name=x246",
+}
+
+var E_X247 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		247,
+	Name:		"testdata.x247",
+	Tag:		"bytes,247,opt,name=x247",
+}
+
+var E_X248 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		248,
+	Name:		"testdata.x248",
+	Tag:		"bytes,248,opt,name=x248",
+}
+
+var E_X249 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		249,
+	Name:		"testdata.x249",
+	Tag:		"bytes,249,opt,name=x249",
+}
+
+var E_X250 = &proto.ExtensionDesc{
+	ExtendedType:	(*MyMessageSet)(nil),
+	ExtensionType:	(*Empty)(nil),
+	Field:		250,
+	Name:		"testdata.x250",
+	Tag:		"bytes,250,opt,name=x250",
+}
+
+func init() {
+	proto.RegisterEnum("testdata.FOO", FOO_name, FOO_value)
+	proto.RegisterEnum("testdata.GoTest_KIND", GoTest_KIND_name, GoTest_KIND_value)
+	proto.RegisterEnum("testdata.MyMessage_Color", MyMessage_Color_name, MyMessage_Color_value)
+	proto.RegisterEnum("testdata.Defaults_Color", Defaults_Color_name, Defaults_Color_value)
+	proto.RegisterEnum("testdata.RepeatedEnum_Color", RepeatedEnum_Color_name, RepeatedEnum_Color_value)
+	proto.RegisterExtension(E_Ext_More)
+	proto.RegisterExtension(E_Ext_Text)
+	proto.RegisterExtension(E_Ext_Number)
+	proto.RegisterExtension(E_Greeting)
+	proto.RegisterExtension(E_X201)
+	proto.RegisterExtension(E_X202)
+	proto.RegisterExtension(E_X203)
+	proto.RegisterExtension(E_X204)
+	proto.RegisterExtension(E_X205)
+	proto.RegisterExtension(E_X206)
+	proto.RegisterExtension(E_X207)
+	proto.RegisterExtension(E_X208)
+	proto.RegisterExtension(E_X209)
+	proto.RegisterExtension(E_X210)
+	proto.RegisterExtension(E_X211)
+	proto.RegisterExtension(E_X212)
+	proto.RegisterExtension(E_X213)
+	proto.RegisterExtension(E_X214)
+	proto.RegisterExtension(E_X215)
+	proto.RegisterExtension(E_X216)
+	proto.RegisterExtension(E_X217)
+	proto.RegisterExtension(E_X218)
+	proto.RegisterExtension(E_X219)
+	proto.RegisterExtension(E_X220)
+	proto.RegisterExtension(E_X221)
+	proto.RegisterExtension(E_X222)
+	proto.RegisterExtension(E_X223)
+	proto.RegisterExtension(E_X224)
+	proto.RegisterExtension(E_X225)
+	proto.RegisterExtension(E_X226)
+	proto.RegisterExtension(E_X227)
+	proto.RegisterExtension(E_X228)
+	proto.RegisterExtension(E_X229)
+	proto.RegisterExtension(E_X230)
+	proto.RegisterExtension(E_X231)
+	proto.RegisterExtension(E_X232)
+	proto.RegisterExtension(E_X233)
+	proto.RegisterExtension(E_X234)
+	proto.RegisterExtension(E_X235)
+	proto.RegisterExtension(E_X236)
+	proto.RegisterExtension(E_X237)
+	proto.RegisterExtension(E_X238)
+	proto.RegisterExtension(E_X239)
+	proto.RegisterExtension(E_X240)
+	proto.RegisterExtension(E_X241)
+	proto.RegisterExtension(E_X242)
+	proto.RegisterExtension(E_X243)
+	proto.RegisterExtension(E_X244)
+	proto.RegisterExtension(E_X245)
+	proto.RegisterExtension(E_X246)
+	proto.RegisterExtension(E_X247)
+	proto.RegisterExtension(E_X248)
+	proto.RegisterExtension(E_X249)
+	proto.RegisterExtension(E_X250)
+}

+ 1737 - 0
third_party/code.google.com/p/gogoprotobuf/proto/testdata/test.pb.go.golden

@@ -0,0 +1,1737 @@
+// Code generated by protoc-gen-gogo.
+// source: test.proto
+// DO NOT EDIT!
+
+package testdata
+
+import proto "code.google.com/p/gogoprotobuf/proto"
+import json "encoding/json"
+import math "math"
+
+import ()
+
+// Reference proto, json, and math imports to suppress error if they are not otherwise used.
+var _ = proto.Marshal
+var _ = &json.SyntaxError{}
+var _ = math.Inf
+
+type FOO int32
+
+const (
+	FOO_FOO1 FOO = 1
+)
+
+var FOO_name = map[int32]string{
+	1: "FOO1",
+}
+var FOO_value = map[string]int32{
+	"FOO1": 1,
+}
+
+func (x FOO) Enum() *FOO {
+	p := new(FOO)
+	*p = x
+	return p
+}
+func (x FOO) String() string {
+	return proto.EnumName(FOO_name, int32(x))
+}
+func (x FOO) MarshalJSON() ([]byte, error) {
+	return json.Marshal(x.String())
+}
+func (x *FOO) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(FOO_value, data, "FOO")
+	if err != nil {
+		return err
+	}
+	*x = FOO(value)
+	return nil
+}
+
+type GoTest_KIND int32
+
+const (
+	GoTest_VOID        GoTest_KIND = 0
+	GoTest_BOOL        GoTest_KIND = 1
+	GoTest_BYTES       GoTest_KIND = 2
+	GoTest_FINGERPRINT GoTest_KIND = 3
+	GoTest_FLOAT       GoTest_KIND = 4
+	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
+)
+
+var GoTest_KIND_name = map[int32]string{
+	0:  "VOID",
+	1:  "BOOL",
+	2:  "BYTES",
+	3:  "FINGERPRINT",
+	4:  "FLOAT",
+	5:  "INT",
+	6:  "STRING",
+	7:  "TIME",
+	8:  "TUPLE",
+	9:  "ARRAY",
+	10: "MAP",
+	11: "TABLE",
+	12: "FUNCTION",
+}
+var GoTest_KIND_value = map[string]int32{
+	"VOID":        0,
+	"BOOL":        1,
+	"BYTES":       2,
+	"FINGERPRINT": 3,
+	"FLOAT":       4,
+	"INT":         5,
+	"STRING":      6,
+	"TIME":        7,
+	"TUPLE":       8,
+	"ARRAY":       9,
+	"MAP":         10,
+	"TABLE":       11,
+	"FUNCTION":    12,
+}
+
+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))
+}
+func (x GoTest_KIND) MarshalJSON() ([]byte, error) {
+	return json.Marshal(x.String())
+}
+func (x *GoTest_KIND) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(GoTest_KIND_value, data, "GoTest_KIND")
+	if err != nil {
+		return err
+	}
+	*x = GoTest_KIND(value)
+	return nil
+}
+
+type MyMessage_Color int32
+
+const (
+	MyMessage_RED   MyMessage_Color = 0
+	MyMessage_GREEN MyMessage_Color = 1
+	MyMessage_BLUE  MyMessage_Color = 2
+)
+
+var MyMessage_Color_name = map[int32]string{
+	0: "RED",
+	1: "GREEN",
+	2: "BLUE",
+}
+var MyMessage_Color_value = map[string]int32{
+	"RED":   0,
+	"GREEN": 1,
+	"BLUE":  2,
+}
+
+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))
+}
+func (x MyMessage_Color) MarshalJSON() ([]byte, error) {
+	return json.Marshal(x.String())
+}
+func (x *MyMessage_Color) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(MyMessage_Color_value, data, "MyMessage_Color")
+	if err != nil {
+		return err
+	}
+	*x = MyMessage_Color(value)
+	return nil
+}
+
+type Defaults_Color int32
+
+const (
+	Defaults_RED   Defaults_Color = 0
+	Defaults_GREEN Defaults_Color = 1
+	Defaults_BLUE  Defaults_Color = 2
+)
+
+var Defaults_Color_name = map[int32]string{
+	0: "RED",
+	1: "GREEN",
+	2: "BLUE",
+}
+var Defaults_Color_value = map[string]int32{
+	"RED":   0,
+	"GREEN": 1,
+	"BLUE":  2,
+}
+
+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))
+}
+func (x Defaults_Color) MarshalJSON() ([]byte, error) {
+	return json.Marshal(x.String())
+}
+func (x *Defaults_Color) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(Defaults_Color_value, data, "Defaults_Color")
+	if err != nil {
+		return err
+	}
+	*x = Defaults_Color(value)
+	return nil
+}
+
+type RepeatedEnum_Color int32
+
+const (
+	RepeatedEnum_RED RepeatedEnum_Color = 1
+)
+
+var RepeatedEnum_Color_name = map[int32]string{
+	1: "RED",
+}
+var RepeatedEnum_Color_value = map[string]int32{
+	"RED": 1,
+}
+
+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))
+}
+func (x RepeatedEnum_Color) MarshalJSON() ([]byte, error) {
+	return json.Marshal(x.String())
+}
+func (x *RepeatedEnum_Color) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(RepeatedEnum_Color_value, data, "RepeatedEnum_Color")
+	if err != nil {
+		return err
+	}
+	*x = RepeatedEnum_Color(value)
+	return nil
+}
+
+type GoEnum struct {
+	Foo              *FOO   `protobuf:"varint,1,req,name=foo,enum=testdata.FOO" json:"foo,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *GoEnum) Reset()         { *m = GoEnum{} }
+func (m *GoEnum) String() string { return proto.CompactTextString(m) }
+func (*GoEnum) ProtoMessage()    {}
+
+func (m *GoEnum) GetFoo() FOO {
+	if m != nil && m.Foo != nil {
+		return *m.Foo
+	}
+	return 0
+}
+
+type GoTestField struct {
+	Label            *string `protobuf:"bytes,1,req" json:"Label,omitempty"`
+	Type             *string `protobuf:"bytes,2,req" json:"Type,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *GoTestField) Reset()         { *m = GoTestField{} }
+func (m *GoTestField) String() string { return proto.CompactTextString(m) }
+func (*GoTestField) ProtoMessage()    {}
+
+func (m *GoTestField) GetLabel() string {
+	if m != nil && m.Label != nil {
+		return *m.Label
+	}
+	return ""
+}
+
+func (m *GoTestField) GetType() string {
+	if m != nil && m.Type != nil {
+		return *m.Type
+	}
+	return ""
+}
+
+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"`
+	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"`
+	F_Fixed32RepeatedPacked []uint32                `protobuf:"fixed32,53,rep,packed,name=F_Fixed32_repeated_packed" json:"F_Fixed32_repeated_packed,omitempty"`
+	F_Fixed64RepeatedPacked []uint64                `protobuf:"fixed64,54,rep,packed,name=F_Fixed64_repeated_packed" json:"F_Fixed64_repeated_packed,omitempty"`
+	F_Uint32RepeatedPacked  []uint32                `protobuf:"varint,55,rep,packed,name=F_Uint32_repeated_packed" json:"F_Uint32_repeated_packed,omitempty"`
+	F_Uint64RepeatedPacked  []uint64                `protobuf:"varint,56,rep,packed,name=F_Uint64_repeated_packed" json:"F_Uint64_repeated_packed,omitempty"`
+	F_FloatRepeatedPacked   []float32               `protobuf:"fixed32,57,rep,packed,name=F_Float_repeated_packed" json:"F_Float_repeated_packed,omitempty"`
+	F_DoubleRepeatedPacked  []float64               `protobuf:"fixed64,58,rep,packed,name=F_Double_repeated_packed" json:"F_Double_repeated_packed,omitempty"`
+	F_Sint32RepeatedPacked  []int32                 `protobuf:"zigzag32,502,rep,packed,name=F_Sint32_repeated_packed" json:"F_Sint32_repeated_packed,omitempty"`
+	F_Sint64RepeatedPacked  []int64                 `protobuf:"zigzag64,503,rep,packed,name=F_Sint64_repeated_packed" json:"F_Sint64_repeated_packed,omitempty"`
+	Requiredgroup           *GoTest_RequiredGroup   `protobuf:"group,70,req,name=RequiredGroup" json:"requiredgroup,omitempty"`
+	Repeatedgroup           []*GoTest_RepeatedGroup `protobuf:"group,80,rep,name=RepeatedGroup" json:"repeatedgroup,omitempty"`
+	Optionalgroup           *GoTest_OptionalGroup   `protobuf:"group,90,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
+	XXX_unrecognized        []byte                  `json:"-"`
+}
+
+func (m *GoTest) Reset()         { *m = GoTest{} }
+func (m *GoTest) String() string { return proto.CompactTextString(m) }
+func (*GoTest) ProtoMessage()    {}
+
+const Default_GoTest_F_BoolDefaulted bool = true
+const Default_GoTest_F_Int32Defaulted int32 = 32
+const Default_GoTest_F_Int64Defaulted int64 = 64
+const Default_GoTest_F_Fixed32Defaulted uint32 = 320
+const Default_GoTest_F_Fixed64Defaulted uint64 = 640
+const Default_GoTest_F_Uint32Defaulted uint32 = 3200
+const Default_GoTest_F_Uint64Defaulted uint64 = 6400
+const Default_GoTest_F_FloatDefaulted float32 = 314159
+const Default_GoTest_F_DoubleDefaulted float64 = 271828
+const Default_GoTest_F_StringDefaulted string = "hello, \"world!\"\n"
+
+var Default_GoTest_F_BytesDefaulted []byte = []byte("Bignose")
+
+const Default_GoTest_F_Sint32Defaulted int32 = -32
+const Default_GoTest_F_Sint64Defaulted int64 = -64
+
+func (m *GoTest) GetKind() GoTest_KIND {
+	if m != nil && m.Kind != nil {
+		return *m.Kind
+	}
+	return 0
+}
+
+func (m *GoTest) GetTable() string {
+	if m != nil && m.Table != nil {
+		return *m.Table
+	}
+	return ""
+}
+
+func (m *GoTest) GetParam() int32 {
+	if m != nil && m.Param != nil {
+		return *m.Param
+	}
+	return 0
+}
+
+func (m *GoTest) GetRequiredField() *GoTestField {
+	if m != nil {
+		return m.RequiredField
+	}
+	return nil
+}
+
+func (m *GoTest) GetRepeatedField() []*GoTestField {
+	if m != nil {
+		return m.RepeatedField
+	}
+	return nil
+}
+
+func (m *GoTest) GetOptionalField() *GoTestField {
+	if m != nil {
+		return m.OptionalField
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_BoolRequired() bool {
+	if m != nil && m.F_BoolRequired != nil {
+		return *m.F_BoolRequired
+	}
+	return false
+}
+
+func (m *GoTest) GetF_Int32Required() int32 {
+	if m != nil && m.F_Int32Required != nil {
+		return *m.F_Int32Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Int64Required() int64 {
+	if m != nil && m.F_Int64Required != nil {
+		return *m.F_Int64Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Fixed32Required() uint32 {
+	if m != nil && m.F_Fixed32Required != nil {
+		return *m.F_Fixed32Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Fixed64Required() uint64 {
+	if m != nil && m.F_Fixed64Required != nil {
+		return *m.F_Fixed64Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Uint32Required() uint32 {
+	if m != nil && m.F_Uint32Required != nil {
+		return *m.F_Uint32Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Uint64Required() uint64 {
+	if m != nil && m.F_Uint64Required != nil {
+		return *m.F_Uint64Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_FloatRequired() float32 {
+	if m != nil && m.F_FloatRequired != nil {
+		return *m.F_FloatRequired
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_DoubleRequired() float64 {
+	if m != nil && m.F_DoubleRequired != nil {
+		return *m.F_DoubleRequired
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_StringRequired() string {
+	if m != nil && m.F_StringRequired != nil {
+		return *m.F_StringRequired
+	}
+	return ""
+}
+
+func (m *GoTest) GetF_BytesRequired() []byte {
+	if m != nil {
+		return m.F_BytesRequired
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint32Required() int32 {
+	if m != nil && m.F_Sint32Required != nil {
+		return *m.F_Sint32Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Sint64Required() int64 {
+	if m != nil && m.F_Sint64Required != nil {
+		return *m.F_Sint64Required
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_BoolRepeated() []bool {
+	if m != nil {
+		return m.F_BoolRepeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Int32Repeated() []int32 {
+	if m != nil {
+		return m.F_Int32Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Int64Repeated() []int64 {
+	if m != nil {
+		return m.F_Int64Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Fixed32Repeated() []uint32 {
+	if m != nil {
+		return m.F_Fixed32Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Fixed64Repeated() []uint64 {
+	if m != nil {
+		return m.F_Fixed64Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Uint32Repeated() []uint32 {
+	if m != nil {
+		return m.F_Uint32Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Uint64Repeated() []uint64 {
+	if m != nil {
+		return m.F_Uint64Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_FloatRepeated() []float32 {
+	if m != nil {
+		return m.F_FloatRepeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_DoubleRepeated() []float64 {
+	if m != nil {
+		return m.F_DoubleRepeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_StringRepeated() []string {
+	if m != nil {
+		return m.F_StringRepeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_BytesRepeated() [][]byte {
+	if m != nil {
+		return m.F_BytesRepeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint32Repeated() []int32 {
+	if m != nil {
+		return m.F_Sint32Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint64Repeated() []int64 {
+	if m != nil {
+		return m.F_Sint64Repeated
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_BoolOptional() bool {
+	if m != nil && m.F_BoolOptional != nil {
+		return *m.F_BoolOptional
+	}
+	return false
+}
+
+func (m *GoTest) GetF_Int32Optional() int32 {
+	if m != nil && m.F_Int32Optional != nil {
+		return *m.F_Int32Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Int64Optional() int64 {
+	if m != nil && m.F_Int64Optional != nil {
+		return *m.F_Int64Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Fixed32Optional() uint32 {
+	if m != nil && m.F_Fixed32Optional != nil {
+		return *m.F_Fixed32Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Fixed64Optional() uint64 {
+	if m != nil && m.F_Fixed64Optional != nil {
+		return *m.F_Fixed64Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Uint32Optional() uint32 {
+	if m != nil && m.F_Uint32Optional != nil {
+		return *m.F_Uint32Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Uint64Optional() uint64 {
+	if m != nil && m.F_Uint64Optional != nil {
+		return *m.F_Uint64Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_FloatOptional() float32 {
+	if m != nil && m.F_FloatOptional != nil {
+		return *m.F_FloatOptional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_DoubleOptional() float64 {
+	if m != nil && m.F_DoubleOptional != nil {
+		return *m.F_DoubleOptional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_StringOptional() string {
+	if m != nil && m.F_StringOptional != nil {
+		return *m.F_StringOptional
+	}
+	return ""
+}
+
+func (m *GoTest) GetF_BytesOptional() []byte {
+	if m != nil {
+		return m.F_BytesOptional
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint32Optional() int32 {
+	if m != nil && m.F_Sint32Optional != nil {
+		return *m.F_Sint32Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_Sint64Optional() int64 {
+	if m != nil && m.F_Sint64Optional != nil {
+		return *m.F_Sint64Optional
+	}
+	return 0
+}
+
+func (m *GoTest) GetF_BoolDefaulted() bool {
+	if m != nil && m.F_BoolDefaulted != nil {
+		return *m.F_BoolDefaulted
+	}
+	return Default_GoTest_F_BoolDefaulted
+}
+
+func (m *GoTest) GetF_Int32Defaulted() int32 {
+	if m != nil && m.F_Int32Defaulted != nil {
+		return *m.F_Int32Defaulted
+	}
+	return Default_GoTest_F_Int32Defaulted
+}
+
+func (m *GoTest) GetF_Int64Defaulted() int64 {
+	if m != nil && m.F_Int64Defaulted != nil {
+		return *m.F_Int64Defaulted
+	}
+	return Default_GoTest_F_Int64Defaulted
+}
+
+func (m *GoTest) GetF_Fixed32Defaulted() uint32 {
+	if m != nil && m.F_Fixed32Defaulted != nil {
+		return *m.F_Fixed32Defaulted
+	}
+	return Default_GoTest_F_Fixed32Defaulted
+}
+
+func (m *GoTest) GetF_Fixed64Defaulted() uint64 {
+	if m != nil && m.F_Fixed64Defaulted != nil {
+		return *m.F_Fixed64Defaulted
+	}
+	return Default_GoTest_F_Fixed64Defaulted
+}
+
+func (m *GoTest) GetF_Uint32Defaulted() uint32 {
+	if m != nil && m.F_Uint32Defaulted != nil {
+		return *m.F_Uint32Defaulted
+	}
+	return Default_GoTest_F_Uint32Defaulted
+}
+
+func (m *GoTest) GetF_Uint64Defaulted() uint64 {
+	if m != nil && m.F_Uint64Defaulted != nil {
+		return *m.F_Uint64Defaulted
+	}
+	return Default_GoTest_F_Uint64Defaulted
+}
+
+func (m *GoTest) GetF_FloatDefaulted() float32 {
+	if m != nil && m.F_FloatDefaulted != nil {
+		return *m.F_FloatDefaulted
+	}
+	return Default_GoTest_F_FloatDefaulted
+}
+
+func (m *GoTest) GetF_DoubleDefaulted() float64 {
+	if m != nil && m.F_DoubleDefaulted != nil {
+		return *m.F_DoubleDefaulted
+	}
+	return Default_GoTest_F_DoubleDefaulted
+}
+
+func (m *GoTest) GetF_StringDefaulted() string {
+	if m != nil && m.F_StringDefaulted != nil {
+		return *m.F_StringDefaulted
+	}
+	return Default_GoTest_F_StringDefaulted
+}
+
+func (m *GoTest) GetF_BytesDefaulted() []byte {
+	if m != nil && m.F_BytesDefaulted != nil {
+		return m.F_BytesDefaulted
+	}
+	return append([]byte(nil), Default_GoTest_F_BytesDefaulted...)
+}
+
+func (m *GoTest) GetF_Sint32Defaulted() int32 {
+	if m != nil && m.F_Sint32Defaulted != nil {
+		return *m.F_Sint32Defaulted
+	}
+	return Default_GoTest_F_Sint32Defaulted
+}
+
+func (m *GoTest) GetF_Sint64Defaulted() int64 {
+	if m != nil && m.F_Sint64Defaulted != nil {
+		return *m.F_Sint64Defaulted
+	}
+	return Default_GoTest_F_Sint64Defaulted
+}
+
+func (m *GoTest) GetF_BoolRepeatedPacked() []bool {
+	if m != nil {
+		return m.F_BoolRepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Int32RepeatedPacked() []int32 {
+	if m != nil {
+		return m.F_Int32RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Int64RepeatedPacked() []int64 {
+	if m != nil {
+		return m.F_Int64RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Fixed32RepeatedPacked() []uint32 {
+	if m != nil {
+		return m.F_Fixed32RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Fixed64RepeatedPacked() []uint64 {
+	if m != nil {
+		return m.F_Fixed64RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Uint32RepeatedPacked() []uint32 {
+	if m != nil {
+		return m.F_Uint32RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Uint64RepeatedPacked() []uint64 {
+	if m != nil {
+		return m.F_Uint64RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_FloatRepeatedPacked() []float32 {
+	if m != nil {
+		return m.F_FloatRepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_DoubleRepeatedPacked() []float64 {
+	if m != nil {
+		return m.F_DoubleRepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint32RepeatedPacked() []int32 {
+	if m != nil {
+		return m.F_Sint32RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetF_Sint64RepeatedPacked() []int64 {
+	if m != nil {
+		return m.F_Sint64RepeatedPacked
+	}
+	return nil
+}
+
+func (m *GoTest) GetRequiredgroup() *GoTest_RequiredGroup {
+	if m != nil {
+		return m.Requiredgroup
+	}
+	return nil
+}
+
+func (m *GoTest) GetRepeatedgroup() []*GoTest_RepeatedGroup {
+	if m != nil {
+		return m.Repeatedgroup
+	}
+	return nil
+}
+
+func (m *GoTest) GetOptionalgroup() *GoTest_OptionalGroup {
+	if m != nil {
+		return m.Optionalgroup
+	}
+	return nil
+}
+
+type GoTest_RequiredGroup struct {
+	RequiredField    *string `protobuf:"bytes,71,req" json:"RequiredField,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *GoTest_RequiredGroup) Reset() { *m = GoTest_RequiredGroup{} }
+
+func (m *GoTest_RequiredGroup) GetRequiredField() string {
+	if m != nil && m.RequiredField != nil {
+		return *m.RequiredField
+	}
+	return ""
+}
+
+type GoTest_RepeatedGroup struct {
+	RequiredField    *string `protobuf:"bytes,81,req" json:"RequiredField,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *GoTest_RepeatedGroup) Reset() { *m = GoTest_RepeatedGroup{} }
+
+func (m *GoTest_RepeatedGroup) GetRequiredField() string {
+	if m != nil && m.RequiredField != nil {
+		return *m.RequiredField
+	}
+	return ""
+}
+
+type GoTest_OptionalGroup struct {
+	RequiredField    *string `protobuf:"bytes,91,req" json:"RequiredField,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *GoTest_OptionalGroup) Reset() { *m = GoTest_OptionalGroup{} }
+
+func (m *GoTest_OptionalGroup) GetRequiredField() string {
+	if m != nil && m.RequiredField != nil {
+		return *m.RequiredField
+	}
+	return ""
+}
+
+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"`
+	SkipFixed64      *uint64               `protobuf:"fixed64,13,req,name=skip_fixed64" json:"skip_fixed64,omitempty"`
+	SkipString       *string               `protobuf:"bytes,14,req,name=skip_string" json:"skip_string,omitempty"`
+	Skipgroup        *GoSkipTest_SkipGroup `protobuf:"group,15,req,name=SkipGroup" json:"skipgroup,omitempty"`
+	XXX_unrecognized []byte                `json:"-"`
+}
+
+func (m *GoSkipTest) Reset()         { *m = GoSkipTest{} }
+func (m *GoSkipTest) String() string { return proto.CompactTextString(m) }
+func (*GoSkipTest) ProtoMessage()    {}
+
+func (m *GoSkipTest) GetSkipInt32() int32 {
+	if m != nil && m.SkipInt32 != nil {
+		return *m.SkipInt32
+	}
+	return 0
+}
+
+func (m *GoSkipTest) GetSkipFixed32() uint32 {
+	if m != nil && m.SkipFixed32 != nil {
+		return *m.SkipFixed32
+	}
+	return 0
+}
+
+func (m *GoSkipTest) GetSkipFixed64() uint64 {
+	if m != nil && m.SkipFixed64 != nil {
+		return *m.SkipFixed64
+	}
+	return 0
+}
+
+func (m *GoSkipTest) GetSkipString() string {
+	if m != nil && m.SkipString != nil {
+		return *m.SkipString
+	}
+	return ""
+}
+
+func (m *GoSkipTest) GetSkipgroup() *GoSkipTest_SkipGroup {
+	if m != nil {
+		return m.Skipgroup
+	}
+	return nil
+}
+
+type GoSkipTest_SkipGroup struct {
+	GroupInt32       *int32  `protobuf:"varint,16,req,name=group_int32" json:"group_int32,omitempty"`
+	GroupString      *string `protobuf:"bytes,17,req,name=group_string" json:"group_string,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *GoSkipTest_SkipGroup) Reset() { *m = GoSkipTest_SkipGroup{} }
+
+func (m *GoSkipTest_SkipGroup) GetGroupInt32() int32 {
+	if m != nil && m.GroupInt32 != nil {
+		return *m.GroupInt32
+	}
+	return 0
+}
+
+func (m *GoSkipTest_SkipGroup) GetGroupString() string {
+	if m != nil && m.GroupString != nil {
+		return *m.GroupString
+	}
+	return ""
+}
+
+type NonPackedTest struct {
+	A                []int32 `protobuf:"varint,1,rep,name=a" json:"a,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *NonPackedTest) Reset()         { *m = NonPackedTest{} }
+func (m *NonPackedTest) String() string { return proto.CompactTextString(m) }
+func (*NonPackedTest) ProtoMessage()    {}
+
+func (m *NonPackedTest) GetA() []int32 {
+	if m != nil {
+		return m.A
+	}
+	return nil
+}
+
+type PackedTest struct {
+	B                []int32 `protobuf:"varint,1,rep,packed,name=b" json:"b,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *PackedTest) Reset()         { *m = PackedTest{} }
+func (m *PackedTest) String() string { return proto.CompactTextString(m) }
+func (*PackedTest) ProtoMessage()    {}
+
+func (m *PackedTest) GetB() []int32 {
+	if m != nil {
+		return m.B
+	}
+	return nil
+}
+
+type MaxTag struct {
+	LastField        *string `protobuf:"bytes,536870911,opt,name=last_field" json:"last_field,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *MaxTag) Reset()         { *m = MaxTag{} }
+func (m *MaxTag) String() string { return proto.CompactTextString(m) }
+func (*MaxTag) ProtoMessage()    {}
+
+func (m *MaxTag) GetLastField() string {
+	if m != nil && m.LastField != nil {
+		return *m.LastField
+	}
+	return ""
+}
+
+type OldMessage struct {
+	Nested           *OldMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"`
+	XXX_unrecognized []byte             `json:"-"`
+}
+
+func (m *OldMessage) Reset()         { *m = OldMessage{} }
+func (m *OldMessage) String() string { return proto.CompactTextString(m) }
+func (*OldMessage) ProtoMessage()    {}
+
+func (m *OldMessage) GetNested() *OldMessage_Nested {
+	if m != nil {
+		return m.Nested
+	}
+	return nil
+}
+
+type OldMessage_Nested struct {
+	Name             *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *OldMessage_Nested) Reset()         { *m = OldMessage_Nested{} }
+func (m *OldMessage_Nested) String() string { return proto.CompactTextString(m) }
+func (*OldMessage_Nested) ProtoMessage()    {}
+
+func (m *OldMessage_Nested) GetName() string {
+	if m != nil && m.Name != nil {
+		return *m.Name
+	}
+	return ""
+}
+
+type NewMessage struct {
+	Nested           *NewMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"`
+	XXX_unrecognized []byte             `json:"-"`
+}
+
+func (m *NewMessage) Reset()         { *m = NewMessage{} }
+func (m *NewMessage) String() string { return proto.CompactTextString(m) }
+func (*NewMessage) ProtoMessage()    {}
+
+func (m *NewMessage) GetNested() *NewMessage_Nested {
+	if m != nil {
+		return m.Nested
+	}
+	return nil
+}
+
+type NewMessage_Nested struct {
+	Name             *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	FoodGroup        *string `protobuf:"bytes,2,opt,name=food_group" json:"food_group,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *NewMessage_Nested) Reset()         { *m = NewMessage_Nested{} }
+func (m *NewMessage_Nested) String() string { return proto.CompactTextString(m) }
+func (*NewMessage_Nested) ProtoMessage()    {}
+
+func (m *NewMessage_Nested) GetName() string {
+	if m != nil && m.Name != nil {
+		return *m.Name
+	}
+	return ""
+}
+
+func (m *NewMessage_Nested) GetFoodGroup() string {
+	if m != nil && m.FoodGroup != nil {
+		return *m.FoodGroup
+	}
+	return ""
+}
+
+type InnerMessage struct {
+	Host             *string `protobuf:"bytes,1,req,name=host" json:"host,omitempty"`
+	Port             *int32  `protobuf:"varint,2,opt,name=port,def=4000" json:"port,omitempty"`
+	Connected        *bool   `protobuf:"varint,3,opt,name=connected" json:"connected,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *InnerMessage) Reset()         { *m = InnerMessage{} }
+func (m *InnerMessage) String() string { return proto.CompactTextString(m) }
+func (*InnerMessage) ProtoMessage()    {}
+
+const Default_InnerMessage_Port int32 = 4000
+
+func (m *InnerMessage) GetHost() string {
+	if m != nil && m.Host != nil {
+		return *m.Host
+	}
+	return ""
+}
+
+func (m *InnerMessage) GetPort() int32 {
+	if m != nil && m.Port != nil {
+		return *m.Port
+	}
+	return Default_InnerMessage_Port
+}
+
+func (m *InnerMessage) GetConnected() bool {
+	if m != nil && m.Connected != nil {
+		return *m.Connected
+	}
+	return false
+}
+
+type OtherMessage struct {
+	Key              *int64        `protobuf:"varint,1,opt,name=key" json:"key,omitempty"`
+	Value            []byte        `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
+	Weight           *float32      `protobuf:"fixed32,3,opt,name=weight" json:"weight,omitempty"`
+	Inner            *InnerMessage `protobuf:"bytes,4,opt,name=inner" json:"inner,omitempty"`
+	XXX_unrecognized []byte        `json:"-"`
+}
+
+func (m *OtherMessage) Reset()         { *m = OtherMessage{} }
+func (m *OtherMessage) String() string { return proto.CompactTextString(m) }
+func (*OtherMessage) ProtoMessage()    {}
+
+func (m *OtherMessage) GetKey() int64 {
+	if m != nil && m.Key != nil {
+		return *m.Key
+	}
+	return 0
+}
+
+func (m *OtherMessage) GetValue() []byte {
+	if m != nil {
+		return m.Value
+	}
+	return nil
+}
+
+func (m *OtherMessage) GetWeight() float32 {
+	if m != nil && m.Weight != nil {
+		return *m.Weight
+	}
+	return 0
+}
+
+func (m *OtherMessage) GetInner() *InnerMessage {
+	if m != nil {
+		return m.Inner
+	}
+	return nil
+}
+
+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"`
+	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"`
+	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:"-"`
+	XXX_unrecognized []byte                    `json:"-"`
+}
+
+func (m *MyMessage) Reset()         { *m = MyMessage{} }
+func (m *MyMessage) String() string { return proto.CompactTextString(m) }
+func (*MyMessage) ProtoMessage()    {}
+
+var extRange_MyMessage = []proto.ExtensionRange{
+	{100, 536870911},
+}
+
+func (*MyMessage) ExtensionRangeArray() []proto.ExtensionRange {
+	return extRange_MyMessage
+}
+func (m *MyMessage) ExtensionMap() map[int32]proto.Extension {
+	if m.XXX_extensions == nil {
+		m.XXX_extensions = make(map[int32]proto.Extension)
+	}
+	return m.XXX_extensions
+}
+
+func (m *MyMessage) GetCount() int32 {
+	if m != nil && m.Count != nil {
+		return *m.Count
+	}
+	return 0
+}
+
+func (m *MyMessage) GetName() string {
+	if m != nil && m.Name != nil {
+		return *m.Name
+	}
+	return ""
+}
+
+func (m *MyMessage) GetQuote() string {
+	if m != nil && m.Quote != nil {
+		return *m.Quote
+	}
+	return ""
+}
+
+func (m *MyMessage) GetPet() []string {
+	if m != nil {
+		return m.Pet
+	}
+	return nil
+}
+
+func (m *MyMessage) GetInner() *InnerMessage {
+	if m != nil {
+		return m.Inner
+	}
+	return nil
+}
+
+func (m *MyMessage) GetOthers() []*OtherMessage {
+	if m != nil {
+		return m.Others
+	}
+	return nil
+}
+
+func (m *MyMessage) GetBikeshed() MyMessage_Color {
+	if m != nil && m.Bikeshed != nil {
+		return *m.Bikeshed
+	}
+	return 0
+}
+
+func (m *MyMessage) GetSomegroup() *MyMessage_SomeGroup {
+	if m != nil {
+		return m.Somegroup
+	}
+	return nil
+}
+
+func (m *MyMessage) GetRepBytes() [][]byte {
+	if m != nil {
+		return m.RepBytes
+	}
+	return nil
+}
+
+func (m *MyMessage) GetBigfloat() float64 {
+	if m != nil && m.Bigfloat != nil {
+		return *m.Bigfloat
+	}
+	return 0
+}
+
+type MyMessage_SomeGroup struct {
+	GroupField       *int32 `protobuf:"varint,9,opt,name=group_field" json:"group_field,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *MyMessage_SomeGroup) Reset() { *m = MyMessage_SomeGroup{} }
+
+func (m *MyMessage_SomeGroup) GetGroupField() int32 {
+	if m != nil && m.GroupField != nil {
+		return *m.GroupField
+	}
+	return 0
+}
+
+type Ext struct {
+	Data             *string `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *Ext) Reset()         { *m = Ext{} }
+func (m *Ext) String() string { return proto.CompactTextString(m) }
+func (*Ext) ProtoMessage()    {}
+
+func (m *Ext) GetData() string {
+	if m != nil && m.Data != nil {
+		return *m.Data
+	}
+	return ""
+}
+
+var E_Ext_More = &proto.ExtensionDesc{
+	ExtendedType:  (*MyMessage)(nil),
+	ExtensionType: (*Ext)(nil),
+	Field:         103,
+	Name:          "testdata.Ext.more",
+	Tag:           "bytes,103,opt,name=more",
+}
+
+var E_Ext_Text = &proto.ExtensionDesc{
+	ExtendedType:  (*MyMessage)(nil),
+	ExtensionType: (*string)(nil),
+	Field:         104,
+	Name:          "testdata.Ext.text",
+	Tag:           "bytes,104,opt,name=text",
+}
+
+var E_Ext_Number = &proto.ExtensionDesc{
+	ExtendedType:  (*MyMessage)(nil),
+	ExtensionType: (*int32)(nil),
+	Field:         105,
+	Name:          "testdata.Ext.number",
+	Tag:           "varint,105,opt,name=number",
+}
+
+type MessageList struct {
+	Message          []*MessageList_Message `protobuf:"group,1,rep" json:"message,omitempty"`
+	XXX_unrecognized []byte                 `json:"-"`
+}
+
+func (m *MessageList) Reset()         { *m = MessageList{} }
+func (m *MessageList) String() string { return proto.CompactTextString(m) }
+func (*MessageList) ProtoMessage()    {}
+
+func (m *MessageList) GetMessage() []*MessageList_Message {
+	if m != nil {
+		return m.Message
+	}
+	return nil
+}
+
+type MessageList_Message struct {
+	Name             *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"`
+	Count            *int32  `protobuf:"varint,3,req,name=count" json:"count,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *MessageList_Message) Reset() { *m = MessageList_Message{} }
+
+func (m *MessageList_Message) GetName() string {
+	if m != nil && m.Name != nil {
+		return *m.Name
+	}
+	return ""
+}
+
+func (m *MessageList_Message) GetCount() int32 {
+	if m != nil && m.Count != nil {
+		return *m.Count
+	}
+	return 0
+}
+
+type Strings struct {
+	StringField      *string `protobuf:"bytes,1,opt,name=string_field" json:"string_field,omitempty"`
+	BytesField       []byte  `protobuf:"bytes,2,opt,name=bytes_field" json:"bytes_field,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *Strings) Reset()         { *m = Strings{} }
+func (m *Strings) String() string { return proto.CompactTextString(m) }
+func (*Strings) ProtoMessage()    {}
+
+func (m *Strings) GetStringField() string {
+	if m != nil && m.StringField != nil {
+		return *m.StringField
+	}
+	return ""
+}
+
+func (m *Strings) GetBytesField() []byte {
+	if m != nil {
+		return m.BytesField
+	}
+	return nil
+}
+
+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:"-"`
+}
+
+func (m *Defaults) Reset()         { *m = Defaults{} }
+func (m *Defaults) String() string { return proto.CompactTextString(m) }
+func (*Defaults) ProtoMessage()    {}
+
+const Default_Defaults_F_Bool bool = true
+const Default_Defaults_F_Int32 int32 = 32
+const Default_Defaults_F_Int64 int64 = 64
+const Default_Defaults_F_Fixed32 uint32 = 320
+const Default_Defaults_F_Fixed64 uint64 = 640
+const Default_Defaults_F_Uint32 uint32 = 3200
+const Default_Defaults_F_Uint64 uint64 = 6400
+const Default_Defaults_F_Float float32 = 314159
+const Default_Defaults_F_Double float64 = 271828
+const Default_Defaults_F_String string = "hello, \"world!\"\n"
+
+var Default_Defaults_F_Bytes []byte = []byte("Bignose")
+
+const Default_Defaults_F_Sint32 int32 = -32
+const Default_Defaults_F_Sint64 int64 = -64
+const Default_Defaults_F_Enum Defaults_Color = Defaults_GREEN
+
+var Default_Defaults_F_Pinf float32 = float32(math.Inf(1))
+var Default_Defaults_F_Ninf float32 = float32(math.Inf(-1))
+var Default_Defaults_F_Nan float32 = float32(math.NaN())
+
+func (m *Defaults) GetF_Bool() bool {
+	if m != nil && m.F_Bool != nil {
+		return *m.F_Bool
+	}
+	return Default_Defaults_F_Bool
+}
+
+func (m *Defaults) GetF_Int32() int32 {
+	if m != nil && m.F_Int32 != nil {
+		return *m.F_Int32
+	}
+	return Default_Defaults_F_Int32
+}
+
+func (m *Defaults) GetF_Int64() int64 {
+	if m != nil && m.F_Int64 != nil {
+		return *m.F_Int64
+	}
+	return Default_Defaults_F_Int64
+}
+
+func (m *Defaults) GetF_Fixed32() uint32 {
+	if m != nil && m.F_Fixed32 != nil {
+		return *m.F_Fixed32
+	}
+	return Default_Defaults_F_Fixed32
+}
+
+func (m *Defaults) GetF_Fixed64() uint64 {
+	if m != nil && m.F_Fixed64 != nil {
+		return *m.F_Fixed64
+	}
+	return Default_Defaults_F_Fixed64
+}
+
+func (m *Defaults) GetF_Uint32() uint32 {
+	if m != nil && m.F_Uint32 != nil {
+		return *m.F_Uint32
+	}
+	return Default_Defaults_F_Uint32
+}
+
+func (m *Defaults) GetF_Uint64() uint64 {
+	if m != nil && m.F_Uint64 != nil {
+		return *m.F_Uint64
+	}
+	return Default_Defaults_F_Uint64
+}
+
+func (m *Defaults) GetF_Float() float32 {
+	if m != nil && m.F_Float != nil {
+		return *m.F_Float
+	}
+	return Default_Defaults_F_Float
+}
+
+func (m *Defaults) GetF_Double() float64 {
+	if m != nil && m.F_Double != nil {
+		return *m.F_Double
+	}
+	return Default_Defaults_F_Double
+}
+
+func (m *Defaults) GetF_String() string {
+	if m != nil && m.F_String != nil {
+		return *m.F_String
+	}
+	return Default_Defaults_F_String
+}
+
+func (m *Defaults) GetF_Bytes() []byte {
+	if m != nil && m.F_Bytes != nil {
+		return m.F_Bytes
+	}
+	return append([]byte(nil), Default_Defaults_F_Bytes...)
+}
+
+func (m *Defaults) GetF_Sint32() int32 {
+	if m != nil && m.F_Sint32 != nil {
+		return *m.F_Sint32
+	}
+	return Default_Defaults_F_Sint32
+}
+
+func (m *Defaults) GetF_Sint64() int64 {
+	if m != nil && m.F_Sint64 != nil {
+		return *m.F_Sint64
+	}
+	return Default_Defaults_F_Sint64
+}
+
+func (m *Defaults) GetF_Enum() Defaults_Color {
+	if m != nil && m.F_Enum != nil {
+		return *m.F_Enum
+	}
+	return Default_Defaults_F_Enum
+}
+
+func (m *Defaults) GetF_Pinf() float32 {
+	if m != nil && m.F_Pinf != nil {
+		return *m.F_Pinf
+	}
+	return Default_Defaults_F_Pinf
+}
+
+func (m *Defaults) GetF_Ninf() float32 {
+	if m != nil && m.F_Ninf != nil {
+		return *m.F_Ninf
+	}
+	return Default_Defaults_F_Ninf
+}
+
+func (m *Defaults) GetF_Nan() float32 {
+	if m != nil && m.F_Nan != nil {
+		return *m.F_Nan
+	}
+	return Default_Defaults_F_Nan
+}
+
+func (m *Defaults) GetSub() *SubDefaults {
+	if m != nil {
+		return m.Sub
+	}
+	return nil
+}
+
+type SubDefaults struct {
+	N                *int64 `protobuf:"varint,1,opt,name=n,def=7" json:"n,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *SubDefaults) Reset()         { *m = SubDefaults{} }
+func (m *SubDefaults) String() string { return proto.CompactTextString(m) }
+func (*SubDefaults) ProtoMessage()    {}
+
+const Default_SubDefaults_N int64 = 7
+
+func (m *SubDefaults) GetN() int64 {
+	if m != nil && m.N != nil {
+		return *m.N
+	}
+	return Default_SubDefaults_N
+}
+
+type RepeatedEnum struct {
+	Color            []RepeatedEnum_Color `protobuf:"varint,1,rep,name=color,enum=testdata.RepeatedEnum_Color" json:"color,omitempty"`
+	XXX_unrecognized []byte               `json:"-"`
+}
+
+func (m *RepeatedEnum) Reset()         { *m = RepeatedEnum{} }
+func (m *RepeatedEnum) String() string { return proto.CompactTextString(m) }
+func (*RepeatedEnum) ProtoMessage()    {}
+
+func (m *RepeatedEnum) GetColor() []RepeatedEnum_Color {
+	if m != nil {
+		return m.Color
+	}
+	return nil
+}
+
+type MoreRepeated struct {
+	Bools            []bool   `protobuf:"varint,1,rep,name=bools" json:"bools,omitempty"`
+	BoolsPacked      []bool   `protobuf:"varint,2,rep,packed,name=bools_packed" json:"bools_packed,omitempty"`
+	Ints             []int32  `protobuf:"varint,3,rep,name=ints" json:"ints,omitempty"`
+	IntsPacked       []int32  `protobuf:"varint,4,rep,packed,name=ints_packed" json:"ints_packed,omitempty"`
+	Strings          []string `protobuf:"bytes,5,rep,name=strings" json:"strings,omitempty"`
+	XXX_unrecognized []byte   `json:"-"`
+}
+
+func (m *MoreRepeated) Reset()         { *m = MoreRepeated{} }
+func (m *MoreRepeated) String() string { return proto.CompactTextString(m) }
+func (*MoreRepeated) ProtoMessage()    {}
+
+func (m *MoreRepeated) GetBools() []bool {
+	if m != nil {
+		return m.Bools
+	}
+	return nil
+}
+
+func (m *MoreRepeated) GetBoolsPacked() []bool {
+	if m != nil {
+		return m.BoolsPacked
+	}
+	return nil
+}
+
+func (m *MoreRepeated) GetInts() []int32 {
+	if m != nil {
+		return m.Ints
+	}
+	return nil
+}
+
+func (m *MoreRepeated) GetIntsPacked() []int32 {
+	if m != nil {
+		return m.IntsPacked
+	}
+	return nil
+}
+
+func (m *MoreRepeated) GetStrings() []string {
+	if m != nil {
+		return m.Strings
+	}
+	return nil
+}
+
+type GroupOld struct {
+	G                *GroupOld_G `protobuf:"group,1,opt" json:"g,omitempty"`
+	XXX_unrecognized []byte      `json:"-"`
+}
+
+func (m *GroupOld) Reset()         { *m = GroupOld{} }
+func (m *GroupOld) String() string { return proto.CompactTextString(m) }
+func (*GroupOld) ProtoMessage()    {}
+
+func (m *GroupOld) GetG() *GroupOld_G {
+	if m != nil {
+		return m.G
+	}
+	return nil
+}
+
+type GroupOld_G struct {
+	X                *int32 `protobuf:"varint,2,opt,name=x" json:"x,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *GroupOld_G) Reset() { *m = GroupOld_G{} }
+
+func (m *GroupOld_G) GetX() int32 {
+	if m != nil && m.X != nil {
+		return *m.X
+	}
+	return 0
+}
+
+type GroupNew struct {
+	G                *GroupNew_G `protobuf:"group,1,opt" json:"g,omitempty"`
+	XXX_unrecognized []byte      `json:"-"`
+}
+
+func (m *GroupNew) Reset()         { *m = GroupNew{} }
+func (m *GroupNew) String() string { return proto.CompactTextString(m) }
+func (*GroupNew) ProtoMessage()    {}
+
+func (m *GroupNew) GetG() *GroupNew_G {
+	if m != nil {
+		return m.G
+	}
+	return nil
+}
+
+type GroupNew_G struct {
+	X                *int32 `protobuf:"varint,2,opt,name=x" json:"x,omitempty"`
+	Y                *int32 `protobuf:"varint,3,opt,name=y" json:"y,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *GroupNew_G) Reset() { *m = GroupNew_G{} }
+
+func (m *GroupNew_G) GetX() int32 {
+	if m != nil && m.X != nil {
+		return *m.X
+	}
+	return 0
+}
+
+func (m *GroupNew_G) GetY() int32 {
+	if m != nil && m.Y != nil {
+		return *m.Y
+	}
+	return 0
+}
+
+var E_Greeting = &proto.ExtensionDesc{
+	ExtendedType:  (*MyMessage)(nil),
+	ExtensionType: ([]string)(nil),
+	Field:         106,
+	Name:          "testdata.greeting",
+	Tag:           "bytes,106,rep,name=greeting",
+}
+
+func init() {
+	proto.RegisterEnum("testdata.FOO", FOO_name, FOO_value)
+	proto.RegisterEnum("testdata.GoTest_KIND", GoTest_KIND_name, GoTest_KIND_value)
+	proto.RegisterEnum("testdata.MyMessage_Color", MyMessage_Color_name, MyMessage_Color_value)
+	proto.RegisterEnum("testdata.Defaults_Color", Defaults_Color_name, Defaults_Color_value)
+	proto.RegisterEnum("testdata.RepeatedEnum_Color", RepeatedEnum_Color_name, RepeatedEnum_Color_value)
+	proto.RegisterExtension(E_Ext_More)
+	proto.RegisterExtension(E_Ext_Text)
+	proto.RegisterExtension(E_Ext_Number)
+	proto.RegisterExtension(E_Greeting)
+}

+ 420 - 0
third_party/code.google.com/p/gogoprotobuf/proto/testdata/test.proto

@@ -0,0 +1,420 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+// A feature-rich test file for the protocol compiler and libraries.
+
+syntax = "proto2";
+
+package testdata;
+
+enum FOO { FOO1 = 1; };
+
+message GoEnum {
+  required FOO foo = 1;
+}
+
+message GoTestField {
+  required string Label = 1;
+  required string Type = 2;
+}
+
+message GoTest {
+  // An enum, for completeness.
+  enum KIND {
+    VOID = 0;
+
+    // Basic types
+    BOOL = 1;
+    BYTES = 2;
+    FINGERPRINT = 3;
+    FLOAT = 4;
+    INT = 5;
+    STRING = 6;
+    TIME = 7;
+
+    // Groupings
+    TUPLE = 8;
+    ARRAY = 9;
+    MAP = 10;
+
+    // Table types
+    TABLE = 11;
+
+    // Functions
+    FUNCTION = 12;  // last tag
+  };
+
+  // Some typical parameters
+  required KIND Kind = 1;
+  optional string Table = 2;
+  optional int32 Param = 3;
+
+  // Required, repeated and optional foreign fields.
+  required GoTestField RequiredField = 4;
+  repeated GoTestField RepeatedField = 5;
+  optional GoTestField OptionalField = 6;
+
+  // Required fields of all basic types
+  required bool F_Bool_required = 10;
+  required int32 F_Int32_required = 11;
+  required int64 F_Int64_required = 12;
+  required fixed32 F_Fixed32_required = 13;
+  required fixed64 F_Fixed64_required = 14;
+  required uint32 F_Uint32_required = 15;
+  required uint64 F_Uint64_required = 16;
+  required float F_Float_required = 17;
+  required double F_Double_required = 18;
+  required string F_String_required = 19;
+  required bytes F_Bytes_required = 101;
+  required sint32 F_Sint32_required = 102;
+  required sint64 F_Sint64_required = 103;
+
+  // Repeated fields of all basic types
+  repeated bool F_Bool_repeated = 20;
+  repeated int32 F_Int32_repeated = 21;
+  repeated int64 F_Int64_repeated = 22;
+  repeated fixed32 F_Fixed32_repeated = 23;
+  repeated fixed64 F_Fixed64_repeated = 24;
+  repeated uint32 F_Uint32_repeated = 25;
+  repeated uint64 F_Uint64_repeated = 26;
+  repeated float F_Float_repeated = 27;
+  repeated double F_Double_repeated = 28;
+  repeated string F_String_repeated = 29;
+  repeated bytes F_Bytes_repeated = 201;
+  repeated sint32 F_Sint32_repeated = 202;
+  repeated sint64 F_Sint64_repeated = 203;
+
+  // Optional fields of all basic types
+  optional bool F_Bool_optional = 30;
+  optional int32 F_Int32_optional = 31;
+  optional int64 F_Int64_optional = 32;
+  optional fixed32 F_Fixed32_optional = 33;
+  optional fixed64 F_Fixed64_optional = 34;
+  optional uint32 F_Uint32_optional = 35;
+  optional uint64 F_Uint64_optional = 36;
+  optional float F_Float_optional = 37;
+  optional double F_Double_optional = 38;
+  optional string F_String_optional = 39;
+  optional bytes F_Bytes_optional = 301;
+  optional sint32 F_Sint32_optional = 302;
+  optional sint64 F_Sint64_optional = 303;
+
+  // Default-valued fields of all basic types
+  optional bool F_Bool_defaulted = 40 [default=true];
+  optional int32 F_Int32_defaulted = 41 [default=32];
+  optional int64 F_Int64_defaulted = 42 [default=64];
+  optional fixed32 F_Fixed32_defaulted = 43 [default=320];
+  optional fixed64 F_Fixed64_defaulted = 44 [default=640];
+  optional uint32 F_Uint32_defaulted = 45 [default=3200];
+  optional uint64 F_Uint64_defaulted = 46 [default=6400];
+  optional float F_Float_defaulted = 47 [default=314159.];
+  optional double F_Double_defaulted = 48 [default=271828.];
+  optional string F_String_defaulted = 49 [default="hello, \"world!\"\n"];
+  optional bytes F_Bytes_defaulted = 401 [default="Bignose"];
+  optional sint32 F_Sint32_defaulted = 402 [default = -32];
+  optional sint64 F_Sint64_defaulted = 403 [default = -64];
+
+  // Packed repeated fields (no string or bytes).
+  repeated bool F_Bool_repeated_packed = 50 [packed=true];
+  repeated int32 F_Int32_repeated_packed = 51 [packed=true];
+  repeated int64 F_Int64_repeated_packed = 52 [packed=true];
+  repeated fixed32 F_Fixed32_repeated_packed = 53 [packed=true];
+  repeated fixed64 F_Fixed64_repeated_packed = 54 [packed=true];
+  repeated uint32 F_Uint32_repeated_packed = 55 [packed=true];
+  repeated uint64 F_Uint64_repeated_packed = 56 [packed=true];
+  repeated float F_Float_repeated_packed = 57 [packed=true];
+  repeated double F_Double_repeated_packed = 58 [packed=true];
+  repeated sint32 F_Sint32_repeated_packed = 502 [packed=true];
+  repeated sint64 F_Sint64_repeated_packed = 503 [packed=true];
+
+  // Required, repeated, and optional groups.
+  required group RequiredGroup = 70 {
+    required string RequiredField = 71;
+  };
+
+  repeated group RepeatedGroup = 80 {
+    required string RequiredField = 81;
+  };
+
+  optional group OptionalGroup = 90 {
+    required string RequiredField = 91;
+  };
+}
+
+// For testing skipping of unrecognized fields.
+// Numbers are all big, larger than tag numbers in GoTestField,
+// the message used in the corresponding test.
+message GoSkipTest {
+  required int32 skip_int32 = 11;
+  required fixed32 skip_fixed32 = 12;
+  required fixed64 skip_fixed64 = 13;
+  required string skip_string = 14;
+  required group SkipGroup = 15 {
+    required int32 group_int32 = 16;
+    required string group_string = 17;
+  }
+}
+
+// For testing packed/non-packed decoder switching.
+// A serialized instance of one should be deserializable as the other.
+message NonPackedTest {
+  repeated int32 a = 1;
+}
+
+message PackedTest {
+  repeated int32 b = 1 [packed=true];
+}
+
+message MaxTag {
+  // Maximum possible tag number.
+  optional string last_field = 536870911;
+}
+
+message OldMessage {
+  message Nested {
+    optional string name = 1;
+  }
+  optional Nested nested = 1;
+}
+
+// NewMessage is wire compatible with OldMessage;
+// imagine it as a future version.
+message NewMessage {
+  message Nested {
+    optional string name = 1;
+    optional string food_group = 2;
+  }
+  optional Nested nested = 1;
+}
+
+// Smaller tests for ASCII formatting.
+
+message InnerMessage {
+  required string host = 1;
+  optional int32 port = 2 [default=4000];
+  optional bool connected = 3;
+}
+
+message OtherMessage {
+  optional int64 key = 1;
+  optional bytes value = 2;
+  optional float weight = 3;
+  optional InnerMessage inner = 4;
+}
+
+message MyMessage {
+  required int32 count = 1;
+  optional string name = 2;
+  optional string quote = 3;
+  repeated string pet = 4;
+  optional InnerMessage inner = 5;
+  repeated OtherMessage others = 6;
+  repeated InnerMessage rep_inner = 12;
+
+  enum Color {
+    RED = 0;
+    GREEN = 1;
+    BLUE = 2;
+  };
+  optional Color bikeshed = 7;
+
+  optional group SomeGroup = 8 {
+    optional int32 group_field = 9;
+  }
+
+  // This field becomes [][]byte in the generated code.
+  repeated bytes rep_bytes = 10;
+
+  optional double bigfloat = 11;
+
+  extensions 100 to max;
+}
+
+message Ext {
+  extend MyMessage {
+    optional Ext more = 103;
+    optional string text = 104;
+    optional int32 number = 105;
+  }
+
+  optional string data = 1;
+}
+
+extend MyMessage {
+  repeated string greeting = 106;
+}
+
+message MyMessageSet {
+  option message_set_wire_format = true;
+  extensions 100 to max;
+}
+
+message Empty {
+}
+
+extend MyMessageSet {
+    optional Empty x201 = 201;
+    optional Empty x202 = 202;
+    optional Empty x203 = 203;
+    optional Empty x204 = 204;
+    optional Empty x205 = 205;
+    optional Empty x206 = 206;
+    optional Empty x207 = 207;
+    optional Empty x208 = 208;
+    optional Empty x209 = 209;
+    optional Empty x210 = 210;
+    optional Empty x211 = 211;
+    optional Empty x212 = 212;
+    optional Empty x213 = 213;
+    optional Empty x214 = 214;
+    optional Empty x215 = 215;
+    optional Empty x216 = 216;
+    optional Empty x217 = 217;
+    optional Empty x218 = 218;
+    optional Empty x219 = 219;
+    optional Empty x220 = 220;
+    optional Empty x221 = 221;
+    optional Empty x222 = 222;
+    optional Empty x223 = 223;
+    optional Empty x224 = 224;
+    optional Empty x225 = 225;
+    optional Empty x226 = 226;
+    optional Empty x227 = 227;
+    optional Empty x228 = 228;
+    optional Empty x229 = 229;
+    optional Empty x230 = 230;
+    optional Empty x231 = 231;
+    optional Empty x232 = 232;
+    optional Empty x233 = 233;
+    optional Empty x234 = 234;
+    optional Empty x235 = 235;
+    optional Empty x236 = 236;
+    optional Empty x237 = 237;
+    optional Empty x238 = 238;
+    optional Empty x239 = 239;
+    optional Empty x240 = 240;
+    optional Empty x241 = 241;
+    optional Empty x242 = 242;
+    optional Empty x243 = 243;
+    optional Empty x244 = 244;
+    optional Empty x245 = 245;
+    optional Empty x246 = 246;
+    optional Empty x247 = 247;
+    optional Empty x248 = 248;
+    optional Empty x249 = 249;
+    optional Empty x250 = 250;
+}
+
+message MessageList {
+  repeated group Message = 1 {
+    required string name = 2;
+    required int32 count = 3;
+  }
+}
+
+message Strings {
+  optional string string_field = 1;
+  optional bytes bytes_field = 2;
+}
+
+message Defaults {
+  enum Color {
+    RED = 0;
+    GREEN = 1;
+    BLUE = 2;
+  }
+
+  // Default-valued fields of all basic types.
+  // Same as GoTest, but copied here to make testing easier.
+  optional bool F_Bool = 1 [default=true];
+  optional int32 F_Int32 = 2 [default=32];
+  optional int64 F_Int64 = 3 [default=64];
+  optional fixed32 F_Fixed32 = 4 [default=320];
+  optional fixed64 F_Fixed64 = 5 [default=640];
+  optional uint32 F_Uint32 = 6 [default=3200];
+  optional uint64 F_Uint64 = 7 [default=6400];
+  optional float F_Float = 8 [default=314159.];
+  optional double F_Double = 9 [default=271828.];
+  optional string F_String = 10 [default="hello, \"world!\"\n"];
+  optional bytes F_Bytes = 11 [default="Bignose"];
+  optional sint32 F_Sint32 = 12 [default=-32];
+  optional sint64 F_Sint64 = 13 [default=-64];
+  optional Color F_Enum = 14 [default=GREEN];
+
+  // More fields with crazy defaults.
+  optional float F_Pinf = 15 [default=inf];
+  optional float F_Ninf = 16 [default=-inf];
+  optional float F_Nan = 17 [default=nan];
+
+  // Sub-message.
+  optional SubDefaults sub = 18;
+}
+
+message SubDefaults {
+  optional int64 n = 1 [default=7];
+}
+
+message RepeatedEnum {
+  enum Color {
+    RED = 1;
+  }
+  repeated Color color = 1;
+}
+
+message MoreRepeated {
+  repeated bool bools = 1;
+  repeated bool bools_packed = 2 [packed=true];
+  repeated int32 ints = 3;
+  repeated int32 ints_packed = 4 [packed=true];
+  repeated int64 int64s_packed = 7 [packed=true];
+  repeated string strings = 5;
+  repeated fixed32 fixeds = 6;
+}
+
+// GroupOld and GroupNew have the same wire format.
+// GroupNew has a new field inside a group.
+
+message GroupOld {
+  optional group G = 101 {
+    optional int32 x = 2;
+  }
+}
+
+message GroupNew {
+  optional group G = 101 {
+    optional int32 x = 2;
+    optional int32 y = 3;
+  }
+}
+
+message FloatingPoint {
+  required double f = 1;
+}

+ 686 - 0
third_party/code.google.com/p/gogoprotobuf/proto/text.go

@@ -0,0 +1,686 @@
+// Extensions for Protocol Buffers to create more go like structures.
+//
+// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+// http://code.google.com/p/gogoprotobuf/gogoproto
+//
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+package proto
+
+// Functions for writing the text protocol buffer format.
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"log"
+	"math"
+	"os"
+	"reflect"
+	"sort"
+	"strings"
+)
+
+var (
+	newline         = []byte("\n")
+	spaces          = []byte("                                        ")
+	gtNewline       = []byte(">\n")
+	endBraceNewline = []byte("}\n")
+	backslashN      = []byte{'\\', 'n'}
+	backslashR      = []byte{'\\', 'r'}
+	backslashT      = []byte{'\\', 't'}
+	backslashDQ     = []byte{'\\', '"'}
+	backslashBS     = []byte{'\\', '\\'}
+	posInf          = []byte("inf")
+	negInf          = []byte("-inf")
+	nan             = []byte("nan")
+)
+
+type writer interface {
+	io.Writer
+	WriteByte(byte) error
+}
+
+// textWriter is an io.Writer that tracks its indentation level.
+type textWriter struct {
+	ind      int
+	complete bool // if the current position is a complete line
+	compact  bool // whether to write out as a one-liner
+	w        writer
+}
+
+func (w *textWriter) WriteString(s string) (n int, err error) {
+	if !strings.Contains(s, "\n") {
+		if !w.compact && w.complete {
+			w.writeIndent()
+		}
+		w.complete = false
+		return io.WriteString(w.w, s)
+	}
+	// WriteString is typically called without newlines, so this
+	// codepath and its copy are rare.  We copy to avoid
+	// duplicating all of Write's logic here.
+	return w.Write([]byte(s))
+}
+
+func (w *textWriter) Write(p []byte) (n int, err error) {
+	newlines := bytes.Count(p, newline)
+	if newlines == 0 {
+		if !w.compact && w.complete {
+			w.writeIndent()
+		}
+		n, err = w.w.Write(p)
+		w.complete = false
+		return n, err
+	}
+
+	frags := bytes.SplitN(p, newline, newlines+1)
+	if w.compact {
+		for i, frag := range frags {
+			if i > 0 {
+				if err := w.w.WriteByte(' '); err != nil {
+					return n, err
+				}
+				n++
+			}
+			nn, err := w.w.Write(frag)
+			n += nn
+			if err != nil {
+				return n, err
+			}
+		}
+		return n, nil
+	}
+
+	for i, frag := range frags {
+		if w.complete {
+			w.writeIndent()
+		}
+		nn, err := w.w.Write(frag)
+		n += nn
+		if err != nil {
+			return n, err
+		}
+		if i+1 < len(frags) {
+			if err := w.w.WriteByte('\n'); err != nil {
+				return n, err
+			}
+			n++
+		}
+	}
+	w.complete = len(frags[len(frags)-1]) == 0
+	return n, nil
+}
+
+func (w *textWriter) WriteByte(c byte) error {
+	if w.compact && c == '\n' {
+		c = ' '
+	}
+	if !w.compact && w.complete {
+		w.writeIndent()
+	}
+	err := w.w.WriteByte(c)
+	w.complete = c == '\n'
+	return err
+}
+
+func (w *textWriter) indent() { w.ind++ }
+
+func (w *textWriter) unindent() {
+	if w.ind == 0 {
+		log.Printf("proto: textWriter unindented too far")
+		return
+	}
+	w.ind--
+}
+
+func writeName(w *textWriter, props *Properties) error {
+	if _, err := w.WriteString(props.OrigName); err != nil {
+		return err
+	}
+	if props.Wire != "group" {
+		return w.WriteByte(':')
+	}
+	return nil
+}
+
+var (
+	messageSetType = reflect.TypeOf((*MessageSet)(nil)).Elem()
+)
+
+// raw is the interface satisfied by RawMessage.
+type raw interface {
+	Bytes() []byte
+}
+
+func writeStruct(w *textWriter, sv reflect.Value) error {
+	if sv.Type() == messageSetType {
+		return writeMessageSet(w, sv.Addr().Interface().(*MessageSet))
+	}
+
+	st := sv.Type()
+	sprops := GetProperties(st)
+	for i := 0; i < sv.NumField(); i++ {
+		fv := sv.Field(i)
+		props := sprops.Prop[i]
+		name := st.Field(i).Name
+
+		if strings.HasPrefix(name, "XXX_") {
+			// There are two XXX_ fields:
+			//   XXX_unrecognized []byte
+			//   XXX_extensions   map[int32]proto.Extension
+			// The first is handled here;
+			// the second is handled at the bottom of this function.
+			if name == "XXX_unrecognized" && !fv.IsNil() {
+				if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {
+					return err
+				}
+			}
+			continue
+		}
+		if fv.Kind() == reflect.Ptr && fv.IsNil() {
+			// Field not filled in. This could be an optional field or
+			// a required field that wasn't filled in. Either way, there
+			// isn't anything we can show for it.
+			continue
+		}
+		if fv.Kind() == reflect.Slice && fv.IsNil() {
+			// Repeated field that is empty, or a bytes field that is unused.
+			continue
+		}
+
+		if props.Repeated && fv.Kind() == reflect.Slice {
+			// Repeated field.
+			for j := 0; j < fv.Len(); j++ {
+				if err := writeName(w, props); err != nil {
+					return err
+				}
+				if !w.compact {
+					if err := w.WriteByte(' '); err != nil {
+						return err
+					}
+				}
+				if len(props.Enum) > 0 {
+					if err := writeEnum(w, fv.Index(j), props); err != nil {
+						return err
+					}
+				} else if err := writeAny(w, fv.Index(j), props); err != nil {
+					return err
+				}
+				if err := w.WriteByte('\n'); err != nil {
+					return err
+				}
+			}
+			continue
+		}
+
+		if err := writeName(w, props); err != nil {
+			return err
+		}
+		if !w.compact {
+			if err := w.WriteByte(' '); err != nil {
+				return err
+			}
+		}
+		if b, ok := fv.Interface().(raw); ok {
+			if err := writeRaw(w, b.Bytes()); err != nil {
+				return err
+			}
+			continue
+		}
+
+		if len(props.Enum) > 0 {
+			if err := writeEnum(w, fv, props); err != nil {
+				return err
+			}
+		} else if err := writeAny(w, fv, props); err != nil {
+			return err
+		}
+
+		if err := w.WriteByte('\n'); err != nil {
+			return err
+		}
+	}
+
+	// Extensions (the XXX_extensions field).
+	pv := sv.Addr()
+	if pv.Type().Implements(extendableProtoType) {
+		if err := writeExtensions(w, pv); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// writeRaw writes an uninterpreted raw message.
+func writeRaw(w *textWriter, b []byte) error {
+	if err := w.WriteByte('<'); err != nil {
+		return err
+	}
+	if !w.compact {
+		if err := w.WriteByte('\n'); err != nil {
+			return err
+		}
+	}
+	w.indent()
+	if err := writeUnknownStruct(w, b); err != nil {
+		return err
+	}
+	w.unindent()
+	if err := w.WriteByte('>'); err != nil {
+		return err
+	}
+	return nil
+}
+
+// writeAny writes an arbitrary field.
+func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
+	v = reflect.Indirect(v)
+
+	if props != nil && len(props.CustomType) > 0 {
+		var custom Marshaler = v.Interface().(Marshaler)
+		data, err := custom.Marshal()
+		if err != nil {
+			return err
+		}
+		if err := writeString(w, string(data)); err != nil {
+			return err
+		}
+		return nil
+	}
+
+	// Floats have special cases.
+	if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
+		x := v.Float()
+		var b []byte
+		switch {
+		case math.IsInf(x, 1):
+			b = posInf
+		case math.IsInf(x, -1):
+			b = negInf
+		case math.IsNaN(x):
+			b = nan
+		}
+		if b != nil {
+			_, err := w.Write(b)
+			return err
+		}
+		// Other values are handled below.
+	}
+
+	// We don't attempt to serialise every possible value type; only those
+	// that can occur in protocol buffers.
+	switch v.Kind() {
+	case reflect.Slice:
+		// Should only be a []byte; repeated fields are handled in writeStruct.
+		if err := writeString(w, string(v.Interface().([]byte))); err != nil {
+			return err
+		}
+	case reflect.String:
+		if err := writeString(w, v.String()); err != nil {
+			return err
+		}
+	case reflect.Struct:
+		// Required/optional group/message.
+		var bra, ket byte = '<', '>'
+		if props != nil && props.Wire == "group" {
+			bra, ket = '{', '}'
+		}
+		if err := w.WriteByte(bra); err != nil {
+			return err
+		}
+		if !w.compact {
+			if err := w.WriteByte('\n'); err != nil {
+				return err
+			}
+		}
+		w.indent()
+		if err := writeStruct(w, v); err != nil {
+			return err
+		}
+		w.unindent()
+		if err := w.WriteByte(ket); err != nil {
+			return err
+		}
+	default:
+		_, err := fmt.Fprint(w, v.Interface())
+		return err
+	}
+	return nil
+}
+
+// equivalent to C's isprint.
+func isprint(c byte) bool {
+	return c >= 0x20 && c < 0x7f
+}
+
+// writeString writes a string in the protocol buffer text format.
+// It is similar to strconv.Quote except we don't use Go escape sequences,
+// we treat the string as a byte sequence, and we use octal escapes.
+// These differences are to maintain interoperability with the other
+// languages' implementations of the text format.
+func writeString(w *textWriter, s string) error {
+	// use WriteByte here to get any needed indent
+	if err := w.WriteByte('"'); err != nil {
+		return err
+	}
+	// Loop over the bytes, not the runes.
+	for i := 0; i < len(s); i++ {
+		var err error
+		// Divergence from C++: we don't escape apostrophes.
+		// There's no need to escape them, and the C++ parser
+		// copes with a naked apostrophe.
+		switch c := s[i]; c {
+		case '\n':
+			_, err = w.w.Write(backslashN)
+		case '\r':
+			_, err = w.w.Write(backslashR)
+		case '\t':
+			_, err = w.w.Write(backslashT)
+		case '"':
+			_, err = w.w.Write(backslashDQ)
+		case '\\':
+			_, err = w.w.Write(backslashBS)
+		default:
+			if isprint(c) {
+				err = w.w.WriteByte(c)
+			} else {
+				_, err = fmt.Fprintf(w.w, "\\%03o", c)
+			}
+		}
+		if err != nil {
+			return err
+		}
+	}
+	return w.WriteByte('"')
+}
+
+func writeMessageSet(w *textWriter, ms *MessageSet) error {
+	for _, item := range ms.Item {
+		id := *item.TypeId
+		if msd, ok := messageSetMap[id]; ok {
+			// Known message set type.
+			if _, err := fmt.Fprintf(w, "[%s]: <\n", msd.name); err != nil {
+				return err
+			}
+			w.indent()
+
+			pb := reflect.New(msd.t.Elem())
+			if err := Unmarshal(item.Message, pb.Interface().(Message)); err != nil {
+				if _, err := fmt.Fprintf(w, "/* bad message: %v */\n", err); err != nil {
+					return err
+				}
+			} else {
+				if err := writeStruct(w, pb.Elem()); err != nil {
+					return err
+				}
+			}
+		} else {
+			// Unknown type.
+			if _, err := fmt.Fprintf(w, "[%d]: <\n", id); err != nil {
+				return err
+			}
+			w.indent()
+			if err := writeUnknownStruct(w, item.Message); err != nil {
+				return err
+			}
+		}
+		w.unindent()
+		if _, err := w.Write(gtNewline); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func writeUnknownStruct(w *textWriter, data []byte) (err error) {
+	if !w.compact {
+		if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
+			return err
+		}
+	}
+	b := NewBuffer(data)
+	for b.index < len(b.buf) {
+		x, err := b.DecodeVarint()
+		if err != nil {
+			_, err := fmt.Fprintf(w, "/* %v */\n", err)
+			return err
+		}
+		wire, tag := x&7, x>>3
+		if wire == WireEndGroup {
+			w.unindent()
+			if _, err := w.Write(endBraceNewline); err != nil {
+				return err
+			}
+			continue
+		}
+		if _, err := fmt.Fprint(w, tag); err != nil {
+			return err
+		}
+		if wire != WireStartGroup {
+			if err := w.WriteByte(':'); err != nil {
+				return err
+			}
+		}
+		if !w.compact || wire == WireStartGroup {
+			if err := w.WriteByte(' '); err != nil {
+				return err
+			}
+		}
+		switch wire {
+		case WireBytes:
+			buf, e := b.DecodeRawBytes(false)
+			if e == nil {
+				_, err = fmt.Fprintf(w, "%q", buf)
+			} else {
+				_, err = fmt.Fprintf(w, "/* %v */", e)
+			}
+		case WireFixed32:
+			x, err = b.DecodeFixed32()
+			err = writeUnknownInt(w, x, err)
+		case WireFixed64:
+			x, err = b.DecodeFixed64()
+			err = writeUnknownInt(w, x, err)
+		case WireStartGroup:
+			err = w.WriteByte('{')
+			w.indent()
+		case WireVarint:
+			x, err = b.DecodeVarint()
+			err = writeUnknownInt(w, x, err)
+		default:
+			_, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)
+		}
+		if err != nil {
+			return err
+		}
+		if err = w.WriteByte('\n'); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func writeUnknownInt(w *textWriter, x uint64, err error) error {
+	if err == nil {
+		_, err = fmt.Fprint(w, x)
+	} else {
+		_, err = fmt.Fprintf(w, "/* %v */", err)
+	}
+	return err
+}
+
+type int32Slice []int32
+
+func (s int32Slice) Len() int           { return len(s) }
+func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
+func (s int32Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+// writeExtensions writes all the extensions in pv.
+// pv is assumed to be a pointer to a protocol message struct that is extendable.
+func writeExtensions(w *textWriter, pv reflect.Value) error {
+	emap := extensionMaps[pv.Type().Elem()]
+	ep := pv.Interface().(extendableProto)
+
+	// Order the extensions by ID.
+	// This isn't strictly necessary, but it will give us
+	// canonical output, which will also make testing easier.
+	m := ep.ExtensionMap()
+	ids := make([]int32, 0, len(m))
+	for id := range m {
+		ids = append(ids, id)
+	}
+	sort.Sort(int32Slice(ids))
+
+	for _, extNum := range ids {
+		ext := m[extNum]
+		var desc *ExtensionDesc
+		if emap != nil {
+			desc = emap[extNum]
+		}
+		if desc == nil {
+			// Unknown extension.
+			if err := writeUnknownStruct(w, ext.enc); err != nil {
+				return err
+			}
+			continue
+		}
+
+		pb, err := GetExtension(ep, desc)
+		if err != nil {
+			if _, err := fmt.Fprintln(os.Stderr, "proto: failed getting extension: ", err); err != nil {
+				return err
+			}
+			continue
+		}
+
+		// Repeated extensions will appear as a slice.
+		if !desc.repeated() {
+			if err := writeExtension(w, desc.Name, pb); err != nil {
+				return err
+			}
+		} else {
+			v := reflect.ValueOf(pb)
+			for i := 0; i < v.Len(); i++ {
+				if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
+					return err
+				}
+			}
+		}
+	}
+	return nil
+}
+
+func writeExtension(w *textWriter, name string, pb interface{}) error {
+	if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
+		return err
+	}
+	if !w.compact {
+		if err := w.WriteByte(' '); err != nil {
+			return err
+		}
+	}
+	if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil {
+		return err
+	}
+	if err := w.WriteByte('\n'); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (w *textWriter) writeIndent() {
+	if !w.complete {
+		return
+	}
+	remain := w.ind * 2
+	for remain > 0 {
+		n := remain
+		if n > len(spaces) {
+			n = len(spaces)
+		}
+		w.w.Write(spaces[:n])
+		remain -= n
+	}
+	w.complete = false
+}
+
+func marshalText(w io.Writer, pb Message, compact bool) error {
+	val := reflect.ValueOf(pb)
+	if pb == nil || val.IsNil() {
+		w.Write([]byte("<nil>"))
+		return nil
+	}
+	var bw *bufio.Writer
+	ww, ok := w.(writer)
+	if !ok {
+		bw = bufio.NewWriter(w)
+		ww = bw
+	}
+	aw := &textWriter{
+		w:        ww,
+		complete: true,
+		compact:  compact,
+	}
+
+	// Dereference the received pointer so we don't have outer < and >.
+	v := reflect.Indirect(val)
+	if err := writeStruct(aw, v); err != nil {
+		return err
+	}
+	if bw != nil {
+		return bw.Flush()
+	}
+	return nil
+}
+
+// MarshalText writes a given protocol buffer in text format.
+// The only errors returned are from w.
+func MarshalText(w io.Writer, pb Message) error { return marshalText(w, pb, false) }
+
+// MarshalTextString is the same as MarshalText, but returns the string directly.
+func MarshalTextString(pb Message) string {
+	var buf bytes.Buffer
+	marshalText(&buf, pb, false)
+	return buf.String()
+}
+
+// CompactText writes a given protocol buffer in compact text format (one line).
+func CompactText(w io.Writer, pb Message) error { return marshalText(w, pb, true) }
+
+// CompactTextString is the same as CompactText, but returns the string directly.
+func CompactTextString(pb Message) string {
+	var buf bytes.Buffer
+	marshalText(&buf, pb, true)
+	return buf.String()
+}

+ 55 - 0
third_party/code.google.com/p/gogoprotobuf/proto/text_gogo.go

@@ -0,0 +1,55 @@
+// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+// http://code.google.com/p/gogoprotobuf/gogoproto
+//
+// 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.
+//
+// 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.
+
+package proto
+
+import (
+	"fmt"
+	"reflect"
+)
+
+func writeEnum(w *textWriter, v reflect.Value, props *Properties) error {
+	m, ok := enumStringMaps[props.Enum]
+	if !ok {
+		if err := writeAny(w, v, props); err != nil {
+			return err
+		}
+	}
+	key := int32(0)
+	if v.Kind() == reflect.Ptr {
+		key = int32(v.Elem().Int())
+	} else {
+		key = int32(v.Int())
+	}
+	s, ok := m[key]
+	if !ok {
+		if err := writeAny(w, v, props); err != nil {
+			return err
+		}
+	}
+	_, err := fmt.Fprint(w, s)
+	return err
+}

+ 713 - 0
third_party/code.google.com/p/gogoprotobuf/proto/text_parser.go

@@ -0,0 +1,713 @@
+// Extensions for Protocol Buffers to create more go like structures.
+//
+// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+// http://code.google.com/p/gogoprotobuf/gogoproto
+//
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+package proto
+
+// Functions for parsing the Text protocol buffer format.
+// TODO: message sets.
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+	"unicode/utf8"
+)
+
+type ParseError struct {
+	Message string
+	Line    int // 1-based line number
+	Offset  int // 0-based byte offset from start of input
+}
+
+func (p *ParseError) Error() string {
+	if p.Line == 1 {
+		// show offset only for first line
+		return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message)
+	}
+	return fmt.Sprintf("line %d: %v", p.Line, p.Message)
+}
+
+type token struct {
+	value    string
+	err      *ParseError
+	line     int    // line number
+	offset   int    // byte number from start of input, not start of line
+	unquoted string // the unquoted version of value, if it was a quoted string
+}
+
+func (t *token) String() string {
+	if t.err == nil {
+		return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset)
+	}
+	return fmt.Sprintf("parse error: %v", t.err)
+}
+
+type textParser struct {
+	s            string // remaining input
+	done         bool   // whether the parsing is finished (success or error)
+	backed       bool   // whether back() was called
+	offset, line int
+	cur          token
+}
+
+func newTextParser(s string) *textParser {
+	p := new(textParser)
+	p.s = s
+	p.line = 1
+	p.cur.line = 1
+	return p
+}
+
+func (p *textParser) errorf(format string, a ...interface{}) *ParseError {
+	pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset}
+	p.cur.err = pe
+	p.done = true
+	return pe
+}
+
+// Numbers and identifiers are matched by [-+._A-Za-z0-9]
+func isIdentOrNumberChar(c byte) bool {
+	switch {
+	case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z':
+		return true
+	case '0' <= c && c <= '9':
+		return true
+	}
+	switch c {
+	case '-', '+', '.', '_':
+		return true
+	}
+	return false
+}
+
+func isWhitespace(c byte) bool {
+	switch c {
+	case ' ', '\t', '\n', '\r':
+		return true
+	}
+	return false
+}
+
+func (p *textParser) skipWhitespace() {
+	i := 0
+	for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {
+		if p.s[i] == '#' {
+			// comment; skip to end of line or input
+			for i < len(p.s) && p.s[i] != '\n' {
+				i++
+			}
+			if i == len(p.s) {
+				break
+			}
+		}
+		if p.s[i] == '\n' {
+			p.line++
+		}
+		i++
+	}
+	p.offset += i
+	p.s = p.s[i:len(p.s)]
+	if len(p.s) == 0 {
+		p.done = true
+	}
+}
+
+func (p *textParser) advance() {
+	// Skip whitespace
+	p.skipWhitespace()
+	if p.done {
+		return
+	}
+
+	// Start of non-whitespace
+	p.cur.err = nil
+	p.cur.offset, p.cur.line = p.offset, p.line
+	p.cur.unquoted = ""
+	switch p.s[0] {
+	case '<', '>', '{', '}', ':', '[', ']', ';', ',':
+		// Single symbol
+		p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
+	case '"', '\'':
+		// Quoted string
+		i := 1
+		for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' {
+			if p.s[i] == '\\' && i+1 < len(p.s) {
+				// skip escaped char
+				i++
+			}
+			i++
+		}
+		if i >= len(p.s) || p.s[i] != p.s[0] {
+			p.errorf("unmatched quote")
+			return
+		}
+		unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
+		if err != nil {
+			p.errorf("invalid quoted string %v", p.s[0:i+1])
+			return
+		}
+		p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
+		p.cur.unquoted = unq
+	default:
+		i := 0
+		for i < len(p.s) && isIdentOrNumberChar(p.s[i]) {
+			i++
+		}
+		if i == 0 {
+			p.errorf("unexpected byte %#x", p.s[0])
+			return
+		}
+		p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)]
+	}
+	p.offset += len(p.cur.value)
+}
+
+var (
+	errBadUTF8 = errors.New("proto: bad UTF-8")
+	errBadHex  = errors.New("proto: bad hexadecimal")
+)
+
+func unquoteC(s string, quote rune) (string, error) {
+	// This is based on C++'s tokenizer.cc.
+	// Despite its name, this is *not* parsing C syntax.
+	// For instance, "\0" is an invalid quoted string.
+
+	// Avoid allocation in trivial cases.
+	simple := true
+	for _, r := range s {
+		if r == '\\' || r == quote {
+			simple = false
+			break
+		}
+	}
+	if simple {
+		return s, nil
+	}
+
+	buf := make([]byte, 0, 3*len(s)/2)
+	for len(s) > 0 {
+		r, n := utf8.DecodeRuneInString(s)
+		if r == utf8.RuneError && n == 1 {
+			return "", errBadUTF8
+		}
+		s = s[n:]
+		if r != '\\' {
+			if r < utf8.RuneSelf {
+				buf = append(buf, byte(r))
+			} else {
+				buf = append(buf, string(r)...)
+			}
+			continue
+		}
+
+		ch, tail, err := unescape(s)
+		if err != nil {
+			return "", err
+		}
+		buf = append(buf, ch...)
+		s = tail
+	}
+	return string(buf), nil
+}
+
+func unescape(s string) (ch string, tail string, err error) {
+	r, n := utf8.DecodeRuneInString(s)
+	if r == utf8.RuneError && n == 1 {
+		return "", "", errBadUTF8
+	}
+	s = s[n:]
+	switch r {
+	case 'a':
+		return "\a", s, nil
+	case 'b':
+		return "\b", s, nil
+	case 'f':
+		return "\f", s, nil
+	case 'n':
+		return "\n", s, nil
+	case 'r':
+		return "\r", s, nil
+	case 't':
+		return "\t", s, nil
+	case 'v':
+		return "\v", s, nil
+	case '?':
+		return "?", s, nil // trigraph workaround
+	case '\'', '"', '\\':
+		return string(r), s, nil
+	case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X':
+		if len(s) < 2 {
+			return "", "", fmt.Errorf(`\%c requires 2 following digits`, r)
+		}
+		base := 8
+		ss := s[:2]
+		s = s[2:]
+		if r == 'x' || r == 'X' {
+			base = 16
+		} else {
+			ss = string(r) + ss
+		}
+		i, err := strconv.ParseUint(ss, base, 8)
+		if err != nil {
+			return "", "", err
+		}
+		return string([]byte{byte(i)}), s, nil
+	case 'u', 'U':
+		n := 4
+		if r == 'U' {
+			n = 8
+		}
+		if len(s) < n {
+			return "", "", fmt.Errorf(`\%c requires %d digits`, r, n)
+		}
+
+		bs := make([]byte, n/2)
+		for i := 0; i < n; i += 2 {
+			a, ok1 := unhex(s[i])
+			b, ok2 := unhex(s[i+1])
+			if !ok1 || !ok2 {
+				return "", "", errBadHex
+			}
+			bs[i/2] = a<<4 | b
+		}
+		s = s[n:]
+		return string(bs), s, nil
+	}
+	return "", "", fmt.Errorf(`unknown escape \%c`, r)
+}
+
+// Adapted from src/pkg/strconv/quote.go.
+func unhex(b byte) (v byte, ok bool) {
+	switch {
+	case '0' <= b && b <= '9':
+		return b - '0', true
+	case 'a' <= b && b <= 'f':
+		return b - 'a' + 10, true
+	case 'A' <= b && b <= 'F':
+		return b - 'A' + 10, true
+	}
+	return 0, false
+}
+
+// Back off the parser by one token. Can only be done between calls to next().
+// It makes the next advance() a no-op.
+func (p *textParser) back() { p.backed = true }
+
+// Advances the parser and returns the new current token.
+func (p *textParser) next() *token {
+	if p.backed || p.done {
+		p.backed = false
+		return &p.cur
+	}
+	p.advance()
+	if p.done {
+		p.cur.value = ""
+	} else if len(p.cur.value) > 0 && p.cur.value[0] == '"' {
+		// Look for multiple quoted strings separated by whitespace,
+		// and concatenate them.
+		cat := p.cur
+		for {
+			p.skipWhitespace()
+			if p.done || p.s[0] != '"' {
+				break
+			}
+			p.advance()
+			if p.cur.err != nil {
+				return &p.cur
+			}
+			cat.value += " " + p.cur.value
+			cat.unquoted += p.cur.unquoted
+		}
+		p.done = false // parser may have seen EOF, but we want to return cat
+		p.cur = cat
+	}
+	return &p.cur
+}
+
+// Return an error indicating which required field was not set.
+func (p *textParser) missingRequiredFieldError(sv reflect.Value) *ParseError {
+	st := sv.Type()
+	sprops := GetProperties(st)
+	for i := 0; i < st.NumField(); i++ {
+		if !isNil(sv.Field(i)) {
+			continue
+		}
+
+		props := sprops.Prop[i]
+		if props.Required {
+			return p.errorf("message %v missing required field %q", st, props.OrigName)
+		}
+	}
+	return p.errorf("message %v missing required field", st) // should not happen
+}
+
+// Returns the index in the struct for the named field, as well as the parsed tag properties.
+func structFieldByName(st reflect.Type, name string) (int, *Properties, bool) {
+	sprops := GetProperties(st)
+	i, ok := sprops.decoderOrigNames[name]
+	if ok {
+		return i, sprops.Prop[i], true
+	}
+	return -1, nil, false
+}
+
+// Consume a ':' from the input stream (if the next token is a colon),
+// returning an error if a colon is needed but not present.
+func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value != ":" {
+		// Colon is optional when the field is a group or message.
+		needColon := true
+		switch props.Wire {
+		case "group":
+			needColon = false
+		case "bytes":
+			// A "bytes" field is either a message, a string, or a repeated field;
+			// those three become *T, *string and []T respectively, so we can check for
+			// this field being a pointer to a non-string.
+			if typ.Kind() == reflect.Ptr {
+				// *T or *string
+				if typ.Elem().Kind() == reflect.String {
+					break
+				}
+			} else if typ.Kind() == reflect.Slice {
+				// []T or []*T
+				if typ.Elem().Kind() != reflect.Ptr {
+					break
+				}
+			}
+			needColon = false
+		}
+		if needColon {
+			return p.errorf("expected ':', found %q", tok.value)
+		}
+		p.back()
+	}
+	return nil
+}
+
+func (p *textParser) readStruct(sv reflect.Value, terminator string) *ParseError {
+	st := sv.Type()
+	reqCount := GetProperties(st).reqCount
+	// A struct is a sequence of "name: value", terminated by one of
+	// '>' or '}', or the end of the input.  A name may also be
+	// "[extension]".
+	for {
+		tok := p.next()
+		if tok.err != nil {
+			return tok.err
+		}
+		if tok.value == terminator {
+			break
+		}
+		if tok.value == "[" {
+			// Looks like an extension.
+			//
+			// TODO: Check whether we need to handle
+			// namespace rooted names (e.g. ".something.Foo").
+			tok = p.next()
+			if tok.err != nil {
+				return tok.err
+			}
+			var desc *ExtensionDesc
+			// This could be faster, but it's functional.
+			// TODO: Do something smarter than a linear scan.
+			for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
+				if d.Name == tok.value {
+					desc = d
+					break
+				}
+			}
+			if desc == nil {
+				return p.errorf("unrecognized extension %q", tok.value)
+			}
+			// Check the extension terminator.
+			tok = p.next()
+			if tok.err != nil {
+				return tok.err
+			}
+			if tok.value != "]" {
+				return p.errorf("unrecognized extension terminator %q", tok.value)
+			}
+
+			props := &Properties{}
+			props.Parse(desc.Tag)
+
+			typ := reflect.TypeOf(desc.ExtensionType)
+			if err := p.checkForColon(props, typ); err != nil {
+				return err
+			}
+
+			rep := desc.repeated()
+
+			// Read the extension structure, and set it in
+			// the value we're constructing.
+			var ext reflect.Value
+			if !rep {
+				ext = reflect.New(typ).Elem()
+			} else {
+				ext = reflect.New(typ.Elem()).Elem()
+			}
+			if err := p.readAny(ext, props); err != nil {
+				return err
+			}
+			ep := sv.Addr().Interface().(extendableProto)
+			if !rep {
+				SetExtension(ep, desc, ext.Interface())
+			} else {
+				old, err := GetExtension(ep, desc)
+				var sl reflect.Value
+				if err == nil {
+					sl = reflect.ValueOf(old) // existing slice
+				} else {
+					sl = reflect.MakeSlice(typ, 0, 1)
+				}
+				sl = reflect.Append(sl, ext)
+				SetExtension(ep, desc, sl.Interface())
+			}
+		} else {
+			// This is a normal, non-extension field.
+			fi, props, ok := structFieldByName(st, tok.value)
+			if !ok {
+				return p.errorf("unknown field name %q in %v", tok.value, st)
+			}
+
+			dst := sv.Field(fi)
+			isDstNil := isNil(dst)
+
+			// Check that it's not already set if it's not a repeated field.
+			if !props.Repeated && !isDstNil && dst.Kind() == reflect.Ptr {
+				return p.errorf("non-repeated field %q was repeated", tok.value)
+			}
+
+			if err := p.checkForColon(props, st.Field(fi).Type); err != nil {
+				return err
+			}
+
+			// Parse into the field.
+			if err := p.readAny(dst, props); err != nil {
+				return err
+			}
+
+			if props.Required {
+				reqCount--
+			}
+		}
+
+		// For backward compatibility, permit a semicolon or comma after a field.
+		tok = p.next()
+		if tok.err != nil {
+			return tok.err
+		}
+		if tok.value != ";" && tok.value != "," {
+			p.back()
+		}
+	}
+
+	if reqCount > 0 {
+		return p.missingRequiredFieldError(sv)
+	}
+	return nil
+}
+
+func (p *textParser) readAny(v reflect.Value, props *Properties) *ParseError {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value == "" {
+		return p.errorf("unexpected EOF")
+	}
+	if len(props.CustomType) > 0 {
+		if props.Repeated {
+			t := reflect.TypeOf(v.Interface())
+			if t.Kind() == reflect.Slice {
+				tc := reflect.TypeOf(new(Marshaler))
+				ok := t.Elem().Implements(tc.Elem())
+				if ok {
+					fv := v
+					flen := fv.Len()
+					if flen == fv.Cap() {
+						nav := reflect.MakeSlice(v.Type(), flen, 2*flen+1)
+						reflect.Copy(nav, fv)
+						fv.Set(nav)
+					}
+					fv.SetLen(flen + 1)
+
+					// Read one.
+					p.back()
+					return p.readAny(fv.Index(flen), props)
+				}
+			}
+		}
+		if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr {
+			custom := reflect.New(props.ctype.Elem()).Interface().(Unmarshaler)
+			err := custom.Unmarshal([]byte(tok.unquoted))
+			if err != nil {
+				return p.errorf("%v %v: %v", err, v.Type(), tok.value)
+			}
+			v.Set(reflect.ValueOf(custom))
+		} else {
+			custom := reflect.New(reflect.TypeOf(v.Interface())).Interface().(Unmarshaler)
+			err := custom.Unmarshal([]byte(tok.unquoted))
+			if err != nil {
+				return p.errorf("%v %v: %v", err, v.Type(), tok.value)
+			}
+			v.Set(reflect.Indirect(reflect.ValueOf(custom)))
+		}
+		return nil
+	}
+	switch fv := v; fv.Kind() {
+	case reflect.Slice:
+		at := v.Type()
+		if at.Elem().Kind() == reflect.Uint8 {
+			// Special case for []byte
+			if tok.value[0] != '"' && tok.value[0] != '\'' {
+				// Deliberately written out here, as the error after
+				// this switch statement would write "invalid []byte: ...",
+				// which is not as user-friendly.
+				return p.errorf("invalid string: %v", tok.value)
+			}
+			bytes := []byte(tok.unquoted)
+			fv.Set(reflect.ValueOf(bytes))
+			return nil
+		}
+		// Repeated field. May already exist.
+		flen := fv.Len()
+		if flen == fv.Cap() {
+			nav := reflect.MakeSlice(at, flen, 2*flen+1)
+			reflect.Copy(nav, fv)
+			fv.Set(nav)
+		}
+		fv.SetLen(flen + 1)
+
+		// Read one.
+		p.back()
+		return p.readAny(fv.Index(flen), props)
+	case reflect.Bool:
+		// Either "true", "false", 1 or 0.
+		switch tok.value {
+		case "true", "1":
+			fv.SetBool(true)
+			return nil
+		case "false", "0":
+			fv.SetBool(false)
+			return nil
+		}
+	case reflect.Float32, reflect.Float64:
+		v := tok.value
+		// Ignore 'f' for compatibility with output generated by C++, but don't
+		// remove 'f' when the value is "-inf" or "inf".
+		if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" {
+			v = v[:len(v)-1]
+		}
+		if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil {
+			fv.SetFloat(f)
+			return nil
+		}
+	case reflect.Int32:
+		if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {
+			fv.SetInt(x)
+			return nil
+		}
+		if len(props.Enum) == 0 {
+			break
+		}
+		m, ok := enumValueMaps[props.Enum]
+		if !ok {
+			break
+		}
+		x, ok := m[tok.value]
+		if !ok {
+			break
+		}
+		fv.SetInt(int64(x))
+		return nil
+	case reflect.Int64:
+		if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil {
+			fv.SetInt(x)
+			return nil
+		}
+	case reflect.Ptr:
+		// A basic field (indirected through pointer), or a repeated message/group
+		p.back()
+		fv.Set(reflect.New(fv.Type().Elem()))
+		return p.readAny(fv.Elem(), props)
+	case reflect.String:
+		if tok.value[0] == '"' || tok.value[0] == '\'' {
+			fv.SetString(tok.unquoted)
+			return nil
+		}
+	case reflect.Struct:
+		var terminator string
+		switch tok.value {
+		case "{":
+			terminator = "}"
+		case "<":
+			terminator = ">"
+		default:
+			return p.errorf("expected '{' or '<', found %q", tok.value)
+		}
+		return p.readStruct(fv, terminator)
+	case reflect.Uint32:
+		if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
+			fv.SetUint(uint64(x))
+			return nil
+		}
+	case reflect.Uint64:
+		if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {
+			fv.SetUint(x)
+			return nil
+		}
+	}
+	return p.errorf("invalid %v: %v", v.Type(), tok.value)
+}
+
+// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb
+// before starting to unmarshal, so any existing data in pb is always removed.
+func UnmarshalText(s string, pb Message) error {
+	pb.Reset()
+	v := reflect.ValueOf(pb)
+	if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil {
+		return pe
+	}
+	return nil
+}

+ 452 - 0
third_party/code.google.com/p/gogoprotobuf/proto/text_parser_test.go

@@ -0,0 +1,452 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+package proto_test
+
+import (
+	"math"
+	"reflect"
+	"testing"
+
+	. "./testdata"
+	. "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+)
+
+type UnmarshalTextTest struct {
+	in	string
+	err	string	// if "", no error expected
+	out	*MyMessage
+}
+
+func buildExtStructTest(text string) UnmarshalTextTest {
+	msg := &MyMessage{
+		Count: Int32(42),
+	}
+	SetExtension(msg, E_Ext_More, &Ext{
+		Data: String("Hello, world!"),
+	})
+	return UnmarshalTextTest{in: text, out: msg}
+}
+
+func buildExtDataTest(text string) UnmarshalTextTest {
+	msg := &MyMessage{
+		Count: Int32(42),
+	}
+	SetExtension(msg, E_Ext_Text, String("Hello, world!"))
+	SetExtension(msg, E_Ext_Number, Int32(1729))
+	return UnmarshalTextTest{in: text, out: msg}
+}
+
+func buildExtRepStringTest(text string) UnmarshalTextTest {
+	msg := &MyMessage{
+		Count: Int32(42),
+	}
+	if err := SetExtension(msg, E_Greeting, []string{"bula", "hola"}); err != nil {
+		panic(err)
+	}
+	return UnmarshalTextTest{in: text, out: msg}
+}
+
+var unMarshalTextTests = []UnmarshalTextTest{
+	// Basic
+	{
+		in:	" count:42\n  name:\"Dave\" ",
+		out: &MyMessage{
+			Count:	Int32(42),
+			Name:	String("Dave"),
+		},
+	},
+
+	// Empty quoted string
+	{
+		in:	`count:42 name:""`,
+		out: &MyMessage{
+			Count:	Int32(42),
+			Name:	String(""),
+		},
+	},
+
+	// Quoted string concatenation
+	{
+		in:	`count:42 name: "My name is "` + "\n" + `"elsewhere"`,
+		out: &MyMessage{
+			Count:	Int32(42),
+			Name:	String("My name is elsewhere"),
+		},
+	},
+
+	// Quoted string with escaped apostrophe
+	{
+		in:	`count:42 name: "HOLIDAY - New Year\'s Day"`,
+		out: &MyMessage{
+			Count:	Int32(42),
+			Name:	String("HOLIDAY - New Year's Day"),
+		},
+	},
+
+	// Quoted string with single quote
+	{
+		in:	`count:42 name: 'Roger "The Ramster" Ramjet'`,
+		out: &MyMessage{
+			Count:	Int32(42),
+			Name:	String(`Roger "The Ramster" Ramjet`),
+		},
+	},
+
+	// Quoted string with all the accepted special characters from the C++ test
+	{
+		in:	`count:42 name: ` + "\"\\\"A string with \\' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and  multiple   spaces\"",
+		out: &MyMessage{
+			Count:	Int32(42),
+			Name:	String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and  multiple   spaces"),
+		},
+	},
+
+	// Quoted string with quoted backslash
+	{
+		in:	`count:42 name: "\\'xyz"`,
+		out: &MyMessage{
+			Count:	Int32(42),
+			Name:	String(`\'xyz`),
+		},
+	},
+
+	// Quoted string with UTF-8 bytes.
+	{
+		in:	"count:42 name: '\303\277\302\201\xAB'",
+		out: &MyMessage{
+			Count:	Int32(42),
+			Name:	String("\303\277\302\201\xAB"),
+		},
+	},
+
+	// Bad quoted string
+	{
+		in:	`inner: < host: "\0" >` + "\n",
+		err:	`line 1.15: invalid quoted string "\0"`,
+	},
+
+	// Number too large for int64
+	{
+		in:	"count: 123456789012345678901",
+		err:	"line 1.7: invalid int32: 123456789012345678901",
+	},
+
+	// Number too large for int32
+	{
+		in:	"count: 1234567890123",
+		err:	"line 1.7: invalid int32: 1234567890123",
+	},
+
+	// Number in hexadecimal
+	{
+		in:	"count: 0x2beef",
+		out: &MyMessage{
+			Count: Int32(0x2beef),
+		},
+	},
+
+	// Number in octal
+	{
+		in:	"count: 024601",
+		out: &MyMessage{
+			Count: Int32(024601),
+		},
+	},
+
+	// Floating point number with "f" suffix
+	{
+		in:	"count: 4 others:< weight: 17.0f >",
+		out: &MyMessage{
+			Count:	Int32(4),
+			Others: []*OtherMessage{
+				{
+					Weight: Float32(17),
+				},
+			},
+		},
+	},
+
+	// Floating point positive infinity
+	{
+		in:	"count: 4 bigfloat: inf",
+		out: &MyMessage{
+			Count:		Int32(4),
+			Bigfloat:	Float64(math.Inf(1)),
+		},
+	},
+
+	// Floating point negative infinity
+	{
+		in:	"count: 4 bigfloat: -inf",
+		out: &MyMessage{
+			Count:		Int32(4),
+			Bigfloat:	Float64(math.Inf(-1)),
+		},
+	},
+
+	// Number too large for float32
+	{
+		in:	"others:< weight: 12345678901234567890123456789012345678901234567890 >",
+		err:	"line 1.17: invalid float32: 12345678901234567890123456789012345678901234567890",
+	},
+
+	// Number posing as a quoted string
+	{
+		in:	`inner: < host: 12 >` + "\n",
+		err:	`line 1.15: invalid string: 12`,
+	},
+
+	// Quoted string posing as int32
+	{
+		in:	`count: "12"`,
+		err:	`line 1.7: invalid int32: "12"`,
+	},
+
+	// Quoted string posing a float32
+	{
+		in:	`others:< weight: "17.4" >`,
+		err:	`line 1.17: invalid float32: "17.4"`,
+	},
+
+	// Enum
+	{
+		in:	`count:42 bikeshed: BLUE`,
+		out: &MyMessage{
+			Count:		Int32(42),
+			Bikeshed:	MyMessage_BLUE.Enum(),
+		},
+	},
+
+	// Repeated field
+	{
+		in:	`count:42 pet: "horsey" pet:"bunny"`,
+		out: &MyMessage{
+			Count:	Int32(42),
+			Pet:	[]string{"horsey", "bunny"},
+		},
+	},
+
+	// Repeated message with/without colon and <>/{}
+	{
+		in:	`count:42 others:{} others{} others:<> others:{}`,
+		out: &MyMessage{
+			Count:	Int32(42),
+			Others: []*OtherMessage{
+				{},
+				{},
+				{},
+				{},
+			},
+		},
+	},
+
+	// Missing colon for inner message
+	{
+		in:	`count:42 inner < host: "cauchy.syd" >`,
+		out: &MyMessage{
+			Count:	Int32(42),
+			Inner: &InnerMessage{
+				Host: String("cauchy.syd"),
+			},
+		},
+	},
+
+	// Missing colon for string field
+	{
+		in:	`name "Dave"`,
+		err:	`line 1.5: expected ':', found "\"Dave\""`,
+	},
+
+	// Missing colon for int32 field
+	{
+		in:	`count 42`,
+		err:	`line 1.6: expected ':', found "42"`,
+	},
+
+	// Missing required field
+	{
+		in:	``,
+		err:	`line 1.0: message testdata.MyMessage missing required field "count"`,
+	},
+
+	// Repeated non-repeated field
+	{
+		in:	`name: "Rob" name: "Russ"`,
+		err:	`line 1.12: non-repeated field "name" was repeated`,
+	},
+
+	// Group
+	{
+		in:	`count: 17 SomeGroup { group_field: 12 }`,
+		out: &MyMessage{
+			Count:	Int32(17),
+			Somegroup: &MyMessage_SomeGroup{
+				GroupField: Int32(12),
+			},
+		},
+	},
+
+	// Semicolon between fields
+	{
+		in:	`count:3;name:"Calvin"`,
+		out: &MyMessage{
+			Count:	Int32(3),
+			Name:	String("Calvin"),
+		},
+	},
+	// Comma between fields
+	{
+		in:	`count:4,name:"Ezekiel"`,
+		out: &MyMessage{
+			Count:	Int32(4),
+			Name:	String("Ezekiel"),
+		},
+	},
+
+	// Extension
+	buildExtStructTest(`count: 42 [testdata.Ext.more]:<data:"Hello, world!" >`),
+	buildExtStructTest(`count: 42 [testdata.Ext.more] {data:"Hello, world!"}`),
+	buildExtDataTest(`count: 42 [testdata.Ext.text]:"Hello, world!" [testdata.Ext.number]:1729`),
+	buildExtRepStringTest(`count: 42 [testdata.greeting]:"bula" [testdata.greeting]:"hola"`),
+
+	// Big all-in-one
+	{
+		in: "count:42  # Meaning\n" +
+			`name:"Dave" ` +
+			`quote:"\"I didn't want to go.\"" ` +
+			`pet:"bunny" ` +
+			`pet:"kitty" ` +
+			`pet:"horsey" ` +
+			`inner:<` +
+			`  host:"footrest.syd" ` +
+			`  port:7001 ` +
+			`  connected:true ` +
+			`> ` +
+			`others:<` +
+			`  key:3735928559 ` +
+			`  value:"\x01A\a\f" ` +
+			`> ` +
+			`others:<` +
+			"  weight:58.9  # Atomic weight of Co\n" +
+			`  inner:<` +
+			`    host:"lesha.mtv" ` +
+			`    port:8002 ` +
+			`  >` +
+			`>`,
+		out: &MyMessage{
+			Count:	Int32(42),
+			Name:	String("Dave"),
+			Quote:	String(`"I didn't want to go."`),
+			Pet:	[]string{"bunny", "kitty", "horsey"},
+			Inner: &InnerMessage{
+				Host:		String("footrest.syd"),
+				Port:		Int32(7001),
+				Connected:	Bool(true),
+			},
+			Others: []*OtherMessage{
+				{
+					Key:	Int64(3735928559),
+					Value:	[]byte{0x1, 'A', '\a', '\f'},
+				},
+				{
+					Weight:	Float32(58.9),
+					Inner: &InnerMessage{
+						Host:	String("lesha.mtv"),
+						Port:	Int32(8002),
+					},
+				},
+			},
+		},
+	},
+}
+
+func TestUnmarshalText(t *testing.T) {
+	for i, test := range unMarshalTextTests {
+		pb := new(MyMessage)
+		err := UnmarshalText(test.in, pb)
+		if test.err == "" {
+			// We don't expect failure.
+			if err != nil {
+				t.Errorf("Test %d: Unexpected error: %v", i, err)
+			} else if !reflect.DeepEqual(pb, test.out) {
+				t.Errorf("Test %d: Incorrect populated \nHave: %v\nWant: %v",
+					i, pb, test.out)
+			}
+		} else {
+			// We do expect failure.
+			if err == nil {
+				t.Errorf("Test %d: Didn't get expected error: %v", i, test.err)
+			} else if err.Error() != test.err {
+				t.Errorf("Test %d: Incorrect error.\nHave: %v\nWant: %v",
+					i, err.Error(), test.err)
+			}
+		}
+	}
+}
+
+// Regression test; this caused a panic.
+func TestRepeatedEnum(t *testing.T) {
+	pb := new(RepeatedEnum)
+	if err := UnmarshalText("color: RED", pb); err != nil {
+		t.Fatal(err)
+	}
+	exp := &RepeatedEnum{
+		Color: []RepeatedEnum_Color{RepeatedEnum_RED},
+	}
+	if !Equal(pb, exp) {
+		t.Errorf("Incorrect populated \nHave: %v\nWant: %v", pb, exp)
+	}
+}
+
+var benchInput string
+
+func init() {
+	benchInput = "count: 4\n"
+	for i := 0; i < 1000; i++ {
+		benchInput += "pet: \"fido\"\n"
+	}
+
+	// Check it is valid input.
+	pb := new(MyMessage)
+	err := UnmarshalText(benchInput, pb)
+	if err != nil {
+		panic("Bad benchmark input: " + err.Error())
+	}
+}
+
+func BenchmarkUnmarshalText(b *testing.B) {
+	pb := new(MyMessage)
+	for i := 0; i < b.N; i++ {
+		UnmarshalText(benchInput, pb)
+	}
+	b.SetBytes(int64(len(benchInput)))
+}

+ 357 - 0
third_party/code.google.com/p/gogoprotobuf/proto/text_test.go

@@ -0,0 +1,357 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  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.
+
+package proto_test
+
+import (
+	"bytes"
+	"errors"
+	"io/ioutil"
+	"math"
+	"strings"
+	"testing"
+
+	"github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+
+	pb "./testdata"
+)
+
+func newTestMessage() *pb.MyMessage {
+	msg := &pb.MyMessage{
+		Count:	proto.Int32(42),
+		Name:	proto.String("Dave"),
+		Quote:	proto.String(`"I didn't want to go."`),
+		Pet:	[]string{"bunny", "kitty", "horsey"},
+		Inner: &pb.InnerMessage{
+			Host:		proto.String("footrest.syd"),
+			Port:		proto.Int32(7001),
+			Connected:	proto.Bool(true),
+		},
+		Others: []*pb.OtherMessage{
+			{
+				Key:	proto.Int64(0xdeadbeef),
+				Value:	[]byte{1, 65, 7, 12},
+			},
+			{
+				Weight:	proto.Float32(6.022),
+				Inner: &pb.InnerMessage{
+					Host:	proto.String("lesha.mtv"),
+					Port:	proto.Int32(8002),
+				},
+			},
+		},
+		Bikeshed:	pb.MyMessage_BLUE.Enum(),
+		Somegroup: &pb.MyMessage_SomeGroup{
+			GroupField: proto.Int32(8),
+		},
+		// One normally wouldn't do this.
+		// This is an undeclared tag 13, as a varint (wire type 0) with value 4.
+		XXX_unrecognized:	[]byte{13<<3 | 0, 4},
+	}
+	ext := &pb.Ext{
+		Data: proto.String("Big gobs for big rats"),
+	}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, ext); err != nil {
+		panic(err)
+	}
+	greetings := []string{"adg", "easy", "cow"}
+	if err := proto.SetExtension(msg, pb.E_Greeting, greetings); err != nil {
+		panic(err)
+	}
+
+	// Add an unknown extension. We marshal a pb.Ext, and fake the ID.
+	b, err := proto.Marshal(&pb.Ext{Data: proto.String("3G skiing")})
+	if err != nil {
+		panic(err)
+	}
+	b = append(proto.EncodeVarint(201<<3|proto.WireBytes), b...)
+	proto.SetRawExtension(msg, 201, b)
+
+	// Extensions can be plain fields, too, so let's test that.
+	b = append(proto.EncodeVarint(202<<3|proto.WireVarint), 19)
+	proto.SetRawExtension(msg, 202, b)
+
+	return msg
+}
+
+const text = `count: 42
+name: "Dave"
+quote: "\"I didn't want to go.\""
+pet: "bunny"
+pet: "kitty"
+pet: "horsey"
+inner: <
+  host: "footrest.syd"
+  port: 7001
+  connected: true
+>
+others: <
+  key: 3735928559
+  value: "\001A\007\014"
+>
+others: <
+  weight: 6.022
+  inner: <
+    host: "lesha.mtv"
+    port: 8002
+  >
+>
+bikeshed: BLUE
+SomeGroup {
+  group_field: 8
+}
+/* 2 unknown bytes */
+13: 4
+[testdata.Ext.more]: <
+  data: "Big gobs for big rats"
+>
+[testdata.greeting]: "adg"
+[testdata.greeting]: "easy"
+[testdata.greeting]: "cow"
+/* 13 unknown bytes */
+201: "\t3G skiing"
+/* 3 unknown bytes */
+202: 19
+`
+
+func TestMarshalText(t *testing.T) {
+	buf := new(bytes.Buffer)
+	if err := proto.MarshalText(buf, newTestMessage()); err != nil {
+		t.Fatalf("proto.MarshalText: %v", err)
+	}
+	s := buf.String()
+	if s != text {
+		t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", s, text)
+	}
+}
+
+func TestMarshalTextNil(t *testing.T) {
+	want := "<nil>"
+	tests := []proto.Message{nil, (*pb.MyMessage)(nil)}
+	for i, test := range tests {
+		buf := new(bytes.Buffer)
+		if err := proto.MarshalText(buf, test); err != nil {
+			t.Fatal(err)
+		}
+		if got := buf.String(); got != want {
+			t.Errorf("%d: got %q want %q", i, got, want)
+		}
+	}
+}
+
+func TestMarshalTextUnknownEnum(t *testing.T) {
+	// The Color enum only specifies values 0-2.
+	m := &pb.MyMessage{Bikeshed: pb.MyMessage_Color(3).Enum()}
+	got := m.String()
+	const want = `bikeshed:3 `
+	if got != want {
+		t.Errorf("\n got %q\nwant %q", got, want)
+	}
+}
+
+func BenchmarkMarshalTextBuffered(b *testing.B) {
+	buf := new(bytes.Buffer)
+	m := newTestMessage()
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		proto.MarshalText(buf, m)
+	}
+}
+
+func BenchmarkMarshalTextUnbuffered(b *testing.B) {
+	w := ioutil.Discard
+	m := newTestMessage()
+	for i := 0; i < b.N; i++ {
+		proto.MarshalText(w, m)
+	}
+}
+
+func compact(src string) string {
+	// s/[ \n]+/ /g; s/ $//;
+	dst := make([]byte, len(src))
+	space, comment := false, false
+	j := 0
+	for i := 0; i < len(src); i++ {
+		if strings.HasPrefix(src[i:], "/*") {
+			comment = true
+			i++
+			continue
+		}
+		if comment && strings.HasPrefix(src[i:], "*/") {
+			comment = false
+			i++
+			continue
+		}
+		if comment {
+			continue
+		}
+		c := src[i]
+		if c == ' ' || c == '\n' {
+			space = true
+			continue
+		}
+		if j > 0 && (dst[j-1] == ':' || dst[j-1] == '<' || dst[j-1] == '{') {
+			space = false
+		}
+		if c == '{' {
+			space = false
+		}
+		if space {
+			dst[j] = ' '
+			j++
+			space = false
+		}
+		dst[j] = c
+		j++
+	}
+	if space {
+		dst[j] = ' '
+		j++
+	}
+	return string(dst[0:j])
+}
+
+var compactText = compact(text)
+
+func TestCompactText(t *testing.T) {
+	s := proto.CompactTextString(newTestMessage())
+	if s != compactText {
+		t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v\n===\n", s, compactText)
+	}
+}
+
+func TestStringEscaping(t *testing.T) {
+	testCases := []struct {
+		in	*pb.Strings
+		out	string
+	}{
+		{
+			// Test data from C++ test (TextFormatTest.StringEscape).
+			// Single divergence: we don't escape apostrophes.
+			&pb.Strings{StringField: proto.String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and  multiple   spaces")},
+			"string_field: \"\\\"A string with ' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and  multiple   spaces\"\n",
+		},
+		{
+			// Test data from the same C++ test.
+			&pb.Strings{StringField: proto.String("\350\260\267\346\255\214")},
+			"string_field: \"\\350\\260\\267\\346\\255\\214\"\n",
+		},
+		{
+			// Some UTF-8.
+			&pb.Strings{StringField: proto.String("\x00\x01\xff\x81")},
+			`string_field: "\000\001\377\201"` + "\n",
+		},
+	}
+
+	for i, tc := range testCases {
+		var buf bytes.Buffer
+		if err := proto.MarshalText(&buf, tc.in); err != nil {
+			t.Errorf("proto.MarsalText: %v", err)
+			continue
+		}
+		s := buf.String()
+		if s != tc.out {
+			t.Errorf("#%d: Got:\n%s\nExpected:\n%s\n", i, s, tc.out)
+			continue
+		}
+
+		// Check round-trip.
+		pb := new(pb.Strings)
+		if err := proto.UnmarshalText(s, pb); err != nil {
+			t.Errorf("#%d: UnmarshalText: %v", i, err)
+			continue
+		}
+		if !proto.Equal(pb, tc.in) {
+			t.Errorf("#%d: Round-trip failed:\nstart: %v\n  end: %v", i, tc.in, pb)
+		}
+	}
+}
+
+// A limitedWriter accepts some output before it fails.
+// This is a proxy for something like a nearly-full or imminently-failing disk,
+// or a network connection that is about to die.
+type limitedWriter struct {
+	b	bytes.Buffer
+	limit	int
+}
+
+var outOfSpace = errors.New("proto: insufficient space")
+
+func (w *limitedWriter) Write(p []byte) (n int, err error) {
+	var avail = w.limit - w.b.Len()
+	if avail <= 0 {
+		return 0, outOfSpace
+	}
+	if len(p) <= avail {
+		return w.b.Write(p)
+	}
+	n, _ = w.b.Write(p[:avail])
+	return n, outOfSpace
+}
+
+func TestMarshalTextFailing(t *testing.T) {
+	// Try lots of different sizes to exercise more error code-paths.
+	for lim := 0; lim < len(text); lim++ {
+		buf := new(limitedWriter)
+		buf.limit = lim
+		err := proto.MarshalText(buf, newTestMessage())
+		// We expect a certain error, but also some partial results in the buffer.
+		if err != outOfSpace {
+			t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", err, outOfSpace)
+		}
+		s := buf.b.String()
+		x := text[:buf.limit]
+		if s != x {
+			t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", s, x)
+		}
+	}
+}
+
+func TestFloats(t *testing.T) {
+	tests := []struct {
+		f	float64
+		want	string
+	}{
+		{0, "0"},
+		{4.7, "4.7"},
+		{math.Inf(1), "inf"},
+		{math.Inf(-1), "-inf"},
+		{math.NaN(), "nan"},
+	}
+	for _, test := range tests {
+		msg := &pb.FloatingPoint{F: &test.f}
+		got := strings.TrimSpace(msg.String())
+		want := `f:` + test.want
+		if got != want {
+			t.Errorf("f=%f: got %q, want %q", test.f, got, want)
+		}
+	}
+}

+ 1 - 0
third_party/github.com/coreos/raft/.gitignore

@@ -22,3 +22,4 @@ _testmain.go
 *.exe
 
 coverage.html
+coverprofile.out

+ 7 - 4
third_party/github.com/coreos/raft/Makefile

@@ -1,8 +1,11 @@
-all: test
+COVERPROFILE=cover.out
 
-coverage:
-	gocov test github.com/coreos/go-raft | gocov-html > coverage.html
-	open coverage.html
+default: test
+
+cover:
+	go test -coverprofile=$(COVERPROFILE) .
+	go tool cover -html=$(COVERPROFILE)
+	rm $(COVERPROFILE)
 
 dependencies:
 	go get -d .

+ 18 - 34
third_party/github.com/coreos/raft/append_entries_request.go

@@ -1,10 +1,11 @@
 package raft
 
 import (
-	"github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
-	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 	"io"
 	"io/ioutil"
+
+	"github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 )
 
 // The request sent to a server to append entries to the log.
@@ -14,43 +15,38 @@ type AppendEntriesRequest struct {
 	PrevLogTerm	uint64
 	CommitIndex	uint64
 	LeaderName	string
-	Entries		[]*LogEntry
+	Entries		[]*protobuf.LogEntry
 }
 
 // Creates a new AppendEntries request.
-func newAppendEntriesRequest(term uint64, prevLogIndex uint64, prevLogTerm uint64, commitIndex uint64, leaderName string, entries []*LogEntry) *AppendEntriesRequest {
+func newAppendEntriesRequest(term uint64, prevLogIndex uint64, prevLogTerm uint64,
+	commitIndex uint64, leaderName string, entries []*LogEntry) *AppendEntriesRequest {
+	pbEntries := make([]*protobuf.LogEntry, len(entries))
+
+	for i := range entries {
+		pbEntries[i] = entries[i].pb
+	}
+
 	return &AppendEntriesRequest{
 		Term:		term,
 		PrevLogIndex:	prevLogIndex,
 		PrevLogTerm:	prevLogTerm,
 		CommitIndex:	commitIndex,
 		LeaderName:	leaderName,
-		Entries:	entries,
+		Entries:	pbEntries,
 	}
 }
 
 // Encodes the AppendEntriesRequest to a buffer. Returns the number of bytes
 // written and any error that may have occurred.
 func (req *AppendEntriesRequest) Encode(w io.Writer) (int, error) {
-
-	protoEntries := make([]*protobuf.ProtoAppendEntriesRequest_ProtoLogEntry, len(req.Entries))
-
-	for i, entry := range req.Entries {
-		protoEntries[i] = &protobuf.ProtoAppendEntriesRequest_ProtoLogEntry{
-			Index:		proto.Uint64(entry.Index),
-			Term:		proto.Uint64(entry.Term),
-			CommandName:	proto.String(entry.CommandName),
-			Command:	entry.Command,
-		}
-	}
-
-	pb := &protobuf.ProtoAppendEntriesRequest{
+	pb := &protobuf.AppendEntriesRequest{
 		Term:		proto.Uint64(req.Term),
 		PrevLogIndex:	proto.Uint64(req.PrevLogIndex),
 		PrevLogTerm:	proto.Uint64(req.PrevLogTerm),
 		CommitIndex:	proto.Uint64(req.CommitIndex),
 		LeaderName:	proto.String(req.LeaderName),
-		Entries:	protoEntries,
+		Entries:	req.Entries,
 	}
 
 	p, err := proto.Marshal(pb)
@@ -70,9 +66,7 @@ func (req *AppendEntriesRequest) Decode(r io.Reader) (int, error) {
 		return -1, err
 	}
 
-	totalBytes := len(data)
-
-	pb := &protobuf.ProtoAppendEntriesRequest{}
+	pb := new(protobuf.AppendEntriesRequest)
 	if err := proto.Unmarshal(data, pb); err != nil {
 		return -1, err
 	}
@@ -82,17 +76,7 @@ func (req *AppendEntriesRequest) Decode(r io.Reader) (int, error) {
 	req.PrevLogTerm = pb.GetPrevLogTerm()
 	req.CommitIndex = pb.GetCommitIndex()
 	req.LeaderName = pb.GetLeaderName()
+	req.Entries = pb.GetEntries()
 
-	req.Entries = make([]*LogEntry, len(pb.Entries))
-
-	for i, entry := range pb.Entries {
-		req.Entries[i] = &LogEntry{
-			Index:		entry.GetIndex(),
-			Term:		entry.GetTerm(),
-			CommandName:	entry.GetCommandName(),
-			Command:	entry.Command,
-		}
-	}
-
-	return totalBytes, nil
+	return len(data), nil
 }

+ 35 - 32
third_party/github.com/coreos/raft/append_entries_response.go

@@ -1,70 +1,73 @@
 package raft
 
 import (
-	"github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
-	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 	"io"
 	"io/ioutil"
+
+	"github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 )
 
 // The response returned from a server appending entries to the log.
 type AppendEntriesResponse struct {
-	Term	uint64
-	// the current index of the server
-	Index		uint64
-	Success		bool
-	CommitIndex	uint64
-	peer		string
-	append		bool
+	pb	*protobuf.AppendEntriesResponse
+	peer	string
+	append	bool
 }
 
 // Creates a new AppendEntries response.
 func newAppendEntriesResponse(term uint64, success bool, index uint64, commitIndex uint64) *AppendEntriesResponse {
+	pb := &protobuf.AppendEntriesResponse{
+		Term:		proto.Uint64(term),
+		Index:		proto.Uint64(index),
+		Success:	proto.Bool(success),
+		CommitIndex:	proto.Uint64(commitIndex),
+	}
+
 	return &AppendEntriesResponse{
-		Term:		term,
-		Success:	success,
-		Index:		index,
-		CommitIndex:	commitIndex,
+		pb: pb,
 	}
 }
 
+func (aer *AppendEntriesResponse) Index() uint64 {
+	return aer.pb.GetIndex()
+}
+
+func (aer *AppendEntriesResponse) CommitIndex() uint64 {
+	return aer.pb.GetCommitIndex()
+}
+
+func (aer *AppendEntriesResponse) Term() uint64 {
+	return aer.pb.GetTerm()
+}
+
+func (aer *AppendEntriesResponse) Success() bool {
+	return aer.pb.GetSuccess()
+}
+
 // Encodes the AppendEntriesResponse to a buffer. Returns the number of bytes
 // written and any error that may have occurred.
 func (resp *AppendEntriesResponse) Encode(w io.Writer) (int, error) {
-	pb := &protobuf.ProtoAppendEntriesResponse{
-		Term:		proto.Uint64(resp.Term),
-		Index:		proto.Uint64(resp.Index),
-		CommitIndex:	proto.Uint64(resp.CommitIndex),
-		Success:	proto.Bool(resp.Success),
-	}
-	p, err := proto.Marshal(pb)
+	b, err := proto.Marshal(resp.pb)
 	if err != nil {
 		return -1, err
 	}
 
-	return w.Write(p)
+	return w.Write(b)
 }
 
 // Decodes the AppendEntriesResponse from a buffer. Returns the number of bytes read and
 // any error that occurs.
 func (resp *AppendEntriesResponse) Decode(r io.Reader) (int, error) {
 	data, err := ioutil.ReadAll(r)
-
 	if err != nil {
 		return -1, err
 	}
 
-	totalBytes := len(data)
-
-	pb := &protobuf.ProtoAppendEntriesResponse{}
-	if err := proto.Unmarshal(data, pb); err != nil {
+	resp.pb = new(protobuf.AppendEntriesResponse)
+	if err := proto.Unmarshal(data, resp.pb); err != nil {
 		return -1, err
 	}
 
-	resp.Term = pb.GetTerm()
-	resp.Index = pb.GetIndex()
-	resp.CommitIndex = pb.GetCommitIndex()
-	resp.Success = pb.GetSuccess()
-
-	return totalBytes, nil
+	return len(data), nil
 }

+ 0 - 1
third_party/github.com/coreos/raft/command.go

@@ -69,7 +69,6 @@ func RegisterCommand(command Command) {
 		panic(fmt.Sprintf("raft: Cannot register nil"))
 	} else if commandTypes[command.CommandName()] != nil {
 		panic(fmt.Sprintf("raft: Duplicate registration: %s", command.CommandName()))
-		return
 	}
 	commandTypes[command.CommandName()] = command
 }

+ 1 - 1
third_party/github.com/coreos/raft/event.go

@@ -7,7 +7,7 @@ const (
 	AddPeerEventType      = "addPeer"
 	RemovePeerEventType   = "removePeer"
 
-	HeartbeatTimeoutEventType         = "heartbeatTimeout"
+	HeartbeatIntervalEventType        = "heartbeatInterval"
 	ElectionTimeoutThresholdEventType = "electionTimeoutThreshold"
 
 	HeartbeatEventType = "heartbeat"

+ 1 - 1
third_party/github.com/coreos/raft/event_dispatcher_test.go

@@ -3,7 +3,7 @@ package raft
 import (
 	"testing"
 
-	"github.com/coreos/etcd/third_party/github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/assert"
 )
 
 // Ensure that we can listen and dispatch events.

+ 4 - 4
third_party/github.com/coreos/raft/http_transporter_test.go

@@ -43,7 +43,7 @@ func runTestHttpServers(t *testing.T, servers *[]Server, transporter *HTTPTransp
 
 		// Create raft server.
 		server := newTestServer(fmt.Sprintf("localhost:%d", port), transporter)
-		server.SetHeartbeatTimeout(testHeartbeatTimeout)
+		server.SetHeartbeatInterval(testHeartbeatInterval)
 		server.SetElectionTimeout(testElectionTimeout)
 		server.Start()
 
@@ -74,7 +74,7 @@ func runTestHttpServers(t *testing.T, servers *[]Server, transporter *HTTPTransp
 	}
 
 	// Wait for configuration to propagate.
-	time.Sleep(testHeartbeatTimeout * 2)
+	time.Sleep(testHeartbeatInterval * 2)
 
 	// Execute all the callbacks at the same time.
 	for _i, _f := range callbacks {
@@ -101,7 +101,7 @@ func BenchmarkSpeed(b *testing.B) {
 
 		// Create raft server.
 		server := newTestServer(fmt.Sprintf("localhost:%d", port), transporter)
-		server.SetHeartbeatTimeout(testHeartbeatTimeout)
+		server.SetHeartbeatInterval(testHeartbeatInterval)
 		server.SetElectionTimeout(testElectionTimeout)
 		server.Start()
 
@@ -131,7 +131,7 @@ func BenchmarkSpeed(b *testing.B) {
 	c := make(chan bool)
 
 	// Wait for configuration to propagate.
-	time.Sleep(testHeartbeatTimeout * 2)
+	time.Sleep(testHeartbeatInterval * 2)
 
 	b.ResetTimer()
 	for n := 0; n < b.N; n++ {

+ 40 - 38
third_party/github.com/coreos/raft/log.go

@@ -2,13 +2,13 @@ package raft
 
 import (
 	"bufio"
-	"github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
 	"errors"
 	"fmt"
-	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 	"io"
 	"os"
 	"sync"
+
+	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 )
 
 //------------------------------------------------------------------------------
@@ -27,8 +27,6 @@ type Log struct {
 	mutex		sync.RWMutex
 	startIndex	uint64	// the index before the first entry in the Log entries
 	startTerm	uint64
-	pBuffer		*proto.Buffer
-	pLogEntry	*protobuf.ProtoLogEntry
 }
 
 // The results of the applying a log entry.
@@ -46,9 +44,7 @@ type logResult struct {
 // Creates a new log.
 func newLog() *Log {
 	return &Log{
-		entries:	make([]*LogEntry, 0),
-		pBuffer:	proto.NewBuffer(nil),
-		pLogEntry:	&protobuf.ProtoLogEntry{},
+		entries: make([]*LogEntry, 0),
 	}
 }
 
@@ -81,7 +77,7 @@ func (l *Log) internalCurrentIndex() uint64 {
 	if len(l.entries) == 0 {
 		return l.startIndex
 	}
-	return l.entries[len(l.entries)-1].Index
+	return l.entries[len(l.entries)-1].Index()
 }
 
 // The next index in the log.
@@ -102,7 +98,7 @@ func (l *Log) lastCommandName() string {
 	defer l.mutex.RUnlock()
 	if len(l.entries) > 0 {
 		if entry := l.entries[len(l.entries)-1]; entry != nil {
-			return entry.CommandName
+			return entry.CommandName()
 		}
 	}
 	return ""
@@ -120,7 +116,7 @@ func (l *Log) currentTerm() uint64 {
 	if len(l.entries) == 0 {
 		return l.startTerm
 	}
-	return l.entries[len(l.entries)-1].Term
+	return l.entries[len(l.entries)-1].Term()
 }
 
 //------------------------------------------------------------------------------
@@ -175,17 +171,17 @@ func (l *Log) open(path string) error {
 			}
 			break
 		}
-		if entry.Index > l.startIndex {
+		if entry.Index() > l.startIndex {
 			// Append entry.
 			l.entries = append(l.entries, entry)
-			if entry.Index <= l.commitIndex {
-				command, err := newCommand(entry.CommandName, entry.Command)
+			if entry.Index() <= l.commitIndex {
+				command, err := newCommand(entry.CommandName(), entry.Command())
 				if err != nil {
 					continue
 				}
 				l.ApplyFunc(command)
 			}
-			debugln("open.log.append log index ", entry.Index)
+			debugln("open.log.append log index ", entry.Index())
 		}
 
 		readBytes += int64(n)
@@ -235,15 +231,15 @@ func (l *Log) getEntry(index uint64) *LogEntry {
 // Checks if the log contains a given index/term combination.
 func (l *Log) containsEntry(index uint64, term uint64) bool {
 	entry := l.getEntry(index)
-	return (entry != nil && entry.Term == term)
+	return (entry != nil && entry.Term() == term)
 }
 
 // Retrieves a list of entries after a given index as well as the term of the
 // index provided. A nil list of entries is returned if the index no longer
 // exists because a snapshot was made.
 func (l *Log) getEntriesAfter(index uint64, maxLogEntriesPerRequest uint64) ([]*LogEntry, uint64) {
-	l.mutex.Lock()
-	defer l.mutex.Unlock()
+	l.mutex.RLock()
+	defer l.mutex.RUnlock()
 
 	// Return nil if index is before the start of the log.
 	if index < l.startIndex {
@@ -271,9 +267,9 @@ func (l *Log) getEntriesAfter(index uint64, maxLogEntriesPerRequest uint64) ([]*
 
 	if uint64(length) < maxLogEntriesPerRequest {
 		// Determine the term at the given entry and return a subslice.
-		return entries, l.entries[index-1-l.startIndex].Term
+		return entries, l.entries[index-1-l.startIndex].Term()
 	} else {
-		return entries[:maxLogEntriesPerRequest], l.entries[index-1-l.startIndex].Term
+		return entries[:maxLogEntriesPerRequest], l.entries[index-1-l.startIndex].Term()
 	}
 }
 
@@ -298,7 +294,7 @@ func (l *Log) commitInfo() (index uint64, term uint64) {
 	// Return the last index & term from the last committed entry.
 	debugln("commitInfo.get.[", l.commitIndex, "/", l.startIndex, "]")
 	entry := l.entries[l.commitIndex-1-l.startIndex]
-	return entry.Index, entry.Term
+	return entry.Index(), entry.Term()
 }
 
 // Retrieves the last index and term that has been appended to the log.
@@ -313,7 +309,7 @@ func (l *Log) lastInfo() (index uint64, term uint64) {
 
 	// Return the last index & term
 	entry := l.entries[len(l.entries)-1]
-	return entry.Index, entry.Term
+	return entry.Index(), entry.Term()
 }
 
 // Updates the commit index
@@ -363,16 +359,17 @@ func (l *Log) setCommitIndex(index uint64) error {
 		entry := l.entries[entryIndex]
 
 		// Update commit index.
-		l.commitIndex = entry.Index
+		l.commitIndex = entry.Index()
 
 		// Decode the command.
-		command, err := newCommand(entry.CommandName, entry.Command)
+		command, err := newCommand(entry.CommandName(), entry.Command())
 		if err != nil {
 			return err
 		}
 
 		// Apply the changes to the state machine and store the error code.
 		returnValue, err := l.ApplyFunc(command)
+
 		debugf("setCommitIndex.set.result index: %v, entries index: %v", i, entryIndex)
 		if entry.event != nil {
 			entry.event.returnValue = returnValue
@@ -430,9 +427,9 @@ func (l *Log) truncate(index uint64, term uint64) error {
 	} else {
 		// Do not truncate if the entry at index does not have the matching term.
 		entry := l.entries[index-l.startIndex-1]
-		if len(l.entries) > 0 && entry.Term != term {
+		if len(l.entries) > 0 && entry.Term() != term {
 			debugln("log.truncate.termMismatch")
-			return fmt.Errorf("raft.Log: Entry at index does not have matching term (%v): (IDX=%v, TERM=%v)", entry.Term, index, term)
+			return fmt.Errorf("raft.Log: Entry at index does not have matching term (%v): (IDX=%v, TERM=%v)", entry.Term(), index, term)
 		}
 
 		// Otherwise truncate up to the desired entry.
@@ -462,7 +459,7 @@ func (l *Log) truncate(index uint64, term uint64) error {
 //--------------------------------------
 
 // Appends a series of entries to the log.
-func (l *Log) appendEntries(entries []*LogEntry) error {
+func (l *Log) appendEntries(entries []*protobuf.LogEntry) error {
 	l.mutex.Lock()
 	defer l.mutex.Unlock()
 
@@ -473,12 +470,17 @@ func (l *Log) appendEntries(entries []*LogEntry) error {
 	var size int64
 	var err error
 	// Append each entry but exit if we hit an error.
-	for _, entry := range entries {
-		entry.log = l
-		if size, err = l.writeEntry(entry, w); err != nil {
+	for i := range entries {
+		logEntry := &LogEntry{
+			log:		l,
+			Position:	startPosition,
+			pb:		entries[i],
+		}
+
+		if size, err = l.writeEntry(logEntry, w); err != nil {
 			return err
 		}
-		entry.Position = startPosition
+
 		startPosition += size
 	}
 	w.Flush()
@@ -503,10 +505,10 @@ func (l *Log) appendEntry(entry *LogEntry) error {
 	// Make sure the term and index are greater than the previous.
 	if len(l.entries) > 0 {
 		lastEntry := l.entries[len(l.entries)-1]
-		if entry.Term < lastEntry.Term {
-			return fmt.Errorf("raft.Log: Cannot append entry with earlier term (%x:%x <= %x:%x)", entry.Term, entry.Index, lastEntry.Term, lastEntry.Index)
-		} else if entry.Term == lastEntry.Term && entry.Index <= lastEntry.Index {
-			return fmt.Errorf("raft.Log: Cannot append entry with earlier index in the same term (%x:%x <= %x:%x)", entry.Term, entry.Index, lastEntry.Term, lastEntry.Index)
+		if entry.Term() < lastEntry.Term() {
+			return fmt.Errorf("raft.Log: Cannot append entry with earlier term (%x:%x <= %x:%x)", entry.Term(), entry.Index(), lastEntry.Term(), lastEntry.Index())
+		} else if entry.Term() == lastEntry.Term() && entry.Index() <= lastEntry.Index() {
+			return fmt.Errorf("raft.Log: Cannot append entry with earlier index in the same term (%x:%x <= %x:%x)", entry.Term(), entry.Index(), lastEntry.Term(), lastEntry.Index())
 		}
 	}
 
@@ -534,10 +536,10 @@ func (l *Log) writeEntry(entry *LogEntry, w io.Writer) (int64, error) {
 	// Make sure the term and index are greater than the previous.
 	if len(l.entries) > 0 {
 		lastEntry := l.entries[len(l.entries)-1]
-		if entry.Term < lastEntry.Term {
-			return -1, fmt.Errorf("raft.Log: Cannot append entry with earlier term (%x:%x <= %x:%x)", entry.Term, entry.Index, lastEntry.Term, lastEntry.Index)
-		} else if entry.Term == lastEntry.Term && entry.Index <= lastEntry.Index {
-			return -1, fmt.Errorf("raft.Log: Cannot append entry with earlier index in the same term (%x:%x <= %x:%x)", entry.Term, entry.Index, lastEntry.Term, lastEntry.Index)
+		if entry.Term() < lastEntry.Term() {
+			return -1, fmt.Errorf("raft.Log: Cannot append entry with earlier term (%x:%x <= %x:%x)", entry.Term(), entry.Index(), lastEntry.Term(), lastEntry.Index())
+		} else if entry.Term() == lastEntry.Term() && entry.Index() <= lastEntry.Index() {
+			return -1, fmt.Errorf("raft.Log: Cannot append entry with earlier index in the same term (%x:%x <= %x:%x)", entry.Term(), entry.Index(), lastEntry.Term(), lastEntry.Index())
 		}
 	}
 

+ 36 - 30
third_party/github.com/coreos/raft/log_entry.go

@@ -2,21 +2,19 @@ package raft
 
 import (
 	"bytes"
-	"github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
 	"encoding/json"
 	"fmt"
-	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 	"io"
+
+	"github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 )
 
 // A log entry stores a single item in the log.
 type LogEntry struct {
-	log		*Log
-	Index		uint64
-	Term		uint64
-	CommandName	string
-	Command		[]byte
+	pb		*protobuf.LogEntry
 	Position	int64	// position in the log file
+	log		*Log
 	event		*ev
 }
 
@@ -35,37 +33,51 @@ func newLogEntry(log *Log, event *ev, index uint64, term uint64, command Command
 		}
 	}
 
-	e := &LogEntry{
-		log:		log,
-		Index:		index,
-		Term:		term,
-		CommandName:	commandName,
+	pb := &protobuf.LogEntry{
+		Index:		proto.Uint64(index),
+		Term:		proto.Uint64(term),
+		CommandName:	proto.String(commandName),
 		Command:	buf.Bytes(),
-		event:		event,
+	}
+
+	e := &LogEntry{
+		pb:	pb,
+		log:	log,
+		event:	event,
 	}
 
 	return e, nil
 }
 
+func (e *LogEntry) Index() uint64 {
+	return e.pb.GetIndex()
+}
+
+func (e *LogEntry) Term() uint64 {
+	return e.pb.GetTerm()
+}
+
+func (e *LogEntry) CommandName() string {
+	return e.pb.GetCommandName()
+}
+
+func (e *LogEntry) Command() []byte {
+	return e.pb.GetCommand()
+}
+
 // Encodes the log entry to a buffer. Returns the number of bytes
 // written and any error that may have occurred.
 func (e *LogEntry) encode(w io.Writer) (int, error) {
-	defer e.log.pBuffer.Reset()
-	e.log.pLogEntry.Index = proto.Uint64(e.Index)
-	e.log.pLogEntry.Term = proto.Uint64(e.Term)
-	e.log.pLogEntry.CommandName = proto.String(e.CommandName)
-	e.log.pLogEntry.Command = e.Command
-
-	err := e.log.pBuffer.Marshal(e.log.pLogEntry)
+	b, err := proto.Marshal(e.pb)
 	if err != nil {
 		return -1, err
 	}
 
-	if _, err = fmt.Fprintf(w, "%8x\n", len(e.log.pBuffer.Bytes())); err != nil {
+	if _, err = fmt.Fprintf(w, "%8x\n", len(b)); err != nil {
 		return -1, err
 	}
 
-	return w.Write(e.log.pBuffer.Bytes())
+	return w.Write(b)
 }
 
 // Decodes the log entry from a buffer. Returns the number of bytes read and
@@ -85,15 +97,9 @@ func (e *LogEntry) decode(r io.Reader) (int, error) {
 		return -1, err
 	}
 
-	pb := &protobuf.ProtoLogEntry{}
-	if err = proto.Unmarshal(data, pb); err != nil {
+	if err = proto.Unmarshal(data, e.pb); err != nil {
 		return -1, err
 	}
 
-	e.Term = pb.GetTerm()
-	e.Index = pb.GetIndex()
-	e.CommandName = pb.GetCommandName()
-	e.Command = pb.Command
-
-	return length, nil
+	return length + 8 + 1, nil
 }

+ 9 - 9
third_party/github.com/coreos/raft/log_test.go

@@ -74,13 +74,13 @@ func TestLogExistingLog(t *testing.T) {
 	if len(log.entries) != 3 {
 		t.Fatalf("Expected 3 entries, got %d", len(log.entries))
 	}
-	if log.entries[0].Index != 1 || log.entries[0].Term != 1 {
+	if log.entries[0].Index() != 1 || log.entries[0].Term() != 1 {
 		t.Fatalf("Unexpected entry[0]: %v", log.entries[0])
 	}
-	if log.entries[1].Index != 2 || log.entries[1].Term != 1 {
+	if log.entries[1].Index() != 2 || log.entries[1].Term() != 1 {
 		t.Fatalf("Unexpected entry[1]: %v", log.entries[1])
 	}
-	if log.entries[2].Index != 3 || log.entries[2].Term != 2 {
+	if log.entries[2].Index() != 3 || log.entries[2].Term() != 2 {
 		t.Fatalf("Unexpected entry[2]: %v", log.entries[2])
 	}
 }
@@ -143,13 +143,13 @@ func TestLogRecovery(t *testing.T) {
 	if len(log.entries) != 3 {
 		t.Fatalf("Expected 3 entries, got %d", len(log.entries))
 	}
-	if log.entries[0].Index != 1 || log.entries[0].Term != 1 {
+	if log.entries[0].Index() != 1 || log.entries[0].Term() != 1 {
 		t.Fatalf("Unexpected entry[0]: %v", log.entries[0])
 	}
-	if log.entries[1].Index != 2 || log.entries[1].Term != 1 {
+	if log.entries[1].Index() != 2 || log.entries[1].Term() != 1 {
 		t.Fatalf("Unexpected entry[1]: %v", log.entries[1])
 	}
-	if log.entries[2].Index != 3 || log.entries[2].Term != 2 {
+	if log.entries[2].Index() != 3 || log.entries[2].Term() != 2 {
 		t.Fatalf("Unexpected entry[2]: %v", log.entries[2])
 	}
 }
@@ -220,13 +220,13 @@ func TestLogTruncate(t *testing.T) {
 	if len(log.entries) != 3 {
 		t.Fatalf("Expected 3 entries, got %d", len(log.entries))
 	}
-	if log.entries[0].Index != 1 || log.entries[0].Term != 1 {
+	if log.entries[0].Index() != 1 || log.entries[0].Term() != 1 {
 		t.Fatalf("Unexpected entry[0]: %v", log.entries[0])
 	}
-	if log.entries[1].Index != 2 || log.entries[1].Term != 1 {
+	if log.entries[1].Index() != 2 || log.entries[1].Term() != 1 {
 		t.Fatalf("Unexpected entry[1]: %v", log.entries[1])
 	}
-	if log.entries[2].Index != 3 || log.entries[2].Term != 2 {
+	if log.entries[2].Index() != 3 || log.entries[2].Term() != 2 {
 		t.Fatalf("Unexpected entry[2]: %v", log.entries[2])
 	}
 }

+ 39 - 35
third_party/github.com/coreos/raft/peer.go

@@ -13,13 +13,13 @@ import (
 
 // A peer is a reference to another server involved in the consensus protocol.
 type Peer struct {
-	server           *server
-	Name             string `json:"name"`
-	ConnectionString string `json:"connectionString"`
-	prevLogIndex     uint64
-	mutex            sync.RWMutex
-	stopChan         chan bool
-	heartbeatTimeout time.Duration
+	server            *server
+	Name              string `json:"name"`
+	ConnectionString  string `json:"connectionString"`
+	prevLogIndex      uint64
+	mutex             sync.RWMutex
+	stopChan          chan bool
+	heartbeatInterval time.Duration
 }
 
 //------------------------------------------------------------------------------
@@ -29,12 +29,12 @@ type Peer struct {
 //------------------------------------------------------------------------------
 
 // Creates a new peer.
-func newPeer(server *server, name string, connectionString string, heartbeatTimeout time.Duration) *Peer {
+func newPeer(server *server, name string, connectionString string, heartbeatInterval time.Duration) *Peer {
 	return &Peer{
-		server:           server,
-		Name:             name,
-		ConnectionString: connectionString,
-		heartbeatTimeout: heartbeatTimeout,
+		server:            server,
+		Name:              name,
+		ConnectionString:  connectionString,
+		heartbeatInterval: heartbeatInterval,
 	}
 }
 
@@ -45,8 +45,8 @@ func newPeer(server *server, name string, connectionString string, heartbeatTime
 //------------------------------------------------------------------------------
 
 // Sets the heartbeat timeout.
-func (p *Peer) setHeartbeatTimeout(duration time.Duration) {
-	p.heartbeatTimeout = duration
+func (p *Peer) setHeartbeatInterval(duration time.Duration) {
+	p.heartbeatInterval = duration
 }
 
 //--------------------------------------
@@ -116,22 +116,22 @@ func (p *Peer) heartbeat(c chan bool) {
 
 	c <- true
 
-	ticker := time.Tick(p.heartbeatTimeout)
+	ticker := time.Tick(p.heartbeatInterval)
 
-	debugln("peer.heartbeat: ", p.Name, p.heartbeatTimeout)
+	debugln("peer.heartbeat: ", p.Name, p.heartbeatInterval)
 
 	for {
 		select {
 		case flush := <-stopChan:
-			if !flush {
-				debugln("peer.heartbeat.stop: ", p.Name)
-				return
-			} else {
+			if flush {
 				// before we can safely remove a node
 				// we must flush the remove command to the node first
 				p.flush()
 				debugln("peer.heartbeat.stop.with.flush: ", p.Name)
 				return
+			} else {
+				debugln("peer.heartbeat.stop: ", p.Name)
+				return
 			}
 
 		case <-ticker:
@@ -146,14 +146,12 @@ func (p *Peer) heartbeat(c chan bool) {
 func (p *Peer) flush() {
 	debugln("peer.heartbeat.flush: ", p.Name)
 	prevLogIndex := p.getPrevLogIndex()
-	entries, prevLogTerm := p.server.log.getEntriesAfter(prevLogIndex, p.server.maxLogEntriesPerRequest)
+	term := p.server.currentTerm
 
-	if p.server.State() != Leader {
-		return
-	}
+	entries, prevLogTerm := p.server.log.getEntriesAfter(prevLogIndex, p.server.maxLogEntriesPerRequest)
 
 	if entries != nil {
-		p.sendAppendEntriesRequest(newAppendEntriesRequest(p.server.currentTerm, prevLogIndex, prevLogTerm, p.server.log.CommitIndex(), p.server.name, entries))
+		p.sendAppendEntriesRequest(newAppendEntriesRequest(term, prevLogIndex, prevLogTerm, p.server.log.CommitIndex(), p.server.name, entries))
 	} else {
 		p.sendSnapshotRequest(newSnapshotRequest(p.server.name, p.server.lastSnapshot))
 	}
@@ -170,7 +168,7 @@ func (p *Peer) sendAppendEntriesRequest(req *AppendEntriesRequest) {
 
 	resp := p.server.Transporter().SendAppendEntriesRequest(p.server, p, req)
 	if resp == nil {
-		p.server.DispatchEvent(newEvent(HeartbeatTimeoutEventType, p, nil))
+		p.server.DispatchEvent(newEvent(HeartbeatIntervalEventType, p, nil))
 		debugln("peer.append.timeout: ", p.server.Name(), "->", p.Name)
 		return
 	}
@@ -178,13 +176,13 @@ func (p *Peer) sendAppendEntriesRequest(req *AppendEntriesRequest) {
 
 	// If successful then update the previous log index.
 	p.mutex.Lock()
-	if resp.Success {
+	if resp.Success() {
 		if len(req.Entries) > 0 {
-			p.prevLogIndex = req.Entries[len(req.Entries)-1].Index
+			p.prevLogIndex = req.Entries[len(req.Entries)-1].GetIndex()
 
 			// if peer append a log entry from the current term
 			// we set append to true
-			if req.Entries[len(req.Entries)-1].Term == p.server.currentTerm {
+			if req.Entries[len(req.Entries)-1].GetTerm() == p.server.currentTerm {
 				resp.append = true
 			}
 		}
@@ -192,7 +190,13 @@ func (p *Peer) sendAppendEntriesRequest(req *AppendEntriesRequest) {
 		// If it was unsuccessful then decrement the previous log index and
 		// we'll try again next time.
 	} else {
-		if resp.CommitIndex >= p.prevLogIndex {
+		if resp.Term() > p.server.Term() {
+			// this happens when there is a new leader comes up that this *leader* has not
+			// known yet.
+			// this server can know until the new leader send a ae with higher term
+			// or this server finish processing this response.
+			debugln("peer.append.resp.not.update: new.leader.found")
+		} else if resp.Term() == req.Term && resp.CommitIndex() >= p.prevLogIndex {
 			// we may miss a response from peer
 			// so maybe the peer has committed the logs we just sent
 			// but we did not receive the successful reply and did not increase
@@ -201,7 +205,7 @@ func (p *Peer) sendAppendEntriesRequest(req *AppendEntriesRequest) {
 			// peer failed to truncate the log and sent a fail reply at this time
 			// we just need to update peer's prevLog index to commitIndex
 
-			p.prevLogIndex = resp.CommitIndex
+			p.prevLogIndex = resp.CommitIndex()
 			debugln("peer.append.resp.update: ", p.Name, "; idx =", p.prevLogIndex)
 
 		} else if p.prevLogIndex > 0 {
@@ -210,8 +214,8 @@ func (p *Peer) sendAppendEntriesRequest(req *AppendEntriesRequest) {
 			// problem.
 			p.prevLogIndex--
 			// if it not enough, we directly decrease to the index of the
-			if p.prevLogIndex > resp.Index {
-				p.prevLogIndex = resp.Index
+			if p.prevLogIndex > resp.Index() {
+				p.prevLogIndex = resp.Index()
 			}
 
 			debugln("peer.append.resp.decrement: ", p.Name, "; idx =", p.prevLogIndex)
@@ -265,8 +269,8 @@ func (p *Peer) sendSnapshotRecoveryRequest() {
 		debugln("peer.snap.recovery.failed: ", p.Name)
 		return
 	}
-	// Send response to server for processing.
-	p.server.sendAsync(&AppendEntriesResponse{Term: resp.Term, Success: resp.Success, append: (resp.Term == p.server.currentTerm)})
+
+	p.server.sendAsync(resp)
 }
 
 //--------------------------------------

+ 608 - 46
third_party/github.com/coreos/raft/protobuf/append_entries_request.pb.go

@@ -1,115 +1,677 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-gogo.
 // source: append_entries_request.proto
 // DO NOT EDIT!
 
 package protobuf
 
-import proto "github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
+import proto "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
 import json "encoding/json"
 import math "math"
 
+// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
+
+import io1 "io"
+import code_google_com_p_gogoprotobuf_proto2 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+
+import fmt3 "fmt"
+import strings2 "strings"
+import reflect2 "reflect"
+
+import fmt4 "fmt"
+import strings3 "strings"
+import code_google_com_p_gogoprotobuf_proto3 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+import sort1 "sort"
+import strconv1 "strconv"
+import reflect3 "reflect"
+
+import fmt5 "fmt"
+import bytes1 "bytes"
+
 // Reference proto, json, and math imports to suppress error if they are not otherwise used.
 var _ = proto.Marshal
 var _ = &json.SyntaxError{}
 var _ = math.Inf
 
-type ProtoAppendEntriesRequest struct {
-	Term			*uint64						`protobuf:"varint,1,req" json:"Term,omitempty"`
-	PrevLogIndex		*uint64						`protobuf:"varint,2,req" json:"PrevLogIndex,omitempty"`
-	PrevLogTerm		*uint64						`protobuf:"varint,3,req" json:"PrevLogTerm,omitempty"`
-	CommitIndex		*uint64						`protobuf:"varint,4,req" json:"CommitIndex,omitempty"`
-	LeaderName		*string						`protobuf:"bytes,5,req" json:"LeaderName,omitempty"`
-	Entries			[]*ProtoAppendEntriesRequest_ProtoLogEntry	`protobuf:"bytes,6,rep" json:"Entries,omitempty"`
-	XXX_unrecognized	[]byte						`json:"-"`
+type AppendEntriesRequest struct {
+	Term			*uint64		`protobuf:"varint,1,req" json:"Term,omitempty"`
+	PrevLogIndex		*uint64		`protobuf:"varint,2,req" json:"PrevLogIndex,omitempty"`
+	PrevLogTerm		*uint64		`protobuf:"varint,3,req" json:"PrevLogTerm,omitempty"`
+	CommitIndex		*uint64		`protobuf:"varint,4,req" json:"CommitIndex,omitempty"`
+	LeaderName		*string		`protobuf:"bytes,5,req" json:"LeaderName,omitempty"`
+	Entries			[]*LogEntry	`protobuf:"bytes,6,rep" json:"Entries,omitempty"`
+	XXX_unrecognized	[]byte		`json:"-"`
 }
 
-func (m *ProtoAppendEntriesRequest) Reset()		{ *m = ProtoAppendEntriesRequest{} }
-func (m *ProtoAppendEntriesRequest) String() string	{ return proto.CompactTextString(m) }
-func (*ProtoAppendEntriesRequest) ProtoMessage()	{}
+func (m *AppendEntriesRequest) Reset()		{ *m = AppendEntriesRequest{} }
+func (*AppendEntriesRequest) ProtoMessage()	{}
 
-func (m *ProtoAppendEntriesRequest) GetTerm() uint64 {
+func (m *AppendEntriesRequest) GetTerm() uint64 {
 	if m != nil && m.Term != nil {
 		return *m.Term
 	}
 	return 0
 }
 
-func (m *ProtoAppendEntriesRequest) GetPrevLogIndex() uint64 {
+func (m *AppendEntriesRequest) GetPrevLogIndex() uint64 {
 	if m != nil && m.PrevLogIndex != nil {
 		return *m.PrevLogIndex
 	}
 	return 0
 }
 
-func (m *ProtoAppendEntriesRequest) GetPrevLogTerm() uint64 {
+func (m *AppendEntriesRequest) GetPrevLogTerm() uint64 {
 	if m != nil && m.PrevLogTerm != nil {
 		return *m.PrevLogTerm
 	}
 	return 0
 }
 
-func (m *ProtoAppendEntriesRequest) GetCommitIndex() uint64 {
+func (m *AppendEntriesRequest) GetCommitIndex() uint64 {
 	if m != nil && m.CommitIndex != nil {
 		return *m.CommitIndex
 	}
 	return 0
 }
 
-func (m *ProtoAppendEntriesRequest) GetLeaderName() string {
+func (m *AppendEntriesRequest) GetLeaderName() string {
 	if m != nil && m.LeaderName != nil {
 		return *m.LeaderName
 	}
 	return ""
 }
 
-func (m *ProtoAppendEntriesRequest) GetEntries() []*ProtoAppendEntriesRequest_ProtoLogEntry {
+func (m *AppendEntriesRequest) GetEntries() []*LogEntry {
 	if m != nil {
 		return m.Entries
 	}
 	return nil
 }
 
-type ProtoAppendEntriesRequest_ProtoLogEntry struct {
-	Index			*uint64	`protobuf:"varint,1,req" json:"Index,omitempty"`
-	Term			*uint64	`protobuf:"varint,2,req" json:"Term,omitempty"`
-	CommandName		*string	`protobuf:"bytes,3,req" json:"CommandName,omitempty"`
-	Command			[]byte	`protobuf:"bytes,4,opt" json:"Command,omitempty"`
-	XXX_unrecognized	[]byte	`json:"-"`
+func init() {
 }
-
-func (m *ProtoAppendEntriesRequest_ProtoLogEntry) Reset() {
-	*m = ProtoAppendEntriesRequest_ProtoLogEntry{}
+func (m *AppendEntriesRequest) Unmarshal(data []byte) error {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return io1.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io1.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Term = &v
+		case 2:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io1.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.PrevLogIndex = &v
+		case 3:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io1.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.PrevLogTerm = &v
+		case 4:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io1.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.CommitIndex = &v
+		case 5:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io1.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + int(stringLen)
+			if postIndex > l {
+				return io1.ErrUnexpectedEOF
+			}
+			s := string(data[index:postIndex])
+			m.LeaderName = &s
+			index = postIndex
+		case 6:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io1.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + msglen
+			if postIndex > l {
+				return io1.ErrUnexpectedEOF
+			}
+			m.Entries = append(m.Entries, &LogEntry{})
+			m.Entries[len(m.Entries)-1].Unmarshal(data[index:postIndex])
+			index = postIndex
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			index -= sizeOfWire
+			skippy, err := code_google_com_p_gogoprotobuf_proto2.Skip(data[index:])
+			if err != nil {
+				return err
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
+			index += skippy
+		}
+	}
+	return nil
+}
+func (this *AppendEntriesRequest) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings2.Join([]string{`&AppendEntriesRequest{`,
+		`Term:` + valueToStringAppendEntriesRequest(this.Term) + `,`,
+		`PrevLogIndex:` + valueToStringAppendEntriesRequest(this.PrevLogIndex) + `,`,
+		`PrevLogTerm:` + valueToStringAppendEntriesRequest(this.PrevLogTerm) + `,`,
+		`CommitIndex:` + valueToStringAppendEntriesRequest(this.CommitIndex) + `,`,
+		`LeaderName:` + valueToStringAppendEntriesRequest(this.LeaderName) + `,`,
+		`Entries:` + strings2.Replace(fmt3.Sprintf("%v", this.Entries), "LogEntry", "LogEntry", 1) + `,`,
+		`XXX_unrecognized:` + fmt3.Sprintf("%v", this.XXX_unrecognized) + `,`,
+		`}`,
+	}, "")
+	return s
+}
+func valueToStringAppendEntriesRequest(v interface{}) string {
+	rv := reflect2.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect2.Indirect(rv).Interface()
+	return fmt3.Sprintf("*%v", pv)
+}
+func (m *AppendEntriesRequest) Size() (n int) {
+	var l int
+	_ = l
+	if m.Term != nil {
+		n += 1 + sovAppendEntriesRequest(uint64(*m.Term))
+	}
+	if m.PrevLogIndex != nil {
+		n += 1 + sovAppendEntriesRequest(uint64(*m.PrevLogIndex))
+	}
+	if m.PrevLogTerm != nil {
+		n += 1 + sovAppendEntriesRequest(uint64(*m.PrevLogTerm))
+	}
+	if m.CommitIndex != nil {
+		n += 1 + sovAppendEntriesRequest(uint64(*m.CommitIndex))
+	}
+	if m.LeaderName != nil {
+		l = len(*m.LeaderName)
+		n += 1 + l + sovAppendEntriesRequest(uint64(l))
+	}
+	if len(m.Entries) > 0 {
+		for _, e := range m.Entries {
+			l = e.Size()
+			n += 1 + l + sovAppendEntriesRequest(uint64(l))
+		}
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
 }
-func (m *ProtoAppendEntriesRequest_ProtoLogEntry) String() string	{ return proto.CompactTextString(m) }
-func (*ProtoAppendEntriesRequest_ProtoLogEntry) ProtoMessage()		{}
 
-func (m *ProtoAppendEntriesRequest_ProtoLogEntry) GetIndex() uint64 {
-	if m != nil && m.Index != nil {
-		return *m.Index
+func sovAppendEntriesRequest(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
 	}
-	return 0
+	return n
+}
+func sozAppendEntriesRequest(x uint64) (n int) {
+	return sovAppendEntriesRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+	return sovAppendEntriesRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func NewPopulatedAppendEntriesRequest(r randyAppendEntriesRequest, easy bool) *AppendEntriesRequest {
+	this := &AppendEntriesRequest{}
+	v1 := uint64(r.Uint32())
+	this.Term = &v1
+	v2 := uint64(r.Uint32())
+	this.PrevLogIndex = &v2
+	v3 := uint64(r.Uint32())
+	this.PrevLogTerm = &v3
+	v4 := uint64(r.Uint32())
+	this.CommitIndex = &v4
+	v5 := randStringAppendEntriesRequest(r)
+	this.LeaderName = &v5
+	if r.Intn(10) != 0 {
+		v6 := r.Intn(10)
+		this.Entries = make([]*LogEntry, v6)
+		for i := 0; i < v6; i++ {
+			this.Entries[i] = NewPopulatedLogEntry(r, easy)
+		}
+	}
+	if !easy && r.Intn(10) != 0 {
+		this.XXX_unrecognized = randUnrecognizedAppendEntriesRequest(r, 7)
+	}
+	return this
 }
 
-func (m *ProtoAppendEntriesRequest_ProtoLogEntry) GetTerm() uint64 {
-	if m != nil && m.Term != nil {
-		return *m.Term
+type randyAppendEntriesRequest interface {
+	Float32() float32
+	Float64() float64
+	Int63() int64
+	Int31() int32
+	Uint32() uint32
+	Intn(n int) int
+}
+
+func randUTF8RuneAppendEntriesRequest(r randyAppendEntriesRequest) rune {
+	res := rune(r.Uint32() % 1112064)
+	if 55296 <= res {
+		res += 2047
 	}
-	return 0
+	return res
+}
+func randStringAppendEntriesRequest(r randyAppendEntriesRequest) string {
+	v7 := r.Intn(100)
+	tmps := make([]rune, v7)
+	for i := 0; i < v7; i++ {
+		tmps[i] = randUTF8RuneAppendEntriesRequest(r)
+	}
+	return string(tmps)
+}
+func randUnrecognizedAppendEntriesRequest(r randyAppendEntriesRequest, maxFieldNumber int) (data []byte) {
+	l := r.Intn(5)
+	for i := 0; i < l; i++ {
+		wire := r.Intn(4)
+		if wire == 3 {
+			wire = 5
+		}
+		fieldNumber := maxFieldNumber + r.Intn(100)
+		data = randFieldAppendEntriesRequest(data, r, fieldNumber, wire)
+	}
+	return data
+}
+func randFieldAppendEntriesRequest(data []byte, r randyAppendEntriesRequest, fieldNumber int, wire int) []byte {
+	key := uint32(fieldNumber)<<3 | uint32(wire)
+	switch wire {
+	case 0:
+		data = encodeVarintPopulateAppendEntriesRequest(data, uint64(key))
+		data = encodeVarintPopulateAppendEntriesRequest(data, uint64(r.Int63()))
+	case 1:
+		data = encodeVarintPopulateAppendEntriesRequest(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	case 2:
+		data = encodeVarintPopulateAppendEntriesRequest(data, uint64(key))
+		ll := r.Intn(100)
+		data = encodeVarintPopulateAppendEntriesRequest(data, uint64(ll))
+		for j := 0; j < ll; j++ {
+			data = append(data, byte(r.Intn(256)))
+		}
+	default:
+		data = encodeVarintPopulateAppendEntriesRequest(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	}
+	return data
+}
+func encodeVarintPopulateAppendEntriesRequest(data []byte, v uint64) []byte {
+	for v >= 1<<7 {
+		data = append(data, uint8(uint64(v)&0x7f|0x80))
+		v >>= 7
+	}
+	data = append(data, uint8(v))
+	return data
+}
+func (m *AppendEntriesRequest) Marshal() (data []byte, err error) {
+	size := m.Size()
+	data = make([]byte, size)
+	n, err := m.MarshalTo(data)
+	if err != nil {
+		return nil, err
+	}
+	return data[:n], nil
 }
 
-func (m *ProtoAppendEntriesRequest_ProtoLogEntry) GetCommandName() string {
-	if m != nil && m.CommandName != nil {
-		return *m.CommandName
+func (m *AppendEntriesRequest) MarshalTo(data []byte) (n int, err error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Term != nil {
+		data[i] = 0x8
+		i++
+		i = encodeVarintAppendEntriesRequest(data, i, uint64(*m.Term))
 	}
-	return ""
+	if m.PrevLogIndex != nil {
+		data[i] = 0x10
+		i++
+		i = encodeVarintAppendEntriesRequest(data, i, uint64(*m.PrevLogIndex))
+	}
+	if m.PrevLogTerm != nil {
+		data[i] = 0x18
+		i++
+		i = encodeVarintAppendEntriesRequest(data, i, uint64(*m.PrevLogTerm))
+	}
+	if m.CommitIndex != nil {
+		data[i] = 0x20
+		i++
+		i = encodeVarintAppendEntriesRequest(data, i, uint64(*m.CommitIndex))
+	}
+	if m.LeaderName != nil {
+		data[i] = 0x2a
+		i++
+		i = encodeVarintAppendEntriesRequest(data, i, uint64(len(*m.LeaderName)))
+		i += copy(data[i:], *m.LeaderName)
+	}
+	if len(m.Entries) > 0 {
+		for _, msg := range m.Entries {
+			data[i] = 0x32
+			i++
+			i = encodeVarintAppendEntriesRequest(data, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(data[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(data[i:], m.XXX_unrecognized)
+	}
+	return i, nil
 }
+func encodeFixed64AppendEntriesRequest(data []byte, offset int, v uint64) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	data[offset+4] = uint8(v >> 32)
+	data[offset+5] = uint8(v >> 40)
+	data[offset+6] = uint8(v >> 48)
+	data[offset+7] = uint8(v >> 56)
+	return offset + 8
+}
+func encodeFixed32AppendEntriesRequest(data []byte, offset int, v uint32) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	return offset + 4
+}
+func encodeVarintAppendEntriesRequest(data []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		data[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	data[offset] = uint8(v)
+	return offset + 1
+}
+func (this *AppendEntriesRequest) GoString() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings3.Join([]string{`&protobuf.AppendEntriesRequest{` + `Term:` + valueToGoStringAppendEntriesRequest(this.Term, "uint64"), `PrevLogIndex:` + valueToGoStringAppendEntriesRequest(this.PrevLogIndex, "uint64"), `PrevLogTerm:` + valueToGoStringAppendEntriesRequest(this.PrevLogTerm, "uint64"), `CommitIndex:` + valueToGoStringAppendEntriesRequest(this.CommitIndex, "uint64"), `LeaderName:` + valueToGoStringAppendEntriesRequest(this.LeaderName, "string"), `Entries:` + fmt4.Sprintf("%#v", this.Entries), `XXX_unrecognized:` + fmt4.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
+	return s
+}
+func valueToGoStringAppendEntriesRequest(v interface{}, typ string) string {
+	rv := reflect3.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect3.Indirect(rv).Interface()
+	return fmt4.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
+}
+func extensionToGoStringAppendEntriesRequest(e map[int32]code_google_com_p_gogoprotobuf_proto3.Extension) string {
+	if e == nil {
+		return "nil"
+	}
+	s := "map[int32]proto.Extension{"
+	keys := make([]int, 0, len(e))
+	for k := range e {
+		keys = append(keys, int(k))
+	}
+	sort1.Ints(keys)
+	ss := []string{}
+	for _, k := range keys {
+		ss = append(ss, strconv1.Itoa(k)+": "+e[int32(k)].GoString())
+	}
+	s += strings3.Join(ss, ",") + "}"
+	return s
+}
+func (this *AppendEntriesRequest) VerboseEqual(that interface{}) error {
+	if that == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt5.Errorf("that == nil && this != nil")
+	}
 
-func (m *ProtoAppendEntriesRequest_ProtoLogEntry) GetCommand() []byte {
-	if m != nil {
-		return m.Command
+	that1, ok := that.(*AppendEntriesRequest)
+	if !ok {
+		return fmt5.Errorf("that is not of type *AppendEntriesRequest")
+	}
+	if that1 == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt5.Errorf("that is type *AppendEntriesRequest but is nil && this != nil")
+	} else if this == nil {
+		return fmt5.Errorf("that is type *AppendEntriesRequestbut is not nil && this == nil")
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return fmt5.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
+		}
+	} else if this.Term != nil {
+		return fmt5.Errorf("this.Term == nil && that.Term != nil")
+	} else if that1.Term != nil {
+		return fmt5.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
+	}
+	if this.PrevLogIndex != nil && that1.PrevLogIndex != nil {
+		if *this.PrevLogIndex != *that1.PrevLogIndex {
+			return fmt5.Errorf("PrevLogIndex this(%v) Not Equal that(%v)", *this.PrevLogIndex, *that1.PrevLogIndex)
+		}
+	} else if this.PrevLogIndex != nil {
+		return fmt5.Errorf("this.PrevLogIndex == nil && that.PrevLogIndex != nil")
+	} else if that1.PrevLogIndex != nil {
+		return fmt5.Errorf("PrevLogIndex this(%v) Not Equal that(%v)", this.PrevLogIndex, that1.PrevLogIndex)
+	}
+	if this.PrevLogTerm != nil && that1.PrevLogTerm != nil {
+		if *this.PrevLogTerm != *that1.PrevLogTerm {
+			return fmt5.Errorf("PrevLogTerm this(%v) Not Equal that(%v)", *this.PrevLogTerm, *that1.PrevLogTerm)
+		}
+	} else if this.PrevLogTerm != nil {
+		return fmt5.Errorf("this.PrevLogTerm == nil && that.PrevLogTerm != nil")
+	} else if that1.PrevLogTerm != nil {
+		return fmt5.Errorf("PrevLogTerm this(%v) Not Equal that(%v)", this.PrevLogTerm, that1.PrevLogTerm)
+	}
+	if this.CommitIndex != nil && that1.CommitIndex != nil {
+		if *this.CommitIndex != *that1.CommitIndex {
+			return fmt5.Errorf("CommitIndex this(%v) Not Equal that(%v)", *this.CommitIndex, *that1.CommitIndex)
+		}
+	} else if this.CommitIndex != nil {
+		return fmt5.Errorf("this.CommitIndex == nil && that.CommitIndex != nil")
+	} else if that1.CommitIndex != nil {
+		return fmt5.Errorf("CommitIndex this(%v) Not Equal that(%v)", this.CommitIndex, that1.CommitIndex)
+	}
+	if this.LeaderName != nil && that1.LeaderName != nil {
+		if *this.LeaderName != *that1.LeaderName {
+			return fmt5.Errorf("LeaderName this(%v) Not Equal that(%v)", *this.LeaderName, *that1.LeaderName)
+		}
+	} else if this.LeaderName != nil {
+		return fmt5.Errorf("this.LeaderName == nil && that.LeaderName != nil")
+	} else if that1.LeaderName != nil {
+		return fmt5.Errorf("LeaderName this(%v) Not Equal that(%v)", this.LeaderName, that1.LeaderName)
+	}
+	if len(this.Entries) != len(that1.Entries) {
+		return fmt5.Errorf("Entries this(%v) Not Equal that(%v)", len(this.Entries), len(that1.Entries))
+	}
+	for i := range this.Entries {
+		if !this.Entries[i].Equal(that1.Entries[i]) {
+			return fmt5.Errorf("Entries this[%v](%v) Not Equal that[%v](%v)", i, this.Entries[i], i, that1.Entries[i])
+		}
+	}
+	if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return fmt5.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
 	}
 	return nil
 }
+func (this *AppendEntriesRequest) Equal(that interface{}) bool {
+	if that == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	}
 
-func init() {
+	that1, ok := that.(*AppendEntriesRequest)
+	if !ok {
+		return false
+	}
+	if that1 == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	} else if this == nil {
+		return false
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return false
+		}
+	} else if this.Term != nil {
+		return false
+	} else if that1.Term != nil {
+		return false
+	}
+	if this.PrevLogIndex != nil && that1.PrevLogIndex != nil {
+		if *this.PrevLogIndex != *that1.PrevLogIndex {
+			return false
+		}
+	} else if this.PrevLogIndex != nil {
+		return false
+	} else if that1.PrevLogIndex != nil {
+		return false
+	}
+	if this.PrevLogTerm != nil && that1.PrevLogTerm != nil {
+		if *this.PrevLogTerm != *that1.PrevLogTerm {
+			return false
+		}
+	} else if this.PrevLogTerm != nil {
+		return false
+	} else if that1.PrevLogTerm != nil {
+		return false
+	}
+	if this.CommitIndex != nil && that1.CommitIndex != nil {
+		if *this.CommitIndex != *that1.CommitIndex {
+			return false
+		}
+	} else if this.CommitIndex != nil {
+		return false
+	} else if that1.CommitIndex != nil {
+		return false
+	}
+	if this.LeaderName != nil && that1.LeaderName != nil {
+		if *this.LeaderName != *that1.LeaderName {
+			return false
+		}
+	} else if this.LeaderName != nil {
+		return false
+	} else if that1.LeaderName != nil {
+		return false
+	}
+	if len(this.Entries) != len(that1.Entries) {
+		return false
+	}
+	for i := range this.Entries {
+		if !this.Entries[i].Equal(that1.Entries[i]) {
+			return false
+		}
+	}
+	if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return false
+	}
+	return true
 }

+ 17 - 10
third_party/github.com/coreos/raft/protobuf/append_entries_request.proto

@@ -1,18 +1,25 @@
 package protobuf;
 
-message ProtoAppendEntriesRequest {
+import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
+import "log_entry.proto";
+
+option (gogoproto.gostring_all) = true;
+option (gogoproto.equal_all) = true;
+option (gogoproto.verbose_equal_all) = true;
+option (gogoproto.goproto_stringer_all) = false;
+option (gogoproto.stringer_all) =  true;
+option (gogoproto.populate_all) = true;
+option (gogoproto.testgen_all) = true;
+option (gogoproto.benchgen_all) = true;
+option (gogoproto.marshaler_all) = true;
+option (gogoproto.sizer_all) = true;
+option (gogoproto.unmarshaler_all) = true;
+
+message AppendEntriesRequest {
 	required uint64 Term=1;
 	required uint64 PrevLogIndex=2;
 	required uint64 PrevLogTerm=3;
 	required uint64 CommitIndex=4;
 	required string LeaderName=5;
-
-	message ProtoLogEntry {
-		required uint64 Index=1;
-		required uint64 Term=2;
-		required string CommandName=3;
-		optional bytes Command=4;
-	}
-
-	repeated ProtoLogEntry Entries=6;
+	repeated LogEntry Entries=6;
 }

+ 501 - 10
third_party/github.com/coreos/raft/protobuf/append_entries_responses.pb.go

@@ -1,19 +1,38 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-gogo.
 // source: append_entries_responses.proto
 // DO NOT EDIT!
 
 package protobuf
 
-import proto "github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
+import proto "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
 import json "encoding/json"
 import math "math"
 
+// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
+
+import io2 "io"
+import code_google_com_p_gogoprotobuf_proto4 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+
+import fmt6 "fmt"
+import strings4 "strings"
+import reflect4 "reflect"
+
+import fmt7 "fmt"
+import strings5 "strings"
+import code_google_com_p_gogoprotobuf_proto5 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+import sort2 "sort"
+import strconv2 "strconv"
+import reflect5 "reflect"
+
+import fmt8 "fmt"
+import bytes2 "bytes"
+
 // Reference proto, json, and math imports to suppress error if they are not otherwise used.
 var _ = proto.Marshal
 var _ = &json.SyntaxError{}
 var _ = math.Inf
 
-type ProtoAppendEntriesResponse struct {
+type AppendEntriesResponse struct {
 	Term			*uint64	`protobuf:"varint,1,req" json:"Term,omitempty"`
 	Index			*uint64	`protobuf:"varint,2,req" json:"Index,omitempty"`
 	CommitIndex		*uint64	`protobuf:"varint,3,req" json:"CommitIndex,omitempty"`
@@ -21,32 +40,31 @@ type ProtoAppendEntriesResponse struct {
 	XXX_unrecognized	[]byte	`json:"-"`
 }
 
-func (m *ProtoAppendEntriesResponse) Reset()		{ *m = ProtoAppendEntriesResponse{} }
-func (m *ProtoAppendEntriesResponse) String() string	{ return proto.CompactTextString(m) }
-func (*ProtoAppendEntriesResponse) ProtoMessage()	{}
+func (m *AppendEntriesResponse) Reset()		{ *m = AppendEntriesResponse{} }
+func (*AppendEntriesResponse) ProtoMessage()	{}
 
-func (m *ProtoAppendEntriesResponse) GetTerm() uint64 {
+func (m *AppendEntriesResponse) GetTerm() uint64 {
 	if m != nil && m.Term != nil {
 		return *m.Term
 	}
 	return 0
 }
 
-func (m *ProtoAppendEntriesResponse) GetIndex() uint64 {
+func (m *AppendEntriesResponse) GetIndex() uint64 {
 	if m != nil && m.Index != nil {
 		return *m.Index
 	}
 	return 0
 }
 
-func (m *ProtoAppendEntriesResponse) GetCommitIndex() uint64 {
+func (m *AppendEntriesResponse) GetCommitIndex() uint64 {
 	if m != nil && m.CommitIndex != nil {
 		return *m.CommitIndex
 	}
 	return 0
 }
 
-func (m *ProtoAppendEntriesResponse) GetSuccess() bool {
+func (m *AppendEntriesResponse) GetSuccess() bool {
 	if m != nil && m.Success != nil {
 		return *m.Success
 	}
@@ -55,3 +73,476 @@ func (m *ProtoAppendEntriesResponse) GetSuccess() bool {
 
 func init() {
 }
+func (m *AppendEntriesResponse) Unmarshal(data []byte) error {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return io2.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io2.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Term = &v
+		case 2:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io2.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Index = &v
+		case 3:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io2.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.CommitIndex = &v
+		case 4:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io2.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			b := bool(v != 0)
+			m.Success = &b
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			index -= sizeOfWire
+			skippy, err := code_google_com_p_gogoprotobuf_proto4.Skip(data[index:])
+			if err != nil {
+				return err
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
+			index += skippy
+		}
+	}
+	return nil
+}
+func (this *AppendEntriesResponse) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings4.Join([]string{`&AppendEntriesResponse{`,
+		`Term:` + valueToStringAppendEntriesResponses(this.Term) + `,`,
+		`Index:` + valueToStringAppendEntriesResponses(this.Index) + `,`,
+		`CommitIndex:` + valueToStringAppendEntriesResponses(this.CommitIndex) + `,`,
+		`Success:` + valueToStringAppendEntriesResponses(this.Success) + `,`,
+		`XXX_unrecognized:` + fmt6.Sprintf("%v", this.XXX_unrecognized) + `,`,
+		`}`,
+	}, "")
+	return s
+}
+func valueToStringAppendEntriesResponses(v interface{}) string {
+	rv := reflect4.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect4.Indirect(rv).Interface()
+	return fmt6.Sprintf("*%v", pv)
+}
+func (m *AppendEntriesResponse) Size() (n int) {
+	var l int
+	_ = l
+	if m.Term != nil {
+		n += 1 + sovAppendEntriesResponses(uint64(*m.Term))
+	}
+	if m.Index != nil {
+		n += 1 + sovAppendEntriesResponses(uint64(*m.Index))
+	}
+	if m.CommitIndex != nil {
+		n += 1 + sovAppendEntriesResponses(uint64(*m.CommitIndex))
+	}
+	if m.Success != nil {
+		n += 2
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func sovAppendEntriesResponses(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozAppendEntriesResponses(x uint64) (n int) {
+	return sovAppendEntriesResponses(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+	return sovAppendEntriesResponses(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func NewPopulatedAppendEntriesResponse(r randyAppendEntriesResponses, easy bool) *AppendEntriesResponse {
+	this := &AppendEntriesResponse{}
+	v1 := uint64(r.Uint32())
+	this.Term = &v1
+	v2 := uint64(r.Uint32())
+	this.Index = &v2
+	v3 := uint64(r.Uint32())
+	this.CommitIndex = &v3
+	v4 := bool(r.Intn(2) == 0)
+	this.Success = &v4
+	if !easy && r.Intn(10) != 0 {
+		this.XXX_unrecognized = randUnrecognizedAppendEntriesResponses(r, 5)
+	}
+	return this
+}
+
+type randyAppendEntriesResponses interface {
+	Float32() float32
+	Float64() float64
+	Int63() int64
+	Int31() int32
+	Uint32() uint32
+	Intn(n int) int
+}
+
+func randUTF8RuneAppendEntriesResponses(r randyAppendEntriesResponses) rune {
+	res := rune(r.Uint32() % 1112064)
+	if 55296 <= res {
+		res += 2047
+	}
+	return res
+}
+func randStringAppendEntriesResponses(r randyAppendEntriesResponses) string {
+	v5 := r.Intn(100)
+	tmps := make([]rune, v5)
+	for i := 0; i < v5; i++ {
+		tmps[i] = randUTF8RuneAppendEntriesResponses(r)
+	}
+	return string(tmps)
+}
+func randUnrecognizedAppendEntriesResponses(r randyAppendEntriesResponses, maxFieldNumber int) (data []byte) {
+	l := r.Intn(5)
+	for i := 0; i < l; i++ {
+		wire := r.Intn(4)
+		if wire == 3 {
+			wire = 5
+		}
+		fieldNumber := maxFieldNumber + r.Intn(100)
+		data = randFieldAppendEntriesResponses(data, r, fieldNumber, wire)
+	}
+	return data
+}
+func randFieldAppendEntriesResponses(data []byte, r randyAppendEntriesResponses, fieldNumber int, wire int) []byte {
+	key := uint32(fieldNumber)<<3 | uint32(wire)
+	switch wire {
+	case 0:
+		data = encodeVarintPopulateAppendEntriesResponses(data, uint64(key))
+		data = encodeVarintPopulateAppendEntriesResponses(data, uint64(r.Int63()))
+	case 1:
+		data = encodeVarintPopulateAppendEntriesResponses(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	case 2:
+		data = encodeVarintPopulateAppendEntriesResponses(data, uint64(key))
+		ll := r.Intn(100)
+		data = encodeVarintPopulateAppendEntriesResponses(data, uint64(ll))
+		for j := 0; j < ll; j++ {
+			data = append(data, byte(r.Intn(256)))
+		}
+	default:
+		data = encodeVarintPopulateAppendEntriesResponses(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	}
+	return data
+}
+func encodeVarintPopulateAppendEntriesResponses(data []byte, v uint64) []byte {
+	for v >= 1<<7 {
+		data = append(data, uint8(uint64(v)&0x7f|0x80))
+		v >>= 7
+	}
+	data = append(data, uint8(v))
+	return data
+}
+func (m *AppendEntriesResponse) Marshal() (data []byte, err error) {
+	size := m.Size()
+	data = make([]byte, size)
+	n, err := m.MarshalTo(data)
+	if err != nil {
+		return nil, err
+	}
+	return data[:n], nil
+}
+
+func (m *AppendEntriesResponse) MarshalTo(data []byte) (n int, err error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Term != nil {
+		data[i] = 0x8
+		i++
+		i = encodeVarintAppendEntriesResponses(data, i, uint64(*m.Term))
+	}
+	if m.Index != nil {
+		data[i] = 0x10
+		i++
+		i = encodeVarintAppendEntriesResponses(data, i, uint64(*m.Index))
+	}
+	if m.CommitIndex != nil {
+		data[i] = 0x18
+		i++
+		i = encodeVarintAppendEntriesResponses(data, i, uint64(*m.CommitIndex))
+	}
+	if m.Success != nil {
+		data[i] = 0x20
+		i++
+		if *m.Success {
+			data[i] = 1
+		} else {
+			data[i] = 0
+		}
+		i++
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(data[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+func encodeFixed64AppendEntriesResponses(data []byte, offset int, v uint64) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	data[offset+4] = uint8(v >> 32)
+	data[offset+5] = uint8(v >> 40)
+	data[offset+6] = uint8(v >> 48)
+	data[offset+7] = uint8(v >> 56)
+	return offset + 8
+}
+func encodeFixed32AppendEntriesResponses(data []byte, offset int, v uint32) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	return offset + 4
+}
+func encodeVarintAppendEntriesResponses(data []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		data[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	data[offset] = uint8(v)
+	return offset + 1
+}
+func (this *AppendEntriesResponse) GoString() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings5.Join([]string{`&protobuf.AppendEntriesResponse{` + `Term:` + valueToGoStringAppendEntriesResponses(this.Term, "uint64"), `Index:` + valueToGoStringAppendEntriesResponses(this.Index, "uint64"), `CommitIndex:` + valueToGoStringAppendEntriesResponses(this.CommitIndex, "uint64"), `Success:` + valueToGoStringAppendEntriesResponses(this.Success, "bool"), `XXX_unrecognized:` + fmt7.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
+	return s
+}
+func valueToGoStringAppendEntriesResponses(v interface{}, typ string) string {
+	rv := reflect5.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect5.Indirect(rv).Interface()
+	return fmt7.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
+}
+func extensionToGoStringAppendEntriesResponses(e map[int32]code_google_com_p_gogoprotobuf_proto5.Extension) string {
+	if e == nil {
+		return "nil"
+	}
+	s := "map[int32]proto.Extension{"
+	keys := make([]int, 0, len(e))
+	for k := range e {
+		keys = append(keys, int(k))
+	}
+	sort2.Ints(keys)
+	ss := []string{}
+	for _, k := range keys {
+		ss = append(ss, strconv2.Itoa(k)+": "+e[int32(k)].GoString())
+	}
+	s += strings5.Join(ss, ",") + "}"
+	return s
+}
+func (this *AppendEntriesResponse) VerboseEqual(that interface{}) error {
+	if that == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt8.Errorf("that == nil && this != nil")
+	}
+
+	that1, ok := that.(*AppendEntriesResponse)
+	if !ok {
+		return fmt8.Errorf("that is not of type *AppendEntriesResponse")
+	}
+	if that1 == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt8.Errorf("that is type *AppendEntriesResponse but is nil && this != nil")
+	} else if this == nil {
+		return fmt8.Errorf("that is type *AppendEntriesResponsebut is not nil && this == nil")
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return fmt8.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
+		}
+	} else if this.Term != nil {
+		return fmt8.Errorf("this.Term == nil && that.Term != nil")
+	} else if that1.Term != nil {
+		return fmt8.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
+	}
+	if this.Index != nil && that1.Index != nil {
+		if *this.Index != *that1.Index {
+			return fmt8.Errorf("Index this(%v) Not Equal that(%v)", *this.Index, *that1.Index)
+		}
+	} else if this.Index != nil {
+		return fmt8.Errorf("this.Index == nil && that.Index != nil")
+	} else if that1.Index != nil {
+		return fmt8.Errorf("Index this(%v) Not Equal that(%v)", this.Index, that1.Index)
+	}
+	if this.CommitIndex != nil && that1.CommitIndex != nil {
+		if *this.CommitIndex != *that1.CommitIndex {
+			return fmt8.Errorf("CommitIndex this(%v) Not Equal that(%v)", *this.CommitIndex, *that1.CommitIndex)
+		}
+	} else if this.CommitIndex != nil {
+		return fmt8.Errorf("this.CommitIndex == nil && that.CommitIndex != nil")
+	} else if that1.CommitIndex != nil {
+		return fmt8.Errorf("CommitIndex this(%v) Not Equal that(%v)", this.CommitIndex, that1.CommitIndex)
+	}
+	if this.Success != nil && that1.Success != nil {
+		if *this.Success != *that1.Success {
+			return fmt8.Errorf("Success this(%v) Not Equal that(%v)", *this.Success, *that1.Success)
+		}
+	} else if this.Success != nil {
+		return fmt8.Errorf("this.Success == nil && that.Success != nil")
+	} else if that1.Success != nil {
+		return fmt8.Errorf("Success this(%v) Not Equal that(%v)", this.Success, that1.Success)
+	}
+	if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return fmt8.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
+	}
+	return nil
+}
+func (this *AppendEntriesResponse) Equal(that interface{}) bool {
+	if that == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	}
+
+	that1, ok := that.(*AppendEntriesResponse)
+	if !ok {
+		return false
+	}
+	if that1 == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	} else if this == nil {
+		return false
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return false
+		}
+	} else if this.Term != nil {
+		return false
+	} else if that1.Term != nil {
+		return false
+	}
+	if this.Index != nil && that1.Index != nil {
+		if *this.Index != *that1.Index {
+			return false
+		}
+	} else if this.Index != nil {
+		return false
+	} else if that1.Index != nil {
+		return false
+	}
+	if this.CommitIndex != nil && that1.CommitIndex != nil {
+		if *this.CommitIndex != *that1.CommitIndex {
+			return false
+		}
+	} else if this.CommitIndex != nil {
+		return false
+	} else if that1.CommitIndex != nil {
+		return false
+	}
+	if this.Success != nil && that1.Success != nil {
+		if *this.Success != *that1.Success {
+			return false
+		}
+	} else if this.Success != nil {
+		return false
+	} else if that1.Success != nil {
+		return false
+	}
+	if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return false
+	}
+	return true
+}

+ 15 - 1
third_party/github.com/coreos/raft/protobuf/append_entries_responses.proto

@@ -1,6 +1,20 @@
 package protobuf;
 
-message ProtoAppendEntriesResponse {
+import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
+
+option (gogoproto.gostring_all) = true;
+option (gogoproto.equal_all) = true;
+option (gogoproto.verbose_equal_all) = true;
+option (gogoproto.goproto_stringer_all) = false;
+option (gogoproto.stringer_all) =  true;
+option (gogoproto.populate_all) = true;
+option (gogoproto.testgen_all) = true;
+option (gogoproto.benchgen_all) = true;
+option (gogoproto.marshaler_all) = true;
+option (gogoproto.sizer_all) = true;
+option (gogoproto.unmarshaler_all) = true;
+
+message AppendEntriesResponse {
 	required uint64 Term=1;
 	required uint64 Index=2;
 	required uint64 CommitIndex=3;

+ 503 - 10
third_party/github.com/coreos/raft/protobuf/log_entry.pb.go

@@ -1,19 +1,38 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-gogo.
 // source: log_entry.proto
 // DO NOT EDIT!
 
 package protobuf
 
-import proto "github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
+import proto "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
 import json "encoding/json"
 import math "math"
 
+// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
+
+import io "io"
+import code_google_com_p_gogoprotobuf_proto "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+
+import fmt "fmt"
+import strings "strings"
+import reflect "reflect"
+
+import fmt1 "fmt"
+import strings1 "strings"
+import code_google_com_p_gogoprotobuf_proto1 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+import sort "sort"
+import strconv "strconv"
+import reflect1 "reflect"
+
+import fmt2 "fmt"
+import bytes "bytes"
+
 // Reference proto, json, and math imports to suppress error if they are not otherwise used.
 var _ = proto.Marshal
 var _ = &json.SyntaxError{}
 var _ = math.Inf
 
-type ProtoLogEntry struct {
+type LogEntry struct {
 	Index			*uint64	`protobuf:"varint,1,req" json:"Index,omitempty"`
 	Term			*uint64	`protobuf:"varint,2,req" json:"Term,omitempty"`
 	CommandName		*string	`protobuf:"bytes,3,req" json:"CommandName,omitempty"`
@@ -21,32 +40,31 @@ type ProtoLogEntry struct {
 	XXX_unrecognized	[]byte	`json:"-"`
 }
 
-func (m *ProtoLogEntry) Reset()		{ *m = ProtoLogEntry{} }
-func (m *ProtoLogEntry) String() string	{ return proto.CompactTextString(m) }
-func (*ProtoLogEntry) ProtoMessage()	{}
+func (m *LogEntry) Reset()	{ *m = LogEntry{} }
+func (*LogEntry) ProtoMessage()	{}
 
-func (m *ProtoLogEntry) GetIndex() uint64 {
+func (m *LogEntry) GetIndex() uint64 {
 	if m != nil && m.Index != nil {
 		return *m.Index
 	}
 	return 0
 }
 
-func (m *ProtoLogEntry) GetTerm() uint64 {
+func (m *LogEntry) GetTerm() uint64 {
 	if m != nil && m.Term != nil {
 		return *m.Term
 	}
 	return 0
 }
 
-func (m *ProtoLogEntry) GetCommandName() string {
+func (m *LogEntry) GetCommandName() string {
 	if m != nil && m.CommandName != nil {
 		return *m.CommandName
 	}
 	return ""
 }
 
-func (m *ProtoLogEntry) GetCommand() []byte {
+func (m *LogEntry) GetCommand() []byte {
 	if m != nil {
 		return m.Command
 	}
@@ -55,3 +73,478 @@ func (m *ProtoLogEntry) GetCommand() []byte {
 
 func init() {
 }
+func (m *LogEntry) Unmarshal(data []byte) error {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Index = &v
+		case 2:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Term = &v
+		case 3:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + int(stringLen)
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			s := string(data[index:postIndex])
+			m.CommandName = &s
+			index = postIndex
+		case 4:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Command = append(m.Command, data[index:postIndex]...)
+			index = postIndex
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			index -= sizeOfWire
+			skippy, err := code_google_com_p_gogoprotobuf_proto.Skip(data[index:])
+			if err != nil {
+				return err
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
+			index += skippy
+		}
+	}
+	return nil
+}
+func (this *LogEntry) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings.Join([]string{`&LogEntry{`,
+		`Index:` + valueToStringLogEntry(this.Index) + `,`,
+		`Term:` + valueToStringLogEntry(this.Term) + `,`,
+		`CommandName:` + valueToStringLogEntry(this.CommandName) + `,`,
+		`Command:` + valueToStringLogEntry(this.Command) + `,`,
+		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
+		`}`,
+	}, "")
+	return s
+}
+func valueToStringLogEntry(v interface{}) string {
+	rv := reflect.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect.Indirect(rv).Interface()
+	return fmt.Sprintf("*%v", pv)
+}
+func (m *LogEntry) Size() (n int) {
+	var l int
+	_ = l
+	if m.Index != nil {
+		n += 1 + sovLogEntry(uint64(*m.Index))
+	}
+	if m.Term != nil {
+		n += 1 + sovLogEntry(uint64(*m.Term))
+	}
+	if m.CommandName != nil {
+		l = len(*m.CommandName)
+		n += 1 + l + sovLogEntry(uint64(l))
+	}
+	if m.Command != nil {
+		l = len(m.Command)
+		n += 1 + l + sovLogEntry(uint64(l))
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func sovLogEntry(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozLogEntry(x uint64) (n int) {
+	return sovLogEntry(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+	return sovLogEntry(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func NewPopulatedLogEntry(r randyLogEntry, easy bool) *LogEntry {
+	this := &LogEntry{}
+	v1 := uint64(r.Uint32())
+	this.Index = &v1
+	v2 := uint64(r.Uint32())
+	this.Term = &v2
+	v3 := randStringLogEntry(r)
+	this.CommandName = &v3
+	if r.Intn(10) != 0 {
+		v4 := r.Intn(100)
+		this.Command = make([]byte, v4)
+		for i := 0; i < v4; i++ {
+			this.Command[i] = byte(r.Intn(256))
+		}
+	}
+	if !easy && r.Intn(10) != 0 {
+		this.XXX_unrecognized = randUnrecognizedLogEntry(r, 5)
+	}
+	return this
+}
+
+type randyLogEntry interface {
+	Float32() float32
+	Float64() float64
+	Int63() int64
+	Int31() int32
+	Uint32() uint32
+	Intn(n int) int
+}
+
+func randUTF8RuneLogEntry(r randyLogEntry) rune {
+	res := rune(r.Uint32() % 1112064)
+	if 55296 <= res {
+		res += 2047
+	}
+	return res
+}
+func randStringLogEntry(r randyLogEntry) string {
+	v5 := r.Intn(100)
+	tmps := make([]rune, v5)
+	for i := 0; i < v5; i++ {
+		tmps[i] = randUTF8RuneLogEntry(r)
+	}
+	return string(tmps)
+}
+func randUnrecognizedLogEntry(r randyLogEntry, maxFieldNumber int) (data []byte) {
+	l := r.Intn(5)
+	for i := 0; i < l; i++ {
+		wire := r.Intn(4)
+		if wire == 3 {
+			wire = 5
+		}
+		fieldNumber := maxFieldNumber + r.Intn(100)
+		data = randFieldLogEntry(data, r, fieldNumber, wire)
+	}
+	return data
+}
+func randFieldLogEntry(data []byte, r randyLogEntry, fieldNumber int, wire int) []byte {
+	key := uint32(fieldNumber)<<3 | uint32(wire)
+	switch wire {
+	case 0:
+		data = encodeVarintPopulateLogEntry(data, uint64(key))
+		data = encodeVarintPopulateLogEntry(data, uint64(r.Int63()))
+	case 1:
+		data = encodeVarintPopulateLogEntry(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	case 2:
+		data = encodeVarintPopulateLogEntry(data, uint64(key))
+		ll := r.Intn(100)
+		data = encodeVarintPopulateLogEntry(data, uint64(ll))
+		for j := 0; j < ll; j++ {
+			data = append(data, byte(r.Intn(256)))
+		}
+	default:
+		data = encodeVarintPopulateLogEntry(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	}
+	return data
+}
+func encodeVarintPopulateLogEntry(data []byte, v uint64) []byte {
+	for v >= 1<<7 {
+		data = append(data, uint8(uint64(v)&0x7f|0x80))
+		v >>= 7
+	}
+	data = append(data, uint8(v))
+	return data
+}
+func (m *LogEntry) Marshal() (data []byte, err error) {
+	size := m.Size()
+	data = make([]byte, size)
+	n, err := m.MarshalTo(data)
+	if err != nil {
+		return nil, err
+	}
+	return data[:n], nil
+}
+
+func (m *LogEntry) MarshalTo(data []byte) (n int, err error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Index != nil {
+		data[i] = 0x8
+		i++
+		i = encodeVarintLogEntry(data, i, uint64(*m.Index))
+	}
+	if m.Term != nil {
+		data[i] = 0x10
+		i++
+		i = encodeVarintLogEntry(data, i, uint64(*m.Term))
+	}
+	if m.CommandName != nil {
+		data[i] = 0x1a
+		i++
+		i = encodeVarintLogEntry(data, i, uint64(len(*m.CommandName)))
+		i += copy(data[i:], *m.CommandName)
+	}
+	if m.Command != nil {
+		data[i] = 0x22
+		i++
+		i = encodeVarintLogEntry(data, i, uint64(len(m.Command)))
+		i += copy(data[i:], m.Command)
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(data[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+func encodeFixed64LogEntry(data []byte, offset int, v uint64) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	data[offset+4] = uint8(v >> 32)
+	data[offset+5] = uint8(v >> 40)
+	data[offset+6] = uint8(v >> 48)
+	data[offset+7] = uint8(v >> 56)
+	return offset + 8
+}
+func encodeFixed32LogEntry(data []byte, offset int, v uint32) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	return offset + 4
+}
+func encodeVarintLogEntry(data []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		data[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	data[offset] = uint8(v)
+	return offset + 1
+}
+func (this *LogEntry) GoString() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings1.Join([]string{`&protobuf.LogEntry{` + `Index:` + valueToGoStringLogEntry(this.Index, "uint64"), `Term:` + valueToGoStringLogEntry(this.Term, "uint64"), `CommandName:` + valueToGoStringLogEntry(this.CommandName, "string"), `Command:` + valueToGoStringLogEntry(this.Command, "byte"), `XXX_unrecognized:` + fmt1.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
+	return s
+}
+func valueToGoStringLogEntry(v interface{}, typ string) string {
+	rv := reflect1.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect1.Indirect(rv).Interface()
+	return fmt1.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
+}
+func extensionToGoStringLogEntry(e map[int32]code_google_com_p_gogoprotobuf_proto1.Extension) string {
+	if e == nil {
+		return "nil"
+	}
+	s := "map[int32]proto.Extension{"
+	keys := make([]int, 0, len(e))
+	for k := range e {
+		keys = append(keys, int(k))
+	}
+	sort.Ints(keys)
+	ss := []string{}
+	for _, k := range keys {
+		ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString())
+	}
+	s += strings1.Join(ss, ",") + "}"
+	return s
+}
+func (this *LogEntry) VerboseEqual(that interface{}) error {
+	if that == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt2.Errorf("that == nil && this != nil")
+	}
+
+	that1, ok := that.(*LogEntry)
+	if !ok {
+		return fmt2.Errorf("that is not of type *LogEntry")
+	}
+	if that1 == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt2.Errorf("that is type *LogEntry but is nil && this != nil")
+	} else if this == nil {
+		return fmt2.Errorf("that is type *LogEntrybut is not nil && this == nil")
+	}
+	if this.Index != nil && that1.Index != nil {
+		if *this.Index != *that1.Index {
+			return fmt2.Errorf("Index this(%v) Not Equal that(%v)", *this.Index, *that1.Index)
+		}
+	} else if this.Index != nil {
+		return fmt2.Errorf("this.Index == nil && that.Index != nil")
+	} else if that1.Index != nil {
+		return fmt2.Errorf("Index this(%v) Not Equal that(%v)", this.Index, that1.Index)
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return fmt2.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
+		}
+	} else if this.Term != nil {
+		return fmt2.Errorf("this.Term == nil && that.Term != nil")
+	} else if that1.Term != nil {
+		return fmt2.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
+	}
+	if this.CommandName != nil && that1.CommandName != nil {
+		if *this.CommandName != *that1.CommandName {
+			return fmt2.Errorf("CommandName this(%v) Not Equal that(%v)", *this.CommandName, *that1.CommandName)
+		}
+	} else if this.CommandName != nil {
+		return fmt2.Errorf("this.CommandName == nil && that.CommandName != nil")
+	} else if that1.CommandName != nil {
+		return fmt2.Errorf("CommandName this(%v) Not Equal that(%v)", this.CommandName, that1.CommandName)
+	}
+	if !bytes.Equal(this.Command, that1.Command) {
+		return fmt2.Errorf("Command this(%v) Not Equal that(%v)", this.Command, that1.Command)
+	}
+	if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return fmt2.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
+	}
+	return nil
+}
+func (this *LogEntry) Equal(that interface{}) bool {
+	if that == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	}
+
+	that1, ok := that.(*LogEntry)
+	if !ok {
+		return false
+	}
+	if that1 == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	} else if this == nil {
+		return false
+	}
+	if this.Index != nil && that1.Index != nil {
+		if *this.Index != *that1.Index {
+			return false
+		}
+	} else if this.Index != nil {
+		return false
+	} else if that1.Index != nil {
+		return false
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return false
+		}
+	} else if this.Term != nil {
+		return false
+	} else if that1.Term != nil {
+		return false
+	}
+	if this.CommandName != nil && that1.CommandName != nil {
+		if *this.CommandName != *that1.CommandName {
+			return false
+		}
+	} else if this.CommandName != nil {
+		return false
+	} else if that1.CommandName != nil {
+		return false
+	}
+	if !bytes.Equal(this.Command, that1.Command) {
+		return false
+	}
+	if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return false
+	}
+	return true
+}

+ 15 - 1
third_party/github.com/coreos/raft/protobuf/log_entry.proto

@@ -1,6 +1,20 @@
 package protobuf;
 
-message ProtoLogEntry {
+import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
+
+option (gogoproto.gostring_all) = true;
+option (gogoproto.equal_all) = true;
+option (gogoproto.verbose_equal_all) = true;
+option (gogoproto.goproto_stringer_all) = false;
+option (gogoproto.stringer_all) =  true;
+option (gogoproto.populate_all) = true;
+option (gogoproto.testgen_all) = true;
+option (gogoproto.benchgen_all) = true;
+option (gogoproto.marshaler_all) = true;
+option (gogoproto.sizer_all) = true;
+option (gogoproto.unmarshaler_all) = true;
+
+message LogEntry {
 	required uint64 Index=1;
 	required uint64 Term=2;
 	required string CommandName=3;

+ 503 - 10
third_party/github.com/coreos/raft/protobuf/request_vote_request.pb.go

@@ -1,19 +1,38 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-gogo.
 // source: request_vote_request.proto
 // DO NOT EDIT!
 
 package protobuf
 
-import proto "github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
+import proto "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
 import json "encoding/json"
 import math "math"
 
+// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
+
+import io3 "io"
+import code_google_com_p_gogoprotobuf_proto6 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+
+import fmt9 "fmt"
+import strings6 "strings"
+import reflect6 "reflect"
+
+import fmt10 "fmt"
+import strings7 "strings"
+import code_google_com_p_gogoprotobuf_proto7 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+import sort3 "sort"
+import strconv3 "strconv"
+import reflect7 "reflect"
+
+import fmt11 "fmt"
+import bytes3 "bytes"
+
 // Reference proto, json, and math imports to suppress error if they are not otherwise used.
 var _ = proto.Marshal
 var _ = &json.SyntaxError{}
 var _ = math.Inf
 
-type ProtoRequestVoteRequest struct {
+type RequestVoteRequest struct {
 	Term			*uint64	`protobuf:"varint,1,req" json:"Term,omitempty"`
 	LastLogIndex		*uint64	`protobuf:"varint,2,req" json:"LastLogIndex,omitempty"`
 	LastLogTerm		*uint64	`protobuf:"varint,3,req" json:"LastLogTerm,omitempty"`
@@ -21,32 +40,31 @@ type ProtoRequestVoteRequest struct {
 	XXX_unrecognized	[]byte	`json:"-"`
 }
 
-func (m *ProtoRequestVoteRequest) Reset()		{ *m = ProtoRequestVoteRequest{} }
-func (m *ProtoRequestVoteRequest) String() string	{ return proto.CompactTextString(m) }
-func (*ProtoRequestVoteRequest) ProtoMessage()		{}
+func (m *RequestVoteRequest) Reset()		{ *m = RequestVoteRequest{} }
+func (*RequestVoteRequest) ProtoMessage()	{}
 
-func (m *ProtoRequestVoteRequest) GetTerm() uint64 {
+func (m *RequestVoteRequest) GetTerm() uint64 {
 	if m != nil && m.Term != nil {
 		return *m.Term
 	}
 	return 0
 }
 
-func (m *ProtoRequestVoteRequest) GetLastLogIndex() uint64 {
+func (m *RequestVoteRequest) GetLastLogIndex() uint64 {
 	if m != nil && m.LastLogIndex != nil {
 		return *m.LastLogIndex
 	}
 	return 0
 }
 
-func (m *ProtoRequestVoteRequest) GetLastLogTerm() uint64 {
+func (m *RequestVoteRequest) GetLastLogTerm() uint64 {
 	if m != nil && m.LastLogTerm != nil {
 		return *m.LastLogTerm
 	}
 	return 0
 }
 
-func (m *ProtoRequestVoteRequest) GetCandidateName() string {
+func (m *RequestVoteRequest) GetCandidateName() string {
 	if m != nil && m.CandidateName != nil {
 		return *m.CandidateName
 	}
@@ -55,3 +73,478 @@ func (m *ProtoRequestVoteRequest) GetCandidateName() string {
 
 func init() {
 }
+func (m *RequestVoteRequest) Unmarshal(data []byte) error {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return io3.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io3.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Term = &v
+		case 2:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io3.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.LastLogIndex = &v
+		case 3:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io3.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.LastLogTerm = &v
+		case 4:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io3.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + int(stringLen)
+			if postIndex > l {
+				return io3.ErrUnexpectedEOF
+			}
+			s := string(data[index:postIndex])
+			m.CandidateName = &s
+			index = postIndex
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			index -= sizeOfWire
+			skippy, err := code_google_com_p_gogoprotobuf_proto6.Skip(data[index:])
+			if err != nil {
+				return err
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
+			index += skippy
+		}
+	}
+	return nil
+}
+func (this *RequestVoteRequest) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings6.Join([]string{`&RequestVoteRequest{`,
+		`Term:` + valueToStringRequestVoteRequest(this.Term) + `,`,
+		`LastLogIndex:` + valueToStringRequestVoteRequest(this.LastLogIndex) + `,`,
+		`LastLogTerm:` + valueToStringRequestVoteRequest(this.LastLogTerm) + `,`,
+		`CandidateName:` + valueToStringRequestVoteRequest(this.CandidateName) + `,`,
+		`XXX_unrecognized:` + fmt9.Sprintf("%v", this.XXX_unrecognized) + `,`,
+		`}`,
+	}, "")
+	return s
+}
+func valueToStringRequestVoteRequest(v interface{}) string {
+	rv := reflect6.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect6.Indirect(rv).Interface()
+	return fmt9.Sprintf("*%v", pv)
+}
+func (m *RequestVoteRequest) Size() (n int) {
+	var l int
+	_ = l
+	if m.Term != nil {
+		n += 1 + sovRequestVoteRequest(uint64(*m.Term))
+	}
+	if m.LastLogIndex != nil {
+		n += 1 + sovRequestVoteRequest(uint64(*m.LastLogIndex))
+	}
+	if m.LastLogTerm != nil {
+		n += 1 + sovRequestVoteRequest(uint64(*m.LastLogTerm))
+	}
+	if m.CandidateName != nil {
+		l = len(*m.CandidateName)
+		n += 1 + l + sovRequestVoteRequest(uint64(l))
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func sovRequestVoteRequest(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozRequestVoteRequest(x uint64) (n int) {
+	return sovRequestVoteRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+	return sovRequestVoteRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func NewPopulatedRequestVoteRequest(r randyRequestVoteRequest, easy bool) *RequestVoteRequest {
+	this := &RequestVoteRequest{}
+	v1 := uint64(r.Uint32())
+	this.Term = &v1
+	v2 := uint64(r.Uint32())
+	this.LastLogIndex = &v2
+	v3 := uint64(r.Uint32())
+	this.LastLogTerm = &v3
+	v4 := randStringRequestVoteRequest(r)
+	this.CandidateName = &v4
+	if !easy && r.Intn(10) != 0 {
+		this.XXX_unrecognized = randUnrecognizedRequestVoteRequest(r, 5)
+	}
+	return this
+}
+
+type randyRequestVoteRequest interface {
+	Float32() float32
+	Float64() float64
+	Int63() int64
+	Int31() int32
+	Uint32() uint32
+	Intn(n int) int
+}
+
+func randUTF8RuneRequestVoteRequest(r randyRequestVoteRequest) rune {
+	res := rune(r.Uint32() % 1112064)
+	if 55296 <= res {
+		res += 2047
+	}
+	return res
+}
+func randStringRequestVoteRequest(r randyRequestVoteRequest) string {
+	v5 := r.Intn(100)
+	tmps := make([]rune, v5)
+	for i := 0; i < v5; i++ {
+		tmps[i] = randUTF8RuneRequestVoteRequest(r)
+	}
+	return string(tmps)
+}
+func randUnrecognizedRequestVoteRequest(r randyRequestVoteRequest, maxFieldNumber int) (data []byte) {
+	l := r.Intn(5)
+	for i := 0; i < l; i++ {
+		wire := r.Intn(4)
+		if wire == 3 {
+			wire = 5
+		}
+		fieldNumber := maxFieldNumber + r.Intn(100)
+		data = randFieldRequestVoteRequest(data, r, fieldNumber, wire)
+	}
+	return data
+}
+func randFieldRequestVoteRequest(data []byte, r randyRequestVoteRequest, fieldNumber int, wire int) []byte {
+	key := uint32(fieldNumber)<<3 | uint32(wire)
+	switch wire {
+	case 0:
+		data = encodeVarintPopulateRequestVoteRequest(data, uint64(key))
+		data = encodeVarintPopulateRequestVoteRequest(data, uint64(r.Int63()))
+	case 1:
+		data = encodeVarintPopulateRequestVoteRequest(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	case 2:
+		data = encodeVarintPopulateRequestVoteRequest(data, uint64(key))
+		ll := r.Intn(100)
+		data = encodeVarintPopulateRequestVoteRequest(data, uint64(ll))
+		for j := 0; j < ll; j++ {
+			data = append(data, byte(r.Intn(256)))
+		}
+	default:
+		data = encodeVarintPopulateRequestVoteRequest(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	}
+	return data
+}
+func encodeVarintPopulateRequestVoteRequest(data []byte, v uint64) []byte {
+	for v >= 1<<7 {
+		data = append(data, uint8(uint64(v)&0x7f|0x80))
+		v >>= 7
+	}
+	data = append(data, uint8(v))
+	return data
+}
+func (m *RequestVoteRequest) Marshal() (data []byte, err error) {
+	size := m.Size()
+	data = make([]byte, size)
+	n, err := m.MarshalTo(data)
+	if err != nil {
+		return nil, err
+	}
+	return data[:n], nil
+}
+
+func (m *RequestVoteRequest) MarshalTo(data []byte) (n int, err error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Term != nil {
+		data[i] = 0x8
+		i++
+		i = encodeVarintRequestVoteRequest(data, i, uint64(*m.Term))
+	}
+	if m.LastLogIndex != nil {
+		data[i] = 0x10
+		i++
+		i = encodeVarintRequestVoteRequest(data, i, uint64(*m.LastLogIndex))
+	}
+	if m.LastLogTerm != nil {
+		data[i] = 0x18
+		i++
+		i = encodeVarintRequestVoteRequest(data, i, uint64(*m.LastLogTerm))
+	}
+	if m.CandidateName != nil {
+		data[i] = 0x22
+		i++
+		i = encodeVarintRequestVoteRequest(data, i, uint64(len(*m.CandidateName)))
+		i += copy(data[i:], *m.CandidateName)
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(data[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+func encodeFixed64RequestVoteRequest(data []byte, offset int, v uint64) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	data[offset+4] = uint8(v >> 32)
+	data[offset+5] = uint8(v >> 40)
+	data[offset+6] = uint8(v >> 48)
+	data[offset+7] = uint8(v >> 56)
+	return offset + 8
+}
+func encodeFixed32RequestVoteRequest(data []byte, offset int, v uint32) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	return offset + 4
+}
+func encodeVarintRequestVoteRequest(data []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		data[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	data[offset] = uint8(v)
+	return offset + 1
+}
+func (this *RequestVoteRequest) GoString() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings7.Join([]string{`&protobuf.RequestVoteRequest{` + `Term:` + valueToGoStringRequestVoteRequest(this.Term, "uint64"), `LastLogIndex:` + valueToGoStringRequestVoteRequest(this.LastLogIndex, "uint64"), `LastLogTerm:` + valueToGoStringRequestVoteRequest(this.LastLogTerm, "uint64"), `CandidateName:` + valueToGoStringRequestVoteRequest(this.CandidateName, "string"), `XXX_unrecognized:` + fmt10.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
+	return s
+}
+func valueToGoStringRequestVoteRequest(v interface{}, typ string) string {
+	rv := reflect7.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect7.Indirect(rv).Interface()
+	return fmt10.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
+}
+func extensionToGoStringRequestVoteRequest(e map[int32]code_google_com_p_gogoprotobuf_proto7.Extension) string {
+	if e == nil {
+		return "nil"
+	}
+	s := "map[int32]proto.Extension{"
+	keys := make([]int, 0, len(e))
+	for k := range e {
+		keys = append(keys, int(k))
+	}
+	sort3.Ints(keys)
+	ss := []string{}
+	for _, k := range keys {
+		ss = append(ss, strconv3.Itoa(k)+": "+e[int32(k)].GoString())
+	}
+	s += strings7.Join(ss, ",") + "}"
+	return s
+}
+func (this *RequestVoteRequest) VerboseEqual(that interface{}) error {
+	if that == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt11.Errorf("that == nil && this != nil")
+	}
+
+	that1, ok := that.(*RequestVoteRequest)
+	if !ok {
+		return fmt11.Errorf("that is not of type *RequestVoteRequest")
+	}
+	if that1 == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt11.Errorf("that is type *RequestVoteRequest but is nil && this != nil")
+	} else if this == nil {
+		return fmt11.Errorf("that is type *RequestVoteRequestbut is not nil && this == nil")
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return fmt11.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
+		}
+	} else if this.Term != nil {
+		return fmt11.Errorf("this.Term == nil && that.Term != nil")
+	} else if that1.Term != nil {
+		return fmt11.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
+	}
+	if this.LastLogIndex != nil && that1.LastLogIndex != nil {
+		if *this.LastLogIndex != *that1.LastLogIndex {
+			return fmt11.Errorf("LastLogIndex this(%v) Not Equal that(%v)", *this.LastLogIndex, *that1.LastLogIndex)
+		}
+	} else if this.LastLogIndex != nil {
+		return fmt11.Errorf("this.LastLogIndex == nil && that.LastLogIndex != nil")
+	} else if that1.LastLogIndex != nil {
+		return fmt11.Errorf("LastLogIndex this(%v) Not Equal that(%v)", this.LastLogIndex, that1.LastLogIndex)
+	}
+	if this.LastLogTerm != nil && that1.LastLogTerm != nil {
+		if *this.LastLogTerm != *that1.LastLogTerm {
+			return fmt11.Errorf("LastLogTerm this(%v) Not Equal that(%v)", *this.LastLogTerm, *that1.LastLogTerm)
+		}
+	} else if this.LastLogTerm != nil {
+		return fmt11.Errorf("this.LastLogTerm == nil && that.LastLogTerm != nil")
+	} else if that1.LastLogTerm != nil {
+		return fmt11.Errorf("LastLogTerm this(%v) Not Equal that(%v)", this.LastLogTerm, that1.LastLogTerm)
+	}
+	if this.CandidateName != nil && that1.CandidateName != nil {
+		if *this.CandidateName != *that1.CandidateName {
+			return fmt11.Errorf("CandidateName this(%v) Not Equal that(%v)", *this.CandidateName, *that1.CandidateName)
+		}
+	} else if this.CandidateName != nil {
+		return fmt11.Errorf("this.CandidateName == nil && that.CandidateName != nil")
+	} else if that1.CandidateName != nil {
+		return fmt11.Errorf("CandidateName this(%v) Not Equal that(%v)", this.CandidateName, that1.CandidateName)
+	}
+	if !bytes3.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return fmt11.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
+	}
+	return nil
+}
+func (this *RequestVoteRequest) Equal(that interface{}) bool {
+	if that == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	}
+
+	that1, ok := that.(*RequestVoteRequest)
+	if !ok {
+		return false
+	}
+	if that1 == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	} else if this == nil {
+		return false
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return false
+		}
+	} else if this.Term != nil {
+		return false
+	} else if that1.Term != nil {
+		return false
+	}
+	if this.LastLogIndex != nil && that1.LastLogIndex != nil {
+		if *this.LastLogIndex != *that1.LastLogIndex {
+			return false
+		}
+	} else if this.LastLogIndex != nil {
+		return false
+	} else if that1.LastLogIndex != nil {
+		return false
+	}
+	if this.LastLogTerm != nil && that1.LastLogTerm != nil {
+		if *this.LastLogTerm != *that1.LastLogTerm {
+			return false
+		}
+	} else if this.LastLogTerm != nil {
+		return false
+	} else if that1.LastLogTerm != nil {
+		return false
+	}
+	if this.CandidateName != nil && that1.CandidateName != nil {
+		if *this.CandidateName != *that1.CandidateName {
+			return false
+		}
+	} else if this.CandidateName != nil {
+		return false
+	} else if that1.CandidateName != nil {
+		return false
+	}
+	if !bytes3.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return false
+	}
+	return true
+}

+ 15 - 1
third_party/github.com/coreos/raft/protobuf/request_vote_request.proto

@@ -1,6 +1,20 @@
 package protobuf;
 
-message ProtoRequestVoteRequest {
+import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
+
+option (gogoproto.gostring_all) = true;
+option (gogoproto.equal_all) = true;
+option (gogoproto.verbose_equal_all) = true;
+option (gogoproto.goproto_stringer_all) = false;
+option (gogoproto.stringer_all) =  true;
+option (gogoproto.populate_all) = true;
+option (gogoproto.testgen_all) = true;
+option (gogoproto.benchgen_all) = true;
+option (gogoproto.marshaler_all) = true;
+option (gogoproto.sizer_all) = true;
+option (gogoproto.unmarshaler_all) = true;
+
+message RequestVoteRequest {
 	required uint64 Term=1;
 	required uint64 LastLogIndex=2;
 	required uint64 LastLogTerm=3;

+ 407 - 8
third_party/github.com/coreos/raft/protobuf/request_vote_responses.pb.go

@@ -1,36 +1,54 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-gogo.
 // source: request_vote_responses.proto
 // DO NOT EDIT!
 
 package protobuf
 
-import proto "github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
+import proto "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
 import json "encoding/json"
 import math "math"
 
+// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
+
+import io4 "io"
+import code_google_com_p_gogoprotobuf_proto8 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+
+import fmt12 "fmt"
+import strings8 "strings"
+import reflect8 "reflect"
+
+import fmt13 "fmt"
+import strings9 "strings"
+import code_google_com_p_gogoprotobuf_proto9 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+import sort4 "sort"
+import strconv4 "strconv"
+import reflect9 "reflect"
+
+import fmt14 "fmt"
+import bytes4 "bytes"
+
 // Reference proto, json, and math imports to suppress error if they are not otherwise used.
 var _ = proto.Marshal
 var _ = &json.SyntaxError{}
 var _ = math.Inf
 
-type ProtoRequestVoteResponse struct {
+type RequestVoteResponse struct {
 	Term			*uint64	`protobuf:"varint,1,req" json:"Term,omitempty"`
 	VoteGranted		*bool	`protobuf:"varint,2,req" json:"VoteGranted,omitempty"`
 	XXX_unrecognized	[]byte	`json:"-"`
 }
 
-func (m *ProtoRequestVoteResponse) Reset()		{ *m = ProtoRequestVoteResponse{} }
-func (m *ProtoRequestVoteResponse) String() string	{ return proto.CompactTextString(m) }
-func (*ProtoRequestVoteResponse) ProtoMessage()		{}
+func (m *RequestVoteResponse) Reset()		{ *m = RequestVoteResponse{} }
+func (*RequestVoteResponse) ProtoMessage()	{}
 
-func (m *ProtoRequestVoteResponse) GetTerm() uint64 {
+func (m *RequestVoteResponse) GetTerm() uint64 {
 	if m != nil && m.Term != nil {
 		return *m.Term
 	}
 	return 0
 }
 
-func (m *ProtoRequestVoteResponse) GetVoteGranted() bool {
+func (m *RequestVoteResponse) GetVoteGranted() bool {
 	if m != nil && m.VoteGranted != nil {
 		return *m.VoteGranted
 	}
@@ -39,3 +57,384 @@ func (m *ProtoRequestVoteResponse) GetVoteGranted() bool {
 
 func init() {
 }
+func (m *RequestVoteResponse) Unmarshal(data []byte) error {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return io4.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io4.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Term = &v
+		case 2:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io4.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			b := bool(v != 0)
+			m.VoteGranted = &b
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			index -= sizeOfWire
+			skippy, err := code_google_com_p_gogoprotobuf_proto8.Skip(data[index:])
+			if err != nil {
+				return err
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
+			index += skippy
+		}
+	}
+	return nil
+}
+func (this *RequestVoteResponse) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings8.Join([]string{`&RequestVoteResponse{`,
+		`Term:` + valueToStringRequestVoteResponses(this.Term) + `,`,
+		`VoteGranted:` + valueToStringRequestVoteResponses(this.VoteGranted) + `,`,
+		`XXX_unrecognized:` + fmt12.Sprintf("%v", this.XXX_unrecognized) + `,`,
+		`}`,
+	}, "")
+	return s
+}
+func valueToStringRequestVoteResponses(v interface{}) string {
+	rv := reflect8.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect8.Indirect(rv).Interface()
+	return fmt12.Sprintf("*%v", pv)
+}
+func (m *RequestVoteResponse) Size() (n int) {
+	var l int
+	_ = l
+	if m.Term != nil {
+		n += 1 + sovRequestVoteResponses(uint64(*m.Term))
+	}
+	if m.VoteGranted != nil {
+		n += 2
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func sovRequestVoteResponses(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozRequestVoteResponses(x uint64) (n int) {
+	return sovRequestVoteResponses(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+	return sovRequestVoteResponses(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func NewPopulatedRequestVoteResponse(r randyRequestVoteResponses, easy bool) *RequestVoteResponse {
+	this := &RequestVoteResponse{}
+	v1 := uint64(r.Uint32())
+	this.Term = &v1
+	v2 := bool(r.Intn(2) == 0)
+	this.VoteGranted = &v2
+	if !easy && r.Intn(10) != 0 {
+		this.XXX_unrecognized = randUnrecognizedRequestVoteResponses(r, 3)
+	}
+	return this
+}
+
+type randyRequestVoteResponses interface {
+	Float32() float32
+	Float64() float64
+	Int63() int64
+	Int31() int32
+	Uint32() uint32
+	Intn(n int) int
+}
+
+func randUTF8RuneRequestVoteResponses(r randyRequestVoteResponses) rune {
+	res := rune(r.Uint32() % 1112064)
+	if 55296 <= res {
+		res += 2047
+	}
+	return res
+}
+func randStringRequestVoteResponses(r randyRequestVoteResponses) string {
+	v3 := r.Intn(100)
+	tmps := make([]rune, v3)
+	for i := 0; i < v3; i++ {
+		tmps[i] = randUTF8RuneRequestVoteResponses(r)
+	}
+	return string(tmps)
+}
+func randUnrecognizedRequestVoteResponses(r randyRequestVoteResponses, maxFieldNumber int) (data []byte) {
+	l := r.Intn(5)
+	for i := 0; i < l; i++ {
+		wire := r.Intn(4)
+		if wire == 3 {
+			wire = 5
+		}
+		fieldNumber := maxFieldNumber + r.Intn(100)
+		data = randFieldRequestVoteResponses(data, r, fieldNumber, wire)
+	}
+	return data
+}
+func randFieldRequestVoteResponses(data []byte, r randyRequestVoteResponses, fieldNumber int, wire int) []byte {
+	key := uint32(fieldNumber)<<3 | uint32(wire)
+	switch wire {
+	case 0:
+		data = encodeVarintPopulateRequestVoteResponses(data, uint64(key))
+		data = encodeVarintPopulateRequestVoteResponses(data, uint64(r.Int63()))
+	case 1:
+		data = encodeVarintPopulateRequestVoteResponses(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	case 2:
+		data = encodeVarintPopulateRequestVoteResponses(data, uint64(key))
+		ll := r.Intn(100)
+		data = encodeVarintPopulateRequestVoteResponses(data, uint64(ll))
+		for j := 0; j < ll; j++ {
+			data = append(data, byte(r.Intn(256)))
+		}
+	default:
+		data = encodeVarintPopulateRequestVoteResponses(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	}
+	return data
+}
+func encodeVarintPopulateRequestVoteResponses(data []byte, v uint64) []byte {
+	for v >= 1<<7 {
+		data = append(data, uint8(uint64(v)&0x7f|0x80))
+		v >>= 7
+	}
+	data = append(data, uint8(v))
+	return data
+}
+func (m *RequestVoteResponse) Marshal() (data []byte, err error) {
+	size := m.Size()
+	data = make([]byte, size)
+	n, err := m.MarshalTo(data)
+	if err != nil {
+		return nil, err
+	}
+	return data[:n], nil
+}
+
+func (m *RequestVoteResponse) MarshalTo(data []byte) (n int, err error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Term != nil {
+		data[i] = 0x8
+		i++
+		i = encodeVarintRequestVoteResponses(data, i, uint64(*m.Term))
+	}
+	if m.VoteGranted != nil {
+		data[i] = 0x10
+		i++
+		if *m.VoteGranted {
+			data[i] = 1
+		} else {
+			data[i] = 0
+		}
+		i++
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(data[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+func encodeFixed64RequestVoteResponses(data []byte, offset int, v uint64) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	data[offset+4] = uint8(v >> 32)
+	data[offset+5] = uint8(v >> 40)
+	data[offset+6] = uint8(v >> 48)
+	data[offset+7] = uint8(v >> 56)
+	return offset + 8
+}
+func encodeFixed32RequestVoteResponses(data []byte, offset int, v uint32) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	return offset + 4
+}
+func encodeVarintRequestVoteResponses(data []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		data[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	data[offset] = uint8(v)
+	return offset + 1
+}
+func (this *RequestVoteResponse) GoString() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings9.Join([]string{`&protobuf.RequestVoteResponse{` + `Term:` + valueToGoStringRequestVoteResponses(this.Term, "uint64"), `VoteGranted:` + valueToGoStringRequestVoteResponses(this.VoteGranted, "bool"), `XXX_unrecognized:` + fmt13.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
+	return s
+}
+func valueToGoStringRequestVoteResponses(v interface{}, typ string) string {
+	rv := reflect9.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect9.Indirect(rv).Interface()
+	return fmt13.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
+}
+func extensionToGoStringRequestVoteResponses(e map[int32]code_google_com_p_gogoprotobuf_proto9.Extension) string {
+	if e == nil {
+		return "nil"
+	}
+	s := "map[int32]proto.Extension{"
+	keys := make([]int, 0, len(e))
+	for k := range e {
+		keys = append(keys, int(k))
+	}
+	sort4.Ints(keys)
+	ss := []string{}
+	for _, k := range keys {
+		ss = append(ss, strconv4.Itoa(k)+": "+e[int32(k)].GoString())
+	}
+	s += strings9.Join(ss, ",") + "}"
+	return s
+}
+func (this *RequestVoteResponse) VerboseEqual(that interface{}) error {
+	if that == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt14.Errorf("that == nil && this != nil")
+	}
+
+	that1, ok := that.(*RequestVoteResponse)
+	if !ok {
+		return fmt14.Errorf("that is not of type *RequestVoteResponse")
+	}
+	if that1 == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt14.Errorf("that is type *RequestVoteResponse but is nil && this != nil")
+	} else if this == nil {
+		return fmt14.Errorf("that is type *RequestVoteResponsebut is not nil && this == nil")
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return fmt14.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
+		}
+	} else if this.Term != nil {
+		return fmt14.Errorf("this.Term == nil && that.Term != nil")
+	} else if that1.Term != nil {
+		return fmt14.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
+	}
+	if this.VoteGranted != nil && that1.VoteGranted != nil {
+		if *this.VoteGranted != *that1.VoteGranted {
+			return fmt14.Errorf("VoteGranted this(%v) Not Equal that(%v)", *this.VoteGranted, *that1.VoteGranted)
+		}
+	} else if this.VoteGranted != nil {
+		return fmt14.Errorf("this.VoteGranted == nil && that.VoteGranted != nil")
+	} else if that1.VoteGranted != nil {
+		return fmt14.Errorf("VoteGranted this(%v) Not Equal that(%v)", this.VoteGranted, that1.VoteGranted)
+	}
+	if !bytes4.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return fmt14.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
+	}
+	return nil
+}
+func (this *RequestVoteResponse) Equal(that interface{}) bool {
+	if that == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	}
+
+	that1, ok := that.(*RequestVoteResponse)
+	if !ok {
+		return false
+	}
+	if that1 == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	} else if this == nil {
+		return false
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return false
+		}
+	} else if this.Term != nil {
+		return false
+	} else if that1.Term != nil {
+		return false
+	}
+	if this.VoteGranted != nil && that1.VoteGranted != nil {
+		if *this.VoteGranted != *that1.VoteGranted {
+			return false
+		}
+	} else if this.VoteGranted != nil {
+		return false
+	} else if that1.VoteGranted != nil {
+		return false
+	}
+	if !bytes4.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return false
+	}
+	return true
+}

+ 15 - 1
third_party/github.com/coreos/raft/protobuf/request_vote_responses.proto

@@ -1,6 +1,20 @@
 package protobuf;
 
-message ProtoRequestVoteResponse {
+import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
+
+option (gogoproto.gostring_all) = true;
+option (gogoproto.equal_all) = true;
+option (gogoproto.verbose_equal_all) = true;
+option (gogoproto.goproto_stringer_all) = false;
+option (gogoproto.stringer_all) =  true;
+option (gogoproto.populate_all) = true;
+option (gogoproto.testgen_all) = true;
+option (gogoproto.benchgen_all) = true;
+option (gogoproto.marshaler_all) = true;
+option (gogoproto.sizer_all) = true;
+option (gogoproto.unmarshaler_all) = true;
+
+message RequestVoteResponse {
 	required uint64 Term=1;
 	required bool VoteGranted=2;
 }

+ 828 - 25
third_party/github.com/coreos/raft/protobuf/snapshot_recovery_request.pb.go

@@ -1,86 +1,101 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-gogo.
 // source: snapshot_recovery_request.proto
 // DO NOT EDIT!
 
 package protobuf
 
-import proto "github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
+import proto "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
 import json "encoding/json"
 import math "math"
 
+// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
+
+import io5 "io"
+import code_google_com_p_gogoprotobuf_proto10 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+
+import fmt15 "fmt"
+import strings10 "strings"
+import reflect10 "reflect"
+
+import fmt16 "fmt"
+import strings11 "strings"
+import code_google_com_p_gogoprotobuf_proto11 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+import sort5 "sort"
+import strconv5 "strconv"
+import reflect11 "reflect"
+
+import fmt17 "fmt"
+import bytes5 "bytes"
+
 // Reference proto, json, and math imports to suppress error if they are not otherwise used.
 var _ = proto.Marshal
 var _ = &json.SyntaxError{}
 var _ = math.Inf
 
-type ProtoSnapshotRecoveryRequest struct {
-	LeaderName		*string						`protobuf:"bytes,1,req" json:"LeaderName,omitempty"`
-	LastIndex		*uint64						`protobuf:"varint,2,req" json:"LastIndex,omitempty"`
-	LastTerm		*uint64						`protobuf:"varint,3,req" json:"LastTerm,omitempty"`
-	Peers			[]*ProtoSnapshotRecoveryRequest_ProtoPeer	`protobuf:"bytes,4,rep" json:"Peers,omitempty"`
-	State			[]byte						`protobuf:"bytes,5,req" json:"State,omitempty"`
-	XXX_unrecognized	[]byte						`json:"-"`
+type SnapshotRecoveryRequest struct {
+	LeaderName		*string				`protobuf:"bytes,1,req" json:"LeaderName,omitempty"`
+	LastIndex		*uint64				`protobuf:"varint,2,req" json:"LastIndex,omitempty"`
+	LastTerm		*uint64				`protobuf:"varint,3,req" json:"LastTerm,omitempty"`
+	Peers			[]*SnapshotRecoveryRequest_Peer	`protobuf:"bytes,4,rep" json:"Peers,omitempty"`
+	State			[]byte				`protobuf:"bytes,5,req" json:"State,omitempty"`
+	XXX_unrecognized	[]byte				`json:"-"`
 }
 
-func (m *ProtoSnapshotRecoveryRequest) Reset()		{ *m = ProtoSnapshotRecoveryRequest{} }
-func (m *ProtoSnapshotRecoveryRequest) String() string	{ return proto.CompactTextString(m) }
-func (*ProtoSnapshotRecoveryRequest) ProtoMessage()	{}
+func (m *SnapshotRecoveryRequest) Reset()	{ *m = SnapshotRecoveryRequest{} }
+func (*SnapshotRecoveryRequest) ProtoMessage()	{}
 
-func (m *ProtoSnapshotRecoveryRequest) GetLeaderName() string {
+func (m *SnapshotRecoveryRequest) GetLeaderName() string {
 	if m != nil && m.LeaderName != nil {
 		return *m.LeaderName
 	}
 	return ""
 }
 
-func (m *ProtoSnapshotRecoveryRequest) GetLastIndex() uint64 {
+func (m *SnapshotRecoveryRequest) GetLastIndex() uint64 {
 	if m != nil && m.LastIndex != nil {
 		return *m.LastIndex
 	}
 	return 0
 }
 
-func (m *ProtoSnapshotRecoveryRequest) GetLastTerm() uint64 {
+func (m *SnapshotRecoveryRequest) GetLastTerm() uint64 {
 	if m != nil && m.LastTerm != nil {
 		return *m.LastTerm
 	}
 	return 0
 }
 
-func (m *ProtoSnapshotRecoveryRequest) GetPeers() []*ProtoSnapshotRecoveryRequest_ProtoPeer {
+func (m *SnapshotRecoveryRequest) GetPeers() []*SnapshotRecoveryRequest_Peer {
 	if m != nil {
 		return m.Peers
 	}
 	return nil
 }
 
-func (m *ProtoSnapshotRecoveryRequest) GetState() []byte {
+func (m *SnapshotRecoveryRequest) GetState() []byte {
 	if m != nil {
 		return m.State
 	}
 	return nil
 }
 
-type ProtoSnapshotRecoveryRequest_ProtoPeer struct {
+type SnapshotRecoveryRequest_Peer struct {
 	Name			*string	`protobuf:"bytes,1,req" json:"Name,omitempty"`
 	ConnectionString	*string	`protobuf:"bytes,2,req" json:"ConnectionString,omitempty"`
 	XXX_unrecognized	[]byte	`json:"-"`
 }
 
-func (m *ProtoSnapshotRecoveryRequest_ProtoPeer) Reset() {
-	*m = ProtoSnapshotRecoveryRequest_ProtoPeer{}
-}
-func (m *ProtoSnapshotRecoveryRequest_ProtoPeer) String() string	{ return proto.CompactTextString(m) }
-func (*ProtoSnapshotRecoveryRequest_ProtoPeer) ProtoMessage()		{}
+func (m *SnapshotRecoveryRequest_Peer) Reset()		{ *m = SnapshotRecoveryRequest_Peer{} }
+func (*SnapshotRecoveryRequest_Peer) ProtoMessage()	{}
 
-func (m *ProtoSnapshotRecoveryRequest_ProtoPeer) GetName() string {
+func (m *SnapshotRecoveryRequest_Peer) GetName() string {
 	if m != nil && m.Name != nil {
 		return *m.Name
 	}
 	return ""
 }
 
-func (m *ProtoSnapshotRecoveryRequest_ProtoPeer) GetConnectionString() string {
+func (m *SnapshotRecoveryRequest_Peer) GetConnectionString() string {
 	if m != nil && m.ConnectionString != nil {
 		return *m.ConnectionString
 	}
@@ -89,3 +104,791 @@ func (m *ProtoSnapshotRecoveryRequest_ProtoPeer) GetConnectionString() string {
 
 func init() {
 }
+func (m *SnapshotRecoveryRequest) Unmarshal(data []byte) error {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return io5.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io5.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + int(stringLen)
+			if postIndex > l {
+				return io5.ErrUnexpectedEOF
+			}
+			s := string(data[index:postIndex])
+			m.LeaderName = &s
+			index = postIndex
+		case 2:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io5.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.LastIndex = &v
+		case 3:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io5.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.LastTerm = &v
+		case 4:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io5.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + msglen
+			if postIndex > l {
+				return io5.ErrUnexpectedEOF
+			}
+			m.Peers = append(m.Peers, &SnapshotRecoveryRequest_Peer{})
+			m.Peers[len(m.Peers)-1].Unmarshal(data[index:postIndex])
+			index = postIndex
+		case 5:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io5.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + byteLen
+			if postIndex > l {
+				return io5.ErrUnexpectedEOF
+			}
+			m.State = append(m.State, data[index:postIndex]...)
+			index = postIndex
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			index -= sizeOfWire
+			skippy, err := code_google_com_p_gogoprotobuf_proto10.Skip(data[index:])
+			if err != nil {
+				return err
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
+			index += skippy
+		}
+	}
+	return nil
+}
+func (m *SnapshotRecoveryRequest_Peer) Unmarshal(data []byte) error {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return io5.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io5.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + int(stringLen)
+			if postIndex > l {
+				return io5.ErrUnexpectedEOF
+			}
+			s := string(data[index:postIndex])
+			m.Name = &s
+			index = postIndex
+		case 2:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io5.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + int(stringLen)
+			if postIndex > l {
+				return io5.ErrUnexpectedEOF
+			}
+			s := string(data[index:postIndex])
+			m.ConnectionString = &s
+			index = postIndex
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			index -= sizeOfWire
+			skippy, err := code_google_com_p_gogoprotobuf_proto10.Skip(data[index:])
+			if err != nil {
+				return err
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
+			index += skippy
+		}
+	}
+	return nil
+}
+func (this *SnapshotRecoveryRequest) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings10.Join([]string{`&SnapshotRecoveryRequest{`,
+		`LeaderName:` + valueToStringSnapshotRecoveryRequest(this.LeaderName) + `,`,
+		`LastIndex:` + valueToStringSnapshotRecoveryRequest(this.LastIndex) + `,`,
+		`LastTerm:` + valueToStringSnapshotRecoveryRequest(this.LastTerm) + `,`,
+		`Peers:` + strings10.Replace(fmt15.Sprintf("%v", this.Peers), "SnapshotRecoveryRequest_Peer", "SnapshotRecoveryRequest_Peer", 1) + `,`,
+		`State:` + valueToStringSnapshotRecoveryRequest(this.State) + `,`,
+		`XXX_unrecognized:` + fmt15.Sprintf("%v", this.XXX_unrecognized) + `,`,
+		`}`,
+	}, "")
+	return s
+}
+func (this *SnapshotRecoveryRequest_Peer) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings10.Join([]string{`&SnapshotRecoveryRequest_Peer{`,
+		`Name:` + valueToStringSnapshotRecoveryRequest(this.Name) + `,`,
+		`ConnectionString:` + valueToStringSnapshotRecoveryRequest(this.ConnectionString) + `,`,
+		`XXX_unrecognized:` + fmt15.Sprintf("%v", this.XXX_unrecognized) + `,`,
+		`}`,
+	}, "")
+	return s
+}
+func valueToStringSnapshotRecoveryRequest(v interface{}) string {
+	rv := reflect10.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect10.Indirect(rv).Interface()
+	return fmt15.Sprintf("*%v", pv)
+}
+func (m *SnapshotRecoveryRequest) Size() (n int) {
+	var l int
+	_ = l
+	if m.LeaderName != nil {
+		l = len(*m.LeaderName)
+		n += 1 + l + sovSnapshotRecoveryRequest(uint64(l))
+	}
+	if m.LastIndex != nil {
+		n += 1 + sovSnapshotRecoveryRequest(uint64(*m.LastIndex))
+	}
+	if m.LastTerm != nil {
+		n += 1 + sovSnapshotRecoveryRequest(uint64(*m.LastTerm))
+	}
+	if len(m.Peers) > 0 {
+		for _, e := range m.Peers {
+			l = e.Size()
+			n += 1 + l + sovSnapshotRecoveryRequest(uint64(l))
+		}
+	}
+	if m.State != nil {
+		l = len(m.State)
+		n += 1 + l + sovSnapshotRecoveryRequest(uint64(l))
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+func (m *SnapshotRecoveryRequest_Peer) Size() (n int) {
+	var l int
+	_ = l
+	if m.Name != nil {
+		l = len(*m.Name)
+		n += 1 + l + sovSnapshotRecoveryRequest(uint64(l))
+	}
+	if m.ConnectionString != nil {
+		l = len(*m.ConnectionString)
+		n += 1 + l + sovSnapshotRecoveryRequest(uint64(l))
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func sovSnapshotRecoveryRequest(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozSnapshotRecoveryRequest(x uint64) (n int) {
+	return sovSnapshotRecoveryRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+	return sovSnapshotRecoveryRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func NewPopulatedSnapshotRecoveryRequest(r randySnapshotRecoveryRequest, easy bool) *SnapshotRecoveryRequest {
+	this := &SnapshotRecoveryRequest{}
+	v1 := randStringSnapshotRecoveryRequest(r)
+	this.LeaderName = &v1
+	v2 := uint64(r.Uint32())
+	this.LastIndex = &v2
+	v3 := uint64(r.Uint32())
+	this.LastTerm = &v3
+	if r.Intn(10) != 0 {
+		v4 := r.Intn(10)
+		this.Peers = make([]*SnapshotRecoveryRequest_Peer, v4)
+		for i := 0; i < v4; i++ {
+			this.Peers[i] = NewPopulatedSnapshotRecoveryRequest_Peer(r, easy)
+		}
+	}
+	v5 := r.Intn(100)
+	this.State = make([]byte, v5)
+	for i := 0; i < v5; i++ {
+		this.State[i] = byte(r.Intn(256))
+	}
+	if !easy && r.Intn(10) != 0 {
+		this.XXX_unrecognized = randUnrecognizedSnapshotRecoveryRequest(r, 6)
+	}
+	return this
+}
+
+func NewPopulatedSnapshotRecoveryRequest_Peer(r randySnapshotRecoveryRequest, easy bool) *SnapshotRecoveryRequest_Peer {
+	this := &SnapshotRecoveryRequest_Peer{}
+	v6 := randStringSnapshotRecoveryRequest(r)
+	this.Name = &v6
+	v7 := randStringSnapshotRecoveryRequest(r)
+	this.ConnectionString = &v7
+	if !easy && r.Intn(10) != 0 {
+		this.XXX_unrecognized = randUnrecognizedSnapshotRecoveryRequest(r, 3)
+	}
+	return this
+}
+
+type randySnapshotRecoveryRequest interface {
+	Float32() float32
+	Float64() float64
+	Int63() int64
+	Int31() int32
+	Uint32() uint32
+	Intn(n int) int
+}
+
+func randUTF8RuneSnapshotRecoveryRequest(r randySnapshotRecoveryRequest) rune {
+	res := rune(r.Uint32() % 1112064)
+	if 55296 <= res {
+		res += 2047
+	}
+	return res
+}
+func randStringSnapshotRecoveryRequest(r randySnapshotRecoveryRequest) string {
+	v8 := r.Intn(100)
+	tmps := make([]rune, v8)
+	for i := 0; i < v8; i++ {
+		tmps[i] = randUTF8RuneSnapshotRecoveryRequest(r)
+	}
+	return string(tmps)
+}
+func randUnrecognizedSnapshotRecoveryRequest(r randySnapshotRecoveryRequest, maxFieldNumber int) (data []byte) {
+	l := r.Intn(5)
+	for i := 0; i < l; i++ {
+		wire := r.Intn(4)
+		if wire == 3 {
+			wire = 5
+		}
+		fieldNumber := maxFieldNumber + r.Intn(100)
+		data = randFieldSnapshotRecoveryRequest(data, r, fieldNumber, wire)
+	}
+	return data
+}
+func randFieldSnapshotRecoveryRequest(data []byte, r randySnapshotRecoveryRequest, fieldNumber int, wire int) []byte {
+	key := uint32(fieldNumber)<<3 | uint32(wire)
+	switch wire {
+	case 0:
+		data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(key))
+		data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(r.Int63()))
+	case 1:
+		data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	case 2:
+		data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(key))
+		ll := r.Intn(100)
+		data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(ll))
+		for j := 0; j < ll; j++ {
+			data = append(data, byte(r.Intn(256)))
+		}
+	default:
+		data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	}
+	return data
+}
+func encodeVarintPopulateSnapshotRecoveryRequest(data []byte, v uint64) []byte {
+	for v >= 1<<7 {
+		data = append(data, uint8(uint64(v)&0x7f|0x80))
+		v >>= 7
+	}
+	data = append(data, uint8(v))
+	return data
+}
+func (m *SnapshotRecoveryRequest) Marshal() (data []byte, err error) {
+	size := m.Size()
+	data = make([]byte, size)
+	n, err := m.MarshalTo(data)
+	if err != nil {
+		return nil, err
+	}
+	return data[:n], nil
+}
+
+func (m *SnapshotRecoveryRequest) MarshalTo(data []byte) (n int, err error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.LeaderName != nil {
+		data[i] = 0xa
+		i++
+		i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(len(*m.LeaderName)))
+		i += copy(data[i:], *m.LeaderName)
+	}
+	if m.LastIndex != nil {
+		data[i] = 0x10
+		i++
+		i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(*m.LastIndex))
+	}
+	if m.LastTerm != nil {
+		data[i] = 0x18
+		i++
+		i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(*m.LastTerm))
+	}
+	if len(m.Peers) > 0 {
+		for _, msg := range m.Peers {
+			data[i] = 0x22
+			i++
+			i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(data[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	if m.State != nil {
+		data[i] = 0x2a
+		i++
+		i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(len(m.State)))
+		i += copy(data[i:], m.State)
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(data[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+func (m *SnapshotRecoveryRequest_Peer) Marshal() (data []byte, err error) {
+	size := m.Size()
+	data = make([]byte, size)
+	n, err := m.MarshalTo(data)
+	if err != nil {
+		return nil, err
+	}
+	return data[:n], nil
+}
+
+func (m *SnapshotRecoveryRequest_Peer) MarshalTo(data []byte) (n int, err error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Name != nil {
+		data[i] = 0xa
+		i++
+		i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(len(*m.Name)))
+		i += copy(data[i:], *m.Name)
+	}
+	if m.ConnectionString != nil {
+		data[i] = 0x12
+		i++
+		i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(len(*m.ConnectionString)))
+		i += copy(data[i:], *m.ConnectionString)
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(data[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+func encodeFixed64SnapshotRecoveryRequest(data []byte, offset int, v uint64) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	data[offset+4] = uint8(v >> 32)
+	data[offset+5] = uint8(v >> 40)
+	data[offset+6] = uint8(v >> 48)
+	data[offset+7] = uint8(v >> 56)
+	return offset + 8
+}
+func encodeFixed32SnapshotRecoveryRequest(data []byte, offset int, v uint32) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	return offset + 4
+}
+func encodeVarintSnapshotRecoveryRequest(data []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		data[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	data[offset] = uint8(v)
+	return offset + 1
+}
+func (this *SnapshotRecoveryRequest) GoString() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings11.Join([]string{`&protobuf.SnapshotRecoveryRequest{` + `LeaderName:` + valueToGoStringSnapshotRecoveryRequest(this.LeaderName, "string"), `LastIndex:` + valueToGoStringSnapshotRecoveryRequest(this.LastIndex, "uint64"), `LastTerm:` + valueToGoStringSnapshotRecoveryRequest(this.LastTerm, "uint64"), `Peers:` + fmt16.Sprintf("%#v", this.Peers), `State:` + valueToGoStringSnapshotRecoveryRequest(this.State, "byte"), `XXX_unrecognized:` + fmt16.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
+	return s
+}
+func (this *SnapshotRecoveryRequest_Peer) GoString() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings11.Join([]string{`&protobuf.SnapshotRecoveryRequest_Peer{` + `Name:` + valueToGoStringSnapshotRecoveryRequest(this.Name, "string"), `ConnectionString:` + valueToGoStringSnapshotRecoveryRequest(this.ConnectionString, "string"), `XXX_unrecognized:` + fmt16.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
+	return s
+}
+func valueToGoStringSnapshotRecoveryRequest(v interface{}, typ string) string {
+	rv := reflect11.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect11.Indirect(rv).Interface()
+	return fmt16.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
+}
+func extensionToGoStringSnapshotRecoveryRequest(e map[int32]code_google_com_p_gogoprotobuf_proto11.Extension) string {
+	if e == nil {
+		return "nil"
+	}
+	s := "map[int32]proto.Extension{"
+	keys := make([]int, 0, len(e))
+	for k := range e {
+		keys = append(keys, int(k))
+	}
+	sort5.Ints(keys)
+	ss := []string{}
+	for _, k := range keys {
+		ss = append(ss, strconv5.Itoa(k)+": "+e[int32(k)].GoString())
+	}
+	s += strings11.Join(ss, ",") + "}"
+	return s
+}
+func (this *SnapshotRecoveryRequest) VerboseEqual(that interface{}) error {
+	if that == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt17.Errorf("that == nil && this != nil")
+	}
+
+	that1, ok := that.(*SnapshotRecoveryRequest)
+	if !ok {
+		return fmt17.Errorf("that is not of type *SnapshotRecoveryRequest")
+	}
+	if that1 == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt17.Errorf("that is type *SnapshotRecoveryRequest but is nil && this != nil")
+	} else if this == nil {
+		return fmt17.Errorf("that is type *SnapshotRecoveryRequestbut is not nil && this == nil")
+	}
+	if this.LeaderName != nil && that1.LeaderName != nil {
+		if *this.LeaderName != *that1.LeaderName {
+			return fmt17.Errorf("LeaderName this(%v) Not Equal that(%v)", *this.LeaderName, *that1.LeaderName)
+		}
+	} else if this.LeaderName != nil {
+		return fmt17.Errorf("this.LeaderName == nil && that.LeaderName != nil")
+	} else if that1.LeaderName != nil {
+		return fmt17.Errorf("LeaderName this(%v) Not Equal that(%v)", this.LeaderName, that1.LeaderName)
+	}
+	if this.LastIndex != nil && that1.LastIndex != nil {
+		if *this.LastIndex != *that1.LastIndex {
+			return fmt17.Errorf("LastIndex this(%v) Not Equal that(%v)", *this.LastIndex, *that1.LastIndex)
+		}
+	} else if this.LastIndex != nil {
+		return fmt17.Errorf("this.LastIndex == nil && that.LastIndex != nil")
+	} else if that1.LastIndex != nil {
+		return fmt17.Errorf("LastIndex this(%v) Not Equal that(%v)", this.LastIndex, that1.LastIndex)
+	}
+	if this.LastTerm != nil && that1.LastTerm != nil {
+		if *this.LastTerm != *that1.LastTerm {
+			return fmt17.Errorf("LastTerm this(%v) Not Equal that(%v)", *this.LastTerm, *that1.LastTerm)
+		}
+	} else if this.LastTerm != nil {
+		return fmt17.Errorf("this.LastTerm == nil && that.LastTerm != nil")
+	} else if that1.LastTerm != nil {
+		return fmt17.Errorf("LastTerm this(%v) Not Equal that(%v)", this.LastTerm, that1.LastTerm)
+	}
+	if len(this.Peers) != len(that1.Peers) {
+		return fmt17.Errorf("Peers this(%v) Not Equal that(%v)", len(this.Peers), len(that1.Peers))
+	}
+	for i := range this.Peers {
+		if !this.Peers[i].Equal(that1.Peers[i]) {
+			return fmt17.Errorf("Peers this[%v](%v) Not Equal that[%v](%v)", i, this.Peers[i], i, that1.Peers[i])
+		}
+	}
+	if !bytes5.Equal(this.State, that1.State) {
+		return fmt17.Errorf("State this(%v) Not Equal that(%v)", this.State, that1.State)
+	}
+	if !bytes5.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return fmt17.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
+	}
+	return nil
+}
+func (this *SnapshotRecoveryRequest) Equal(that interface{}) bool {
+	if that == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	}
+
+	that1, ok := that.(*SnapshotRecoveryRequest)
+	if !ok {
+		return false
+	}
+	if that1 == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	} else if this == nil {
+		return false
+	}
+	if this.LeaderName != nil && that1.LeaderName != nil {
+		if *this.LeaderName != *that1.LeaderName {
+			return false
+		}
+	} else if this.LeaderName != nil {
+		return false
+	} else if that1.LeaderName != nil {
+		return false
+	}
+	if this.LastIndex != nil && that1.LastIndex != nil {
+		if *this.LastIndex != *that1.LastIndex {
+			return false
+		}
+	} else if this.LastIndex != nil {
+		return false
+	} else if that1.LastIndex != nil {
+		return false
+	}
+	if this.LastTerm != nil && that1.LastTerm != nil {
+		if *this.LastTerm != *that1.LastTerm {
+			return false
+		}
+	} else if this.LastTerm != nil {
+		return false
+	} else if that1.LastTerm != nil {
+		return false
+	}
+	if len(this.Peers) != len(that1.Peers) {
+		return false
+	}
+	for i := range this.Peers {
+		if !this.Peers[i].Equal(that1.Peers[i]) {
+			return false
+		}
+	}
+	if !bytes5.Equal(this.State, that1.State) {
+		return false
+	}
+	if !bytes5.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return false
+	}
+	return true
+}
+func (this *SnapshotRecoveryRequest_Peer) VerboseEqual(that interface{}) error {
+	if that == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt17.Errorf("that == nil && this != nil")
+	}
+
+	that1, ok := that.(*SnapshotRecoveryRequest_Peer)
+	if !ok {
+		return fmt17.Errorf("that is not of type *SnapshotRecoveryRequest_Peer")
+	}
+	if that1 == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt17.Errorf("that is type *SnapshotRecoveryRequest_Peer but is nil && this != nil")
+	} else if this == nil {
+		return fmt17.Errorf("that is type *SnapshotRecoveryRequest_Peerbut is not nil && this == nil")
+	}
+	if this.Name != nil && that1.Name != nil {
+		if *this.Name != *that1.Name {
+			return fmt17.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name)
+		}
+	} else if this.Name != nil {
+		return fmt17.Errorf("this.Name == nil && that.Name != nil")
+	} else if that1.Name != nil {
+		return fmt17.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name)
+	}
+	if this.ConnectionString != nil && that1.ConnectionString != nil {
+		if *this.ConnectionString != *that1.ConnectionString {
+			return fmt17.Errorf("ConnectionString this(%v) Not Equal that(%v)", *this.ConnectionString, *that1.ConnectionString)
+		}
+	} else if this.ConnectionString != nil {
+		return fmt17.Errorf("this.ConnectionString == nil && that.ConnectionString != nil")
+	} else if that1.ConnectionString != nil {
+		return fmt17.Errorf("ConnectionString this(%v) Not Equal that(%v)", this.ConnectionString, that1.ConnectionString)
+	}
+	if !bytes5.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return fmt17.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
+	}
+	return nil
+}
+func (this *SnapshotRecoveryRequest_Peer) Equal(that interface{}) bool {
+	if that == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	}
+
+	that1, ok := that.(*SnapshotRecoveryRequest_Peer)
+	if !ok {
+		return false
+	}
+	if that1 == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	} else if this == nil {
+		return false
+	}
+	if this.Name != nil && that1.Name != nil {
+		if *this.Name != *that1.Name {
+			return false
+		}
+	} else if this.Name != nil {
+		return false
+	} else if that1.Name != nil {
+		return false
+	}
+	if this.ConnectionString != nil && that1.ConnectionString != nil {
+		if *this.ConnectionString != *that1.ConnectionString {
+			return false
+		}
+	} else if this.ConnectionString != nil {
+		return false
+	} else if that1.ConnectionString != nil {
+		return false
+	}
+	if !bytes5.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return false
+	}
+	return true
+}

+ 17 - 3
third_party/github.com/coreos/raft/protobuf/snapshot_recovery_request.proto

@@ -1,15 +1,29 @@
 package protobuf;
 
-message ProtoSnapshotRecoveryRequest {
+import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
+
+option (gogoproto.gostring_all) = true;
+option (gogoproto.equal_all) = true;
+option (gogoproto.verbose_equal_all) = true;
+option (gogoproto.goproto_stringer_all) = false;
+option (gogoproto.stringer_all) =  true;
+option (gogoproto.populate_all) = true;
+option (gogoproto.testgen_all) = true;
+option (gogoproto.benchgen_all) = true;
+option (gogoproto.marshaler_all) = true;
+option (gogoproto.sizer_all) = true;
+option (gogoproto.unmarshaler_all) = true;
+
+message SnapshotRecoveryRequest {
 	required string  LeaderName=1;
 	required uint64  LastIndex=2;
 	required uint64  LastTerm=3;   
 
-	message ProtoPeer {
+	message Peer {
 		required string Name=1;
 		required string ConnectionString=2;
 	}  
-	repeated ProtoPeer  Peers=4;  
+	repeated Peer  Peers=4;  
 
 	required bytes   State=5;
 }

+ 454 - 9
third_party/github.com/coreos/raft/protobuf/snapshot_recovery_response.pb.go

@@ -1,44 +1,62 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-gogo.
 // source: snapshot_recovery_response.proto
 // DO NOT EDIT!
 
 package protobuf
 
-import proto "github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
+import proto "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
 import json "encoding/json"
 import math "math"
 
+// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
+
+import io6 "io"
+import code_google_com_p_gogoprotobuf_proto12 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+
+import fmt18 "fmt"
+import strings12 "strings"
+import reflect12 "reflect"
+
+import fmt19 "fmt"
+import strings13 "strings"
+import code_google_com_p_gogoprotobuf_proto13 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+import sort6 "sort"
+import strconv6 "strconv"
+import reflect13 "reflect"
+
+import fmt20 "fmt"
+import bytes6 "bytes"
+
 // Reference proto, json, and math imports to suppress error if they are not otherwise used.
 var _ = proto.Marshal
 var _ = &json.SyntaxError{}
 var _ = math.Inf
 
-type ProtoSnapshotRecoveryResponse struct {
+type SnapshotRecoveryResponse struct {
 	Term			*uint64	`protobuf:"varint,1,req" json:"Term,omitempty"`
 	Success			*bool	`protobuf:"varint,2,req" json:"Success,omitempty"`
 	CommitIndex		*uint64	`protobuf:"varint,3,req" json:"CommitIndex,omitempty"`
 	XXX_unrecognized	[]byte	`json:"-"`
 }
 
-func (m *ProtoSnapshotRecoveryResponse) Reset()		{ *m = ProtoSnapshotRecoveryResponse{} }
-func (m *ProtoSnapshotRecoveryResponse) String() string	{ return proto.CompactTextString(m) }
-func (*ProtoSnapshotRecoveryResponse) ProtoMessage()	{}
+func (m *SnapshotRecoveryResponse) Reset()	{ *m = SnapshotRecoveryResponse{} }
+func (*SnapshotRecoveryResponse) ProtoMessage()	{}
 
-func (m *ProtoSnapshotRecoveryResponse) GetTerm() uint64 {
+func (m *SnapshotRecoveryResponse) GetTerm() uint64 {
 	if m != nil && m.Term != nil {
 		return *m.Term
 	}
 	return 0
 }
 
-func (m *ProtoSnapshotRecoveryResponse) GetSuccess() bool {
+func (m *SnapshotRecoveryResponse) GetSuccess() bool {
 	if m != nil && m.Success != nil {
 		return *m.Success
 	}
 	return false
 }
 
-func (m *ProtoSnapshotRecoveryResponse) GetCommitIndex() uint64 {
+func (m *SnapshotRecoveryResponse) GetCommitIndex() uint64 {
 	if m != nil && m.CommitIndex != nil {
 		return *m.CommitIndex
 	}
@@ -47,3 +65,430 @@ func (m *ProtoSnapshotRecoveryResponse) GetCommitIndex() uint64 {
 
 func init() {
 }
+func (m *SnapshotRecoveryResponse) Unmarshal(data []byte) error {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return io6.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io6.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Term = &v
+		case 2:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io6.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			b := bool(v != 0)
+			m.Success = &b
+		case 3:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io6.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.CommitIndex = &v
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			index -= sizeOfWire
+			skippy, err := code_google_com_p_gogoprotobuf_proto12.Skip(data[index:])
+			if err != nil {
+				return err
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
+			index += skippy
+		}
+	}
+	return nil
+}
+func (this *SnapshotRecoveryResponse) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings12.Join([]string{`&SnapshotRecoveryResponse{`,
+		`Term:` + valueToStringSnapshotRecoveryResponse(this.Term) + `,`,
+		`Success:` + valueToStringSnapshotRecoveryResponse(this.Success) + `,`,
+		`CommitIndex:` + valueToStringSnapshotRecoveryResponse(this.CommitIndex) + `,`,
+		`XXX_unrecognized:` + fmt18.Sprintf("%v", this.XXX_unrecognized) + `,`,
+		`}`,
+	}, "")
+	return s
+}
+func valueToStringSnapshotRecoveryResponse(v interface{}) string {
+	rv := reflect12.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect12.Indirect(rv).Interface()
+	return fmt18.Sprintf("*%v", pv)
+}
+func (m *SnapshotRecoveryResponse) Size() (n int) {
+	var l int
+	_ = l
+	if m.Term != nil {
+		n += 1 + sovSnapshotRecoveryResponse(uint64(*m.Term))
+	}
+	if m.Success != nil {
+		n += 2
+	}
+	if m.CommitIndex != nil {
+		n += 1 + sovSnapshotRecoveryResponse(uint64(*m.CommitIndex))
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func sovSnapshotRecoveryResponse(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozSnapshotRecoveryResponse(x uint64) (n int) {
+	return sovSnapshotRecoveryResponse(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+	return sovSnapshotRecoveryResponse(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func NewPopulatedSnapshotRecoveryResponse(r randySnapshotRecoveryResponse, easy bool) *SnapshotRecoveryResponse {
+	this := &SnapshotRecoveryResponse{}
+	v1 := uint64(r.Uint32())
+	this.Term = &v1
+	v2 := bool(r.Intn(2) == 0)
+	this.Success = &v2
+	v3 := uint64(r.Uint32())
+	this.CommitIndex = &v3
+	if !easy && r.Intn(10) != 0 {
+		this.XXX_unrecognized = randUnrecognizedSnapshotRecoveryResponse(r, 4)
+	}
+	return this
+}
+
+type randySnapshotRecoveryResponse interface {
+	Float32() float32
+	Float64() float64
+	Int63() int64
+	Int31() int32
+	Uint32() uint32
+	Intn(n int) int
+}
+
+func randUTF8RuneSnapshotRecoveryResponse(r randySnapshotRecoveryResponse) rune {
+	res := rune(r.Uint32() % 1112064)
+	if 55296 <= res {
+		res += 2047
+	}
+	return res
+}
+func randStringSnapshotRecoveryResponse(r randySnapshotRecoveryResponse) string {
+	v4 := r.Intn(100)
+	tmps := make([]rune, v4)
+	for i := 0; i < v4; i++ {
+		tmps[i] = randUTF8RuneSnapshotRecoveryResponse(r)
+	}
+	return string(tmps)
+}
+func randUnrecognizedSnapshotRecoveryResponse(r randySnapshotRecoveryResponse, maxFieldNumber int) (data []byte) {
+	l := r.Intn(5)
+	for i := 0; i < l; i++ {
+		wire := r.Intn(4)
+		if wire == 3 {
+			wire = 5
+		}
+		fieldNumber := maxFieldNumber + r.Intn(100)
+		data = randFieldSnapshotRecoveryResponse(data, r, fieldNumber, wire)
+	}
+	return data
+}
+func randFieldSnapshotRecoveryResponse(data []byte, r randySnapshotRecoveryResponse, fieldNumber int, wire int) []byte {
+	key := uint32(fieldNumber)<<3 | uint32(wire)
+	switch wire {
+	case 0:
+		data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(key))
+		data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(r.Int63()))
+	case 1:
+		data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	case 2:
+		data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(key))
+		ll := r.Intn(100)
+		data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(ll))
+		for j := 0; j < ll; j++ {
+			data = append(data, byte(r.Intn(256)))
+		}
+	default:
+		data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	}
+	return data
+}
+func encodeVarintPopulateSnapshotRecoveryResponse(data []byte, v uint64) []byte {
+	for v >= 1<<7 {
+		data = append(data, uint8(uint64(v)&0x7f|0x80))
+		v >>= 7
+	}
+	data = append(data, uint8(v))
+	return data
+}
+func (m *SnapshotRecoveryResponse) Marshal() (data []byte, err error) {
+	size := m.Size()
+	data = make([]byte, size)
+	n, err := m.MarshalTo(data)
+	if err != nil {
+		return nil, err
+	}
+	return data[:n], nil
+}
+
+func (m *SnapshotRecoveryResponse) MarshalTo(data []byte) (n int, err error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Term != nil {
+		data[i] = 0x8
+		i++
+		i = encodeVarintSnapshotRecoveryResponse(data, i, uint64(*m.Term))
+	}
+	if m.Success != nil {
+		data[i] = 0x10
+		i++
+		if *m.Success {
+			data[i] = 1
+		} else {
+			data[i] = 0
+		}
+		i++
+	}
+	if m.CommitIndex != nil {
+		data[i] = 0x18
+		i++
+		i = encodeVarintSnapshotRecoveryResponse(data, i, uint64(*m.CommitIndex))
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(data[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+func encodeFixed64SnapshotRecoveryResponse(data []byte, offset int, v uint64) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	data[offset+4] = uint8(v >> 32)
+	data[offset+5] = uint8(v >> 40)
+	data[offset+6] = uint8(v >> 48)
+	data[offset+7] = uint8(v >> 56)
+	return offset + 8
+}
+func encodeFixed32SnapshotRecoveryResponse(data []byte, offset int, v uint32) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	return offset + 4
+}
+func encodeVarintSnapshotRecoveryResponse(data []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		data[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	data[offset] = uint8(v)
+	return offset + 1
+}
+func (this *SnapshotRecoveryResponse) GoString() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings13.Join([]string{`&protobuf.SnapshotRecoveryResponse{` + `Term:` + valueToGoStringSnapshotRecoveryResponse(this.Term, "uint64"), `Success:` + valueToGoStringSnapshotRecoveryResponse(this.Success, "bool"), `CommitIndex:` + valueToGoStringSnapshotRecoveryResponse(this.CommitIndex, "uint64"), `XXX_unrecognized:` + fmt19.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
+	return s
+}
+func valueToGoStringSnapshotRecoveryResponse(v interface{}, typ string) string {
+	rv := reflect13.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect13.Indirect(rv).Interface()
+	return fmt19.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
+}
+func extensionToGoStringSnapshotRecoveryResponse(e map[int32]code_google_com_p_gogoprotobuf_proto13.Extension) string {
+	if e == nil {
+		return "nil"
+	}
+	s := "map[int32]proto.Extension{"
+	keys := make([]int, 0, len(e))
+	for k := range e {
+		keys = append(keys, int(k))
+	}
+	sort6.Ints(keys)
+	ss := []string{}
+	for _, k := range keys {
+		ss = append(ss, strconv6.Itoa(k)+": "+e[int32(k)].GoString())
+	}
+	s += strings13.Join(ss, ",") + "}"
+	return s
+}
+func (this *SnapshotRecoveryResponse) VerboseEqual(that interface{}) error {
+	if that == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt20.Errorf("that == nil && this != nil")
+	}
+
+	that1, ok := that.(*SnapshotRecoveryResponse)
+	if !ok {
+		return fmt20.Errorf("that is not of type *SnapshotRecoveryResponse")
+	}
+	if that1 == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt20.Errorf("that is type *SnapshotRecoveryResponse but is nil && this != nil")
+	} else if this == nil {
+		return fmt20.Errorf("that is type *SnapshotRecoveryResponsebut is not nil && this == nil")
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return fmt20.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
+		}
+	} else if this.Term != nil {
+		return fmt20.Errorf("this.Term == nil && that.Term != nil")
+	} else if that1.Term != nil {
+		return fmt20.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
+	}
+	if this.Success != nil && that1.Success != nil {
+		if *this.Success != *that1.Success {
+			return fmt20.Errorf("Success this(%v) Not Equal that(%v)", *this.Success, *that1.Success)
+		}
+	} else if this.Success != nil {
+		return fmt20.Errorf("this.Success == nil && that.Success != nil")
+	} else if that1.Success != nil {
+		return fmt20.Errorf("Success this(%v) Not Equal that(%v)", this.Success, that1.Success)
+	}
+	if this.CommitIndex != nil && that1.CommitIndex != nil {
+		if *this.CommitIndex != *that1.CommitIndex {
+			return fmt20.Errorf("CommitIndex this(%v) Not Equal that(%v)", *this.CommitIndex, *that1.CommitIndex)
+		}
+	} else if this.CommitIndex != nil {
+		return fmt20.Errorf("this.CommitIndex == nil && that.CommitIndex != nil")
+	} else if that1.CommitIndex != nil {
+		return fmt20.Errorf("CommitIndex this(%v) Not Equal that(%v)", this.CommitIndex, that1.CommitIndex)
+	}
+	if !bytes6.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return fmt20.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
+	}
+	return nil
+}
+func (this *SnapshotRecoveryResponse) Equal(that interface{}) bool {
+	if that == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	}
+
+	that1, ok := that.(*SnapshotRecoveryResponse)
+	if !ok {
+		return false
+	}
+	if that1 == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	} else if this == nil {
+		return false
+	}
+	if this.Term != nil && that1.Term != nil {
+		if *this.Term != *that1.Term {
+			return false
+		}
+	} else if this.Term != nil {
+		return false
+	} else if that1.Term != nil {
+		return false
+	}
+	if this.Success != nil && that1.Success != nil {
+		if *this.Success != *that1.Success {
+			return false
+		}
+	} else if this.Success != nil {
+		return false
+	} else if that1.Success != nil {
+		return false
+	}
+	if this.CommitIndex != nil && that1.CommitIndex != nil {
+		if *this.CommitIndex != *that1.CommitIndex {
+			return false
+		}
+	} else if this.CommitIndex != nil {
+		return false
+	} else if that1.CommitIndex != nil {
+		return false
+	}
+	if !bytes6.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return false
+	}
+	return true
+}

+ 15 - 1
third_party/github.com/coreos/raft/protobuf/snapshot_recovery_response.proto

@@ -1,6 +1,20 @@
 package protobuf;
 
-message ProtoSnapshotRecoveryResponse {
+import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
+
+option (gogoproto.gostring_all) = true;
+option (gogoproto.equal_all) = true;
+option (gogoproto.verbose_equal_all) = true;
+option (gogoproto.goproto_stringer_all) = false;
+option (gogoproto.stringer_all) =  true;
+option (gogoproto.populate_all) = true;
+option (gogoproto.testgen_all) = true;
+option (gogoproto.benchgen_all) = true;
+option (gogoproto.marshaler_all) = true;
+option (gogoproto.sizer_all) = true;
+option (gogoproto.unmarshaler_all) = true;
+
+message SnapshotRecoveryResponse {
 	required uint64 Term=1;     
 	required bool Success=2;
 	required uint64 CommitIndex=3;

+ 456 - 9
third_party/github.com/coreos/raft/protobuf/snapshot_request.pb.go

@@ -1,44 +1,62 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-gogo.
 // source: snapshot_request.proto
 // DO NOT EDIT!
 
 package protobuf
 
-import proto "github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
+import proto "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
 import json "encoding/json"
 import math "math"
 
+// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
+
+import io7 "io"
+import code_google_com_p_gogoprotobuf_proto14 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+
+import fmt21 "fmt"
+import strings14 "strings"
+import reflect14 "reflect"
+
+import fmt22 "fmt"
+import strings15 "strings"
+import code_google_com_p_gogoprotobuf_proto15 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+import sort7 "sort"
+import strconv7 "strconv"
+import reflect15 "reflect"
+
+import fmt23 "fmt"
+import bytes7 "bytes"
+
 // Reference proto, json, and math imports to suppress error if they are not otherwise used.
 var _ = proto.Marshal
 var _ = &json.SyntaxError{}
 var _ = math.Inf
 
-type ProtoSnapshotRequest struct {
+type SnapshotRequest struct {
 	LeaderName		*string	`protobuf:"bytes,1,req" json:"LeaderName,omitempty"`
 	LastIndex		*uint64	`protobuf:"varint,2,req" json:"LastIndex,omitempty"`
 	LastTerm		*uint64	`protobuf:"varint,3,req" json:"LastTerm,omitempty"`
 	XXX_unrecognized	[]byte	`json:"-"`
 }
 
-func (m *ProtoSnapshotRequest) Reset()		{ *m = ProtoSnapshotRequest{} }
-func (m *ProtoSnapshotRequest) String() string	{ return proto.CompactTextString(m) }
-func (*ProtoSnapshotRequest) ProtoMessage()	{}
+func (m *SnapshotRequest) Reset()	{ *m = SnapshotRequest{} }
+func (*SnapshotRequest) ProtoMessage()	{}
 
-func (m *ProtoSnapshotRequest) GetLeaderName() string {
+func (m *SnapshotRequest) GetLeaderName() string {
 	if m != nil && m.LeaderName != nil {
 		return *m.LeaderName
 	}
 	return ""
 }
 
-func (m *ProtoSnapshotRequest) GetLastIndex() uint64 {
+func (m *SnapshotRequest) GetLastIndex() uint64 {
 	if m != nil && m.LastIndex != nil {
 		return *m.LastIndex
 	}
 	return 0
 }
 
-func (m *ProtoSnapshotRequest) GetLastTerm() uint64 {
+func (m *SnapshotRequest) GetLastTerm() uint64 {
 	if m != nil && m.LastTerm != nil {
 		return *m.LastTerm
 	}
@@ -47,3 +65,432 @@ func (m *ProtoSnapshotRequest) GetLastTerm() uint64 {
 
 func init() {
 }
+func (m *SnapshotRequest) Unmarshal(data []byte) error {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return io7.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io7.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := index + int(stringLen)
+			if postIndex > l {
+				return io7.ErrUnexpectedEOF
+			}
+			s := string(data[index:postIndex])
+			m.LeaderName = &s
+			index = postIndex
+		case 2:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io7.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.LastIndex = &v
+		case 3:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io7.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.LastTerm = &v
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			index -= sizeOfWire
+			skippy, err := code_google_com_p_gogoprotobuf_proto14.Skip(data[index:])
+			if err != nil {
+				return err
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
+			index += skippy
+		}
+	}
+	return nil
+}
+func (this *SnapshotRequest) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings14.Join([]string{`&SnapshotRequest{`,
+		`LeaderName:` + valueToStringSnapshotRequest(this.LeaderName) + `,`,
+		`LastIndex:` + valueToStringSnapshotRequest(this.LastIndex) + `,`,
+		`LastTerm:` + valueToStringSnapshotRequest(this.LastTerm) + `,`,
+		`XXX_unrecognized:` + fmt21.Sprintf("%v", this.XXX_unrecognized) + `,`,
+		`}`,
+	}, "")
+	return s
+}
+func valueToStringSnapshotRequest(v interface{}) string {
+	rv := reflect14.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect14.Indirect(rv).Interface()
+	return fmt21.Sprintf("*%v", pv)
+}
+func (m *SnapshotRequest) Size() (n int) {
+	var l int
+	_ = l
+	if m.LeaderName != nil {
+		l = len(*m.LeaderName)
+		n += 1 + l + sovSnapshotRequest(uint64(l))
+	}
+	if m.LastIndex != nil {
+		n += 1 + sovSnapshotRequest(uint64(*m.LastIndex))
+	}
+	if m.LastTerm != nil {
+		n += 1 + sovSnapshotRequest(uint64(*m.LastTerm))
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func sovSnapshotRequest(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozSnapshotRequest(x uint64) (n int) {
+	return sovSnapshotRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+	return sovSnapshotRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func NewPopulatedSnapshotRequest(r randySnapshotRequest, easy bool) *SnapshotRequest {
+	this := &SnapshotRequest{}
+	v1 := randStringSnapshotRequest(r)
+	this.LeaderName = &v1
+	v2 := uint64(r.Uint32())
+	this.LastIndex = &v2
+	v3 := uint64(r.Uint32())
+	this.LastTerm = &v3
+	if !easy && r.Intn(10) != 0 {
+		this.XXX_unrecognized = randUnrecognizedSnapshotRequest(r, 4)
+	}
+	return this
+}
+
+type randySnapshotRequest interface {
+	Float32() float32
+	Float64() float64
+	Int63() int64
+	Int31() int32
+	Uint32() uint32
+	Intn(n int) int
+}
+
+func randUTF8RuneSnapshotRequest(r randySnapshotRequest) rune {
+	res := rune(r.Uint32() % 1112064)
+	if 55296 <= res {
+		res += 2047
+	}
+	return res
+}
+func randStringSnapshotRequest(r randySnapshotRequest) string {
+	v4 := r.Intn(100)
+	tmps := make([]rune, v4)
+	for i := 0; i < v4; i++ {
+		tmps[i] = randUTF8RuneSnapshotRequest(r)
+	}
+	return string(tmps)
+}
+func randUnrecognizedSnapshotRequest(r randySnapshotRequest, maxFieldNumber int) (data []byte) {
+	l := r.Intn(5)
+	for i := 0; i < l; i++ {
+		wire := r.Intn(4)
+		if wire == 3 {
+			wire = 5
+		}
+		fieldNumber := maxFieldNumber + r.Intn(100)
+		data = randFieldSnapshotRequest(data, r, fieldNumber, wire)
+	}
+	return data
+}
+func randFieldSnapshotRequest(data []byte, r randySnapshotRequest, fieldNumber int, wire int) []byte {
+	key := uint32(fieldNumber)<<3 | uint32(wire)
+	switch wire {
+	case 0:
+		data = encodeVarintPopulateSnapshotRequest(data, uint64(key))
+		data = encodeVarintPopulateSnapshotRequest(data, uint64(r.Int63()))
+	case 1:
+		data = encodeVarintPopulateSnapshotRequest(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	case 2:
+		data = encodeVarintPopulateSnapshotRequest(data, uint64(key))
+		ll := r.Intn(100)
+		data = encodeVarintPopulateSnapshotRequest(data, uint64(ll))
+		for j := 0; j < ll; j++ {
+			data = append(data, byte(r.Intn(256)))
+		}
+	default:
+		data = encodeVarintPopulateSnapshotRequest(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	}
+	return data
+}
+func encodeVarintPopulateSnapshotRequest(data []byte, v uint64) []byte {
+	for v >= 1<<7 {
+		data = append(data, uint8(uint64(v)&0x7f|0x80))
+		v >>= 7
+	}
+	data = append(data, uint8(v))
+	return data
+}
+func (m *SnapshotRequest) Marshal() (data []byte, err error) {
+	size := m.Size()
+	data = make([]byte, size)
+	n, err := m.MarshalTo(data)
+	if err != nil {
+		return nil, err
+	}
+	return data[:n], nil
+}
+
+func (m *SnapshotRequest) MarshalTo(data []byte) (n int, err error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.LeaderName != nil {
+		data[i] = 0xa
+		i++
+		i = encodeVarintSnapshotRequest(data, i, uint64(len(*m.LeaderName)))
+		i += copy(data[i:], *m.LeaderName)
+	}
+	if m.LastIndex != nil {
+		data[i] = 0x10
+		i++
+		i = encodeVarintSnapshotRequest(data, i, uint64(*m.LastIndex))
+	}
+	if m.LastTerm != nil {
+		data[i] = 0x18
+		i++
+		i = encodeVarintSnapshotRequest(data, i, uint64(*m.LastTerm))
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(data[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+func encodeFixed64SnapshotRequest(data []byte, offset int, v uint64) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	data[offset+4] = uint8(v >> 32)
+	data[offset+5] = uint8(v >> 40)
+	data[offset+6] = uint8(v >> 48)
+	data[offset+7] = uint8(v >> 56)
+	return offset + 8
+}
+func encodeFixed32SnapshotRequest(data []byte, offset int, v uint32) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	return offset + 4
+}
+func encodeVarintSnapshotRequest(data []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		data[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	data[offset] = uint8(v)
+	return offset + 1
+}
+func (this *SnapshotRequest) GoString() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings15.Join([]string{`&protobuf.SnapshotRequest{` + `LeaderName:` + valueToGoStringSnapshotRequest(this.LeaderName, "string"), `LastIndex:` + valueToGoStringSnapshotRequest(this.LastIndex, "uint64"), `LastTerm:` + valueToGoStringSnapshotRequest(this.LastTerm, "uint64"), `XXX_unrecognized:` + fmt22.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
+	return s
+}
+func valueToGoStringSnapshotRequest(v interface{}, typ string) string {
+	rv := reflect15.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect15.Indirect(rv).Interface()
+	return fmt22.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
+}
+func extensionToGoStringSnapshotRequest(e map[int32]code_google_com_p_gogoprotobuf_proto15.Extension) string {
+	if e == nil {
+		return "nil"
+	}
+	s := "map[int32]proto.Extension{"
+	keys := make([]int, 0, len(e))
+	for k := range e {
+		keys = append(keys, int(k))
+	}
+	sort7.Ints(keys)
+	ss := []string{}
+	for _, k := range keys {
+		ss = append(ss, strconv7.Itoa(k)+": "+e[int32(k)].GoString())
+	}
+	s += strings15.Join(ss, ",") + "}"
+	return s
+}
+func (this *SnapshotRequest) VerboseEqual(that interface{}) error {
+	if that == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt23.Errorf("that == nil && this != nil")
+	}
+
+	that1, ok := that.(*SnapshotRequest)
+	if !ok {
+		return fmt23.Errorf("that is not of type *SnapshotRequest")
+	}
+	if that1 == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt23.Errorf("that is type *SnapshotRequest but is nil && this != nil")
+	} else if this == nil {
+		return fmt23.Errorf("that is type *SnapshotRequestbut is not nil && this == nil")
+	}
+	if this.LeaderName != nil && that1.LeaderName != nil {
+		if *this.LeaderName != *that1.LeaderName {
+			return fmt23.Errorf("LeaderName this(%v) Not Equal that(%v)", *this.LeaderName, *that1.LeaderName)
+		}
+	} else if this.LeaderName != nil {
+		return fmt23.Errorf("this.LeaderName == nil && that.LeaderName != nil")
+	} else if that1.LeaderName != nil {
+		return fmt23.Errorf("LeaderName this(%v) Not Equal that(%v)", this.LeaderName, that1.LeaderName)
+	}
+	if this.LastIndex != nil && that1.LastIndex != nil {
+		if *this.LastIndex != *that1.LastIndex {
+			return fmt23.Errorf("LastIndex this(%v) Not Equal that(%v)", *this.LastIndex, *that1.LastIndex)
+		}
+	} else if this.LastIndex != nil {
+		return fmt23.Errorf("this.LastIndex == nil && that.LastIndex != nil")
+	} else if that1.LastIndex != nil {
+		return fmt23.Errorf("LastIndex this(%v) Not Equal that(%v)", this.LastIndex, that1.LastIndex)
+	}
+	if this.LastTerm != nil && that1.LastTerm != nil {
+		if *this.LastTerm != *that1.LastTerm {
+			return fmt23.Errorf("LastTerm this(%v) Not Equal that(%v)", *this.LastTerm, *that1.LastTerm)
+		}
+	} else if this.LastTerm != nil {
+		return fmt23.Errorf("this.LastTerm == nil && that.LastTerm != nil")
+	} else if that1.LastTerm != nil {
+		return fmt23.Errorf("LastTerm this(%v) Not Equal that(%v)", this.LastTerm, that1.LastTerm)
+	}
+	if !bytes7.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return fmt23.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
+	}
+	return nil
+}
+func (this *SnapshotRequest) Equal(that interface{}) bool {
+	if that == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	}
+
+	that1, ok := that.(*SnapshotRequest)
+	if !ok {
+		return false
+	}
+	if that1 == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	} else if this == nil {
+		return false
+	}
+	if this.LeaderName != nil && that1.LeaderName != nil {
+		if *this.LeaderName != *that1.LeaderName {
+			return false
+		}
+	} else if this.LeaderName != nil {
+		return false
+	} else if that1.LeaderName != nil {
+		return false
+	}
+	if this.LastIndex != nil && that1.LastIndex != nil {
+		if *this.LastIndex != *that1.LastIndex {
+			return false
+		}
+	} else if this.LastIndex != nil {
+		return false
+	} else if that1.LastIndex != nil {
+		return false
+	}
+	if this.LastTerm != nil && that1.LastTerm != nil {
+		if *this.LastTerm != *that1.LastTerm {
+			return false
+		}
+	} else if this.LastTerm != nil {
+		return false
+	} else if that1.LastTerm != nil {
+		return false
+	}
+	if !bytes7.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return false
+	}
+	return true
+}

+ 15 - 1
third_party/github.com/coreos/raft/protobuf/snapshot_request.proto

@@ -1,6 +1,20 @@
 package protobuf;
 
-message ProtoSnapshotRequest {
+import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
+
+option (gogoproto.gostring_all) = true;
+option (gogoproto.equal_all) = true;
+option (gogoproto.verbose_equal_all) = true;
+option (gogoproto.goproto_stringer_all) = false;
+option (gogoproto.stringer_all) =  true;
+option (gogoproto.populate_all) = true;
+option (gogoproto.testgen_all) = true;
+option (gogoproto.benchgen_all) = true;
+option (gogoproto.marshaler_all) = true;
+option (gogoproto.sizer_all) = true;
+option (gogoproto.unmarshaler_all) = true;
+
+message SnapshotRequest {
 	required string LeaderName=1;
 	required uint64 LastIndex=2; 
 	required uint64 LastTerm=3;

+ 360 - 7
third_party/github.com/coreos/raft/protobuf/snapshot_response.pb.go

@@ -1,28 +1,46 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-gogo.
 // source: snapshot_response.proto
 // DO NOT EDIT!
 
 package protobuf
 
-import proto "github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
+import proto "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
 import json "encoding/json"
 import math "math"
 
+// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
+
+import io8 "io"
+import code_google_com_p_gogoprotobuf_proto16 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+
+import fmt24 "fmt"
+import strings16 "strings"
+import reflect16 "reflect"
+
+import fmt25 "fmt"
+import strings17 "strings"
+import code_google_com_p_gogoprotobuf_proto17 "github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+import sort8 "sort"
+import strconv8 "strconv"
+import reflect17 "reflect"
+
+import fmt26 "fmt"
+import bytes8 "bytes"
+
 // Reference proto, json, and math imports to suppress error if they are not otherwise used.
 var _ = proto.Marshal
 var _ = &json.SyntaxError{}
 var _ = math.Inf
 
-type ProtoSnapshotResponse struct {
+type SnapshotResponse struct {
 	Success			*bool	`protobuf:"varint,1,req" json:"Success,omitempty"`
 	XXX_unrecognized	[]byte	`json:"-"`
 }
 
-func (m *ProtoSnapshotResponse) Reset()		{ *m = ProtoSnapshotResponse{} }
-func (m *ProtoSnapshotResponse) String() string	{ return proto.CompactTextString(m) }
-func (*ProtoSnapshotResponse) ProtoMessage()	{}
+func (m *SnapshotResponse) Reset()	{ *m = SnapshotResponse{} }
+func (*SnapshotResponse) ProtoMessage()	{}
 
-func (m *ProtoSnapshotResponse) GetSuccess() bool {
+func (m *SnapshotResponse) GetSuccess() bool {
 	if m != nil && m.Success != nil {
 		return *m.Success
 	}
@@ -31,3 +49,338 @@ func (m *ProtoSnapshotResponse) GetSuccess() bool {
 
 func init() {
 }
+func (m *SnapshotResponse) Unmarshal(data []byte) error {
+	l := len(data)
+	index := 0
+	for index < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if index >= l {
+				return io8.ErrUnexpectedEOF
+			}
+			b := data[index]
+			index++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return proto.ErrWrongType
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if index >= l {
+					return io8.ErrUnexpectedEOF
+				}
+				b := data[index]
+				index++
+				v |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			b := bool(v != 0)
+			m.Success = &b
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			index -= sizeOfWire
+			skippy, err := code_google_com_p_gogoprotobuf_proto16.Skip(data[index:])
+			if err != nil {
+				return err
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
+			index += skippy
+		}
+	}
+	return nil
+}
+func (this *SnapshotResponse) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings16.Join([]string{`&SnapshotResponse{`,
+		`Success:` + valueToStringSnapshotResponse(this.Success) + `,`,
+		`XXX_unrecognized:` + fmt24.Sprintf("%v", this.XXX_unrecognized) + `,`,
+		`}`,
+	}, "")
+	return s
+}
+func valueToStringSnapshotResponse(v interface{}) string {
+	rv := reflect16.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect16.Indirect(rv).Interface()
+	return fmt24.Sprintf("*%v", pv)
+}
+func (m *SnapshotResponse) Size() (n int) {
+	var l int
+	_ = l
+	if m.Success != nil {
+		n += 2
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func sovSnapshotResponse(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozSnapshotResponse(x uint64) (n int) {
+	return sovSnapshotResponse(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+	return sovSnapshotResponse(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func NewPopulatedSnapshotResponse(r randySnapshotResponse, easy bool) *SnapshotResponse {
+	this := &SnapshotResponse{}
+	v1 := bool(r.Intn(2) == 0)
+	this.Success = &v1
+	if !easy && r.Intn(10) != 0 {
+		this.XXX_unrecognized = randUnrecognizedSnapshotResponse(r, 2)
+	}
+	return this
+}
+
+type randySnapshotResponse interface {
+	Float32() float32
+	Float64() float64
+	Int63() int64
+	Int31() int32
+	Uint32() uint32
+	Intn(n int) int
+}
+
+func randUTF8RuneSnapshotResponse(r randySnapshotResponse) rune {
+	res := rune(r.Uint32() % 1112064)
+	if 55296 <= res {
+		res += 2047
+	}
+	return res
+}
+func randStringSnapshotResponse(r randySnapshotResponse) string {
+	v2 := r.Intn(100)
+	tmps := make([]rune, v2)
+	for i := 0; i < v2; i++ {
+		tmps[i] = randUTF8RuneSnapshotResponse(r)
+	}
+	return string(tmps)
+}
+func randUnrecognizedSnapshotResponse(r randySnapshotResponse, maxFieldNumber int) (data []byte) {
+	l := r.Intn(5)
+	for i := 0; i < l; i++ {
+		wire := r.Intn(4)
+		if wire == 3 {
+			wire = 5
+		}
+		fieldNumber := maxFieldNumber + r.Intn(100)
+		data = randFieldSnapshotResponse(data, r, fieldNumber, wire)
+	}
+	return data
+}
+func randFieldSnapshotResponse(data []byte, r randySnapshotResponse, fieldNumber int, wire int) []byte {
+	key := uint32(fieldNumber)<<3 | uint32(wire)
+	switch wire {
+	case 0:
+		data = encodeVarintPopulateSnapshotResponse(data, uint64(key))
+		data = encodeVarintPopulateSnapshotResponse(data, uint64(r.Int63()))
+	case 1:
+		data = encodeVarintPopulateSnapshotResponse(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	case 2:
+		data = encodeVarintPopulateSnapshotResponse(data, uint64(key))
+		ll := r.Intn(100)
+		data = encodeVarintPopulateSnapshotResponse(data, uint64(ll))
+		for j := 0; j < ll; j++ {
+			data = append(data, byte(r.Intn(256)))
+		}
+	default:
+		data = encodeVarintPopulateSnapshotResponse(data, uint64(key))
+		data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
+	}
+	return data
+}
+func encodeVarintPopulateSnapshotResponse(data []byte, v uint64) []byte {
+	for v >= 1<<7 {
+		data = append(data, uint8(uint64(v)&0x7f|0x80))
+		v >>= 7
+	}
+	data = append(data, uint8(v))
+	return data
+}
+func (m *SnapshotResponse) Marshal() (data []byte, err error) {
+	size := m.Size()
+	data = make([]byte, size)
+	n, err := m.MarshalTo(data)
+	if err != nil {
+		return nil, err
+	}
+	return data[:n], nil
+}
+
+func (m *SnapshotResponse) MarshalTo(data []byte) (n int, err error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Success != nil {
+		data[i] = 0x8
+		i++
+		if *m.Success {
+			data[i] = 1
+		} else {
+			data[i] = 0
+		}
+		i++
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(data[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+func encodeFixed64SnapshotResponse(data []byte, offset int, v uint64) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	data[offset+4] = uint8(v >> 32)
+	data[offset+5] = uint8(v >> 40)
+	data[offset+6] = uint8(v >> 48)
+	data[offset+7] = uint8(v >> 56)
+	return offset + 8
+}
+func encodeFixed32SnapshotResponse(data []byte, offset int, v uint32) int {
+	data[offset] = uint8(v)
+	data[offset+1] = uint8(v >> 8)
+	data[offset+2] = uint8(v >> 16)
+	data[offset+3] = uint8(v >> 24)
+	return offset + 4
+}
+func encodeVarintSnapshotResponse(data []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		data[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	data[offset] = uint8(v)
+	return offset + 1
+}
+func (this *SnapshotResponse) GoString() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings17.Join([]string{`&protobuf.SnapshotResponse{` + `Success:` + valueToGoStringSnapshotResponse(this.Success, "bool"), `XXX_unrecognized:` + fmt25.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
+	return s
+}
+func valueToGoStringSnapshotResponse(v interface{}, typ string) string {
+	rv := reflect17.ValueOf(v)
+	if rv.IsNil() {
+		return "nil"
+	}
+	pv := reflect17.Indirect(rv).Interface()
+	return fmt25.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
+}
+func extensionToGoStringSnapshotResponse(e map[int32]code_google_com_p_gogoprotobuf_proto17.Extension) string {
+	if e == nil {
+		return "nil"
+	}
+	s := "map[int32]proto.Extension{"
+	keys := make([]int, 0, len(e))
+	for k := range e {
+		keys = append(keys, int(k))
+	}
+	sort8.Ints(keys)
+	ss := []string{}
+	for _, k := range keys {
+		ss = append(ss, strconv8.Itoa(k)+": "+e[int32(k)].GoString())
+	}
+	s += strings17.Join(ss, ",") + "}"
+	return s
+}
+func (this *SnapshotResponse) VerboseEqual(that interface{}) error {
+	if that == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt26.Errorf("that == nil && this != nil")
+	}
+
+	that1, ok := that.(*SnapshotResponse)
+	if !ok {
+		return fmt26.Errorf("that is not of type *SnapshotResponse")
+	}
+	if that1 == nil {
+		if this == nil {
+			return nil
+		}
+		return fmt26.Errorf("that is type *SnapshotResponse but is nil && this != nil")
+	} else if this == nil {
+		return fmt26.Errorf("that is type *SnapshotResponsebut is not nil && this == nil")
+	}
+	if this.Success != nil && that1.Success != nil {
+		if *this.Success != *that1.Success {
+			return fmt26.Errorf("Success this(%v) Not Equal that(%v)", *this.Success, *that1.Success)
+		}
+	} else if this.Success != nil {
+		return fmt26.Errorf("this.Success == nil && that.Success != nil")
+	} else if that1.Success != nil {
+		return fmt26.Errorf("Success this(%v) Not Equal that(%v)", this.Success, that1.Success)
+	}
+	if !bytes8.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return fmt26.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
+	}
+	return nil
+}
+func (this *SnapshotResponse) Equal(that interface{}) bool {
+	if that == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	}
+
+	that1, ok := that.(*SnapshotResponse)
+	if !ok {
+		return false
+	}
+	if that1 == nil {
+		if this == nil {
+			return true
+		}
+		return false
+	} else if this == nil {
+		return false
+	}
+	if this.Success != nil && that1.Success != nil {
+		if *this.Success != *that1.Success {
+			return false
+		}
+	} else if this.Success != nil {
+		return false
+	} else if that1.Success != nil {
+		return false
+	}
+	if !bytes8.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+		return false
+	}
+	return true
+}

+ 15 - 1
third_party/github.com/coreos/raft/protobuf/snapshot_response.proto

@@ -1,5 +1,19 @@
 package protobuf;
 
-message ProtoSnapshotResponse {
+import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
+
+option (gogoproto.gostring_all) = true;
+option (gogoproto.equal_all) = true;
+option (gogoproto.verbose_equal_all) = true;
+option (gogoproto.goproto_stringer_all) = false;
+option (gogoproto.stringer_all) =  true;
+option (gogoproto.populate_all) = true;
+option (gogoproto.testgen_all) = true;
+option (gogoproto.benchgen_all) = true;
+option (gogoproto.marshaler_all) = true;
+option (gogoproto.sizer_all) = true;
+option (gogoproto.unmarshaler_all) = true;
+
+message SnapshotResponse {
 	required bool Success=1;
 }

+ 5 - 4
third_party/github.com/coreos/raft/request_vote_request.go

@@ -1,10 +1,11 @@
 package raft
 
 import (
-	"github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
-	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 	"io"
 	"io/ioutil"
+
+	"github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 )
 
 // The request sent to a server to vote for a candidate to become a leader.
@@ -29,7 +30,7 @@ func newRequestVoteRequest(term uint64, candidateName string, lastLogIndex uint6
 // Encodes the RequestVoteRequest to a buffer. Returns the number of bytes
 // written and any error that may have occurred.
 func (req *RequestVoteRequest) Encode(w io.Writer) (int, error) {
-	pb := &protobuf.ProtoRequestVoteRequest{
+	pb := &protobuf.RequestVoteRequest{
 		Term:		proto.Uint64(req.Term),
 		LastLogIndex:	proto.Uint64(req.LastLogIndex),
 		LastLogTerm:	proto.Uint64(req.LastLogTerm),
@@ -54,7 +55,7 @@ func (req *RequestVoteRequest) Decode(r io.Reader) (int, error) {
 
 	totalBytes := len(data)
 
-	pb := &protobuf.ProtoRequestVoteRequest{}
+	pb := &protobuf.RequestVoteRequest{}
 	if err = proto.Unmarshal(data, pb); err != nil {
 		return -1, err
 	}

+ 5 - 4
third_party/github.com/coreos/raft/request_vote_response.go

@@ -1,10 +1,11 @@
 package raft
 
 import (
-	"github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
-	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 	"io"
 	"io/ioutil"
+
+	"github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 )
 
 // The response returned from a server after a vote for a candidate to become a leader.
@@ -25,7 +26,7 @@ func newRequestVoteResponse(term uint64, voteGranted bool) *RequestVoteResponse
 // Encodes the RequestVoteResponse to a buffer. Returns the number of bytes
 // written and any error that may have occurred.
 func (resp *RequestVoteResponse) Encode(w io.Writer) (int, error) {
-	pb := &protobuf.ProtoRequestVoteResponse{
+	pb := &protobuf.RequestVoteResponse{
 		Term:		proto.Uint64(resp.Term),
 		VoteGranted:	proto.Bool(resp.VoteGranted),
 	}
@@ -49,7 +50,7 @@ func (resp *RequestVoteResponse) Decode(r io.Reader) (int, error) {
 
 	totalBytes := len(data)
 
-	pb := &protobuf.ProtoRequestVoteResponse{}
+	pb := &protobuf.RequestVoteResponse{}
 	if err = proto.Unmarshal(data, pb); err != nil {
 		return -1, err
 	}

+ 93 - 119
third_party/github.com/coreos/raft/server.go

@@ -33,8 +33,11 @@ const (
 )
 
 const (
-	DefaultHeartbeatTimeout = 50 * time.Millisecond
-	DefaultElectionTimeout  = 150 * time.Millisecond
+	// DefaultHeartbeatInterval is the interval that the leader will send
+	// AppendEntriesRequests to followers to maintain leadership.
+	DefaultHeartbeatInterval = 50 * time.Millisecond
+
+	DefaultElectionTimeout = 150 * time.Millisecond
 )
 
 // ElectionTimeoutThresholdPercent specifies the threshold at which the server
@@ -82,8 +85,8 @@ type Server interface {
 	GetState() string
 	ElectionTimeout() time.Duration
 	SetElectionTimeout(duration time.Duration)
-	HeartbeatTimeout() time.Duration
-	SetHeartbeatTimeout(duration time.Duration)
+	HeartbeatInterval() time.Duration
+	SetHeartbeatInterval(duration time.Duration)
 	Transporter() Transporter
 	SetTransporter(t Transporter)
 	AppendEntries(req *AppendEntriesRequest) *AppendEntriesResponse
@@ -119,10 +122,10 @@ type server struct {
 	mutex      sync.RWMutex
 	syncedPeer map[string]bool
 
-	stopped          chan bool
-	c                chan *ev
-	electionTimeout  time.Duration
-	heartbeatTimeout time.Duration
+	stopped           chan bool
+	c                 chan *ev
+	electionTimeout   time.Duration
+	heartbeatInterval time.Duration
 
 	currentSnapshot         *Snapshot
 	lastSnapshot            *Snapshot
@@ -170,7 +173,7 @@ func NewServer(name string, path string, transporter Transporter, stateMachine S
 		stopped:                 make(chan bool),
 		c:                       make(chan *ev, 256),
 		electionTimeout:         DefaultElectionTimeout,
-		heartbeatTimeout:        DefaultHeartbeatTimeout,
+		heartbeatInterval:       DefaultHeartbeatInterval,
 		maxLogEntriesPerRequest: MaxLogEntriesPerRequest,
 		connectionString:        connectionString,
 	}
@@ -378,20 +381,20 @@ func (s *server) SetElectionTimeout(duration time.Duration) {
 //--------------------------------------
 
 // Retrieves the heartbeat timeout.
-func (s *server) HeartbeatTimeout() time.Duration {
+func (s *server) HeartbeatInterval() time.Duration {
 	s.mutex.RLock()
 	defer s.mutex.RUnlock()
-	return s.heartbeatTimeout
+	return s.heartbeatInterval
 }
 
 // Sets the heartbeat timeout.
-func (s *server) SetHeartbeatTimeout(duration time.Duration) {
+func (s *server) SetHeartbeatInterval(duration time.Duration) {
 	s.mutex.Lock()
 	defer s.mutex.Unlock()
 
-	s.heartbeatTimeout = duration
+	s.heartbeatInterval = duration
 	for _, peer := range s.peers {
-		peer.setHeartbeatTimeout(duration)
+		peer.setHeartbeatInterval(duration)
 	}
 }
 
@@ -495,6 +498,14 @@ func (s *server) setCurrentTerm(term uint64, leaderName string, append bool) {
 	prevLeader := s.leader
 
 	if term > s.currentTerm {
+		// stop heartbeats before step-down
+		if s.state == Leader {
+			s.mutex.Unlock()
+			for _, peer := range s.peers {
+				peer.stopHeartbeat(false)
+			}
+			s.mutex.Lock()
+		}
 		// update the term and clear vote for
 		s.state = Follower
 		s.currentTerm = term
@@ -599,7 +610,7 @@ func (s *server) followerLoop() {
 	electionTimeout := s.ElectionTimeout()
 	timeoutChan := afterBetween(s.ElectionTimeout(), s.ElectionTimeout()*2)
 
-	for {
+	for s.State() == Follower {
 		var err error
 		update := false
 		select {
@@ -654,11 +665,6 @@ func (s *server) followerLoop() {
 			since = time.Now()
 			timeoutChan = afterBetween(s.ElectionTimeout(), s.ElectionTimeout()*2)
 		}
-
-		// Exit loop on state change.
-		if s.State() != Follower {
-			break
-		}
 	}
 }
 
@@ -673,7 +679,7 @@ func (s *server) candidateLoop() {
 		s.DispatchEvent(newEvent(LeaderChangeEventType, s.leader, prevLeader))
 	}
 
-	for {
+	for s.State() == Candidate {
 		// Increment current term, vote for self.
 		s.currentTerm++
 		s.votedFor = s.name
@@ -741,12 +747,6 @@ func (s *server) candidateLoop() {
 				break
 			}
 		}
-
-		// break when we are not candidate
-		if s.State() != Candidate {
-			break
-		}
-
 		// continue when timeout happened
 	}
 }
@@ -763,14 +763,22 @@ func (s *server) leaderLoop() {
 		peer.startHeartbeat()
 	}
 
+	// Commit a NOP after the server becomes leader. From the Raft paper:
+	// "Upon election: send initial empty AppendEntries RPCs (heartbeat) to
+	// each server; repeat during idle periods to prevent election timeouts
+	// (§5.2)". The heartbeats started above do the "idle" period work.
 	go s.Do(NOPCommand{})
 
 	// Begin to collect response from followers
-	for {
+	for s.State() == Leader {
 		var err error
 		select {
 		case e := <-s.c:
 			if e.target == &stopValue {
+				// Stop all peers before stop
+				for _, peer := range s.peers {
+					peer.stopHeartbeat(false)
+				}
 				s.setState(Stopped)
 			} else {
 				switch req := e.target.(type) {
@@ -789,16 +797,6 @@ func (s *server) leaderLoop() {
 			// Callback to event.
 			e.c <- err
 		}
-
-		// Exit loop on state change.
-		if s.State() != Leader {
-			break
-		}
-	}
-
-	// Stop all peers.
-	for _, peer := range s.peers {
-		peer.stopHeartbeat(false)
 	}
 
 	s.syncedPeer = nil
@@ -807,7 +805,7 @@ func (s *server) leaderLoop() {
 func (s *server) snapshotLoop() {
 	s.setState(Snapshotting)
 
-	for {
+	for s.State() == Snapshotting {
 		var err error
 
 		e := <-s.c
@@ -828,11 +826,6 @@ func (s *server) snapshotLoop() {
 		}
 		// Callback to event.
 		e.c <- err
-
-		// Exit loop on state change.
-		if s.State() != Snapshotting {
-			break
-		}
 	}
 }
 
@@ -924,15 +917,14 @@ func (s *server) processAppendEntriesRequest(req *AppendEntriesRequest) (*Append
 // processed when the server is a leader. Responses received during other
 // states are dropped.
 func (s *server) processAppendEntriesResponse(resp *AppendEntriesResponse) {
-
 	// If we find a higher term then change to a follower and exit.
-	if resp.Term > s.Term() {
-		s.setCurrentTerm(resp.Term, "", false)
+	if resp.Term() > s.Term() {
+		s.setCurrentTerm(resp.Term(), "", false)
 		return
 	}
 
 	// panic response if it's not successful.
-	if !resp.Success {
+	if !resp.Success() {
 		return
 	}
 
@@ -1029,7 +1021,7 @@ func (s *server) AddPeer(name string, connectiongString string) error {
 
 	// Skip the Peer if it has the same name as the Server
 	if s.name != name {
-		peer := newPeer(s, name, connectiongString, s.heartbeatTimeout)
+		peer := newPeer(s, name, connectiongString, s.heartbeatInterval)
 
 		if s.State() == Leader {
 			peer.startHeartbeat()
@@ -1079,57 +1071,48 @@ func (s *server) RemovePeer(name string) error {
 //--------------------------------------
 
 func (s *server) TakeSnapshot() error {
-	//TODO put a snapshot mutex
+	// TODO: put a snapshot mutex
 	s.debugln("take Snapshot")
+
+	// Exit if the server is currently creating a snapshot.
 	if s.currentSnapshot != nil {
 		return errors.New("handling snapshot")
 	}
 
+	// Exit if there are no logs yet in the system.
 	lastIndex, lastTerm := s.log.commitInfo()
-
+	path := s.SnapshotPath(lastIndex, lastTerm)
 	if lastIndex == 0 {
 		return errors.New("No logs")
 	}
 
-	path := s.SnapshotPath(lastIndex, lastTerm)
-
 	var state []byte
 	var err error
-
 	if s.stateMachine != nil {
 		state, err = s.stateMachine.Save()
-
 		if err != nil {
 			return err
 		}
-
 	} else {
 		state = []byte{0}
 	}
 
-	peers := make([]*Peer, len(s.peers)+1)
-
-	i := 0
+	// Clone the list of peers.
+	peers := make([]*Peer, 0, len(s.peers)+1)
 	for _, peer := range s.peers {
-		peers[i] = peer.clone()
-		i++
-	}
-
-	peers[i] = &Peer{
-		Name:             s.Name(),
-		ConnectionString: s.connectionString,
+		peers = append(peers, peer.clone())
 	}
+	peers = append(peers, &Peer{Name: s.Name(), ConnectionString: s.connectionString})
 
+	// Attach current snapshot and save it to disk.
 	s.currentSnapshot = &Snapshot{lastIndex, lastTerm, peers, state, path}
-
 	s.saveSnapshot()
 
-	// We keep some log entries after the snapshot
-	// We do not want to send the whole snapshot
-	// to the slightly slow machines
+	// We keep some log entries after the snapshot.
+	// We do not want to send the whole snapshot to the slightly slow machines
 	if lastIndex-s.log.startIndex > NumberOfLogEntriesAfterSnapshot {
 		compactIndex := lastIndex - NumberOfLogEntriesAfterSnapshot
-		compactTerm := s.log.getEntry(compactIndex).Term
+		compactTerm := s.log.getEntry(compactIndex).Term()
 		s.log.compact(compactIndex, compactTerm)
 	}
 
@@ -1138,25 +1121,25 @@ func (s *server) TakeSnapshot() error {
 
 // Retrieves the log path for the server.
 func (s *server) saveSnapshot() error {
-
 	if s.currentSnapshot == nil {
 		return errors.New("no snapshot to save")
 	}
 
-	err := s.currentSnapshot.save()
-
-	if err != nil {
+	// Write snapshot to disk.
+	if err := s.currentSnapshot.save(); err != nil {
 		return err
 	}
 
+	// Swap the current and last snapshots.
 	tmp := s.lastSnapshot
 	s.lastSnapshot = s.currentSnapshot
 
-	// delete the previous snapshot if there is any change
+	// Delete the previous snapshot if there is any change
 	if tmp != nil && !(tmp.LastIndex == s.lastSnapshot.LastIndex && tmp.LastTerm == s.lastSnapshot.LastTerm) {
 		tmp.remove()
 	}
 	s.currentSnapshot = nil
+
 	return nil
 }
 
@@ -1172,18 +1155,16 @@ func (s *server) RequestSnapshot(req *SnapshotRequest) *SnapshotResponse {
 }
 
 func (s *server) processSnapshotRequest(req *SnapshotRequest) *SnapshotResponse {
-
 	// If the follower’s log contains an entry at the snapshot’s last index with a term
-	// that matches the snapshot’s last term
-	// Then the follower already has all the information found in the snapshot
-	// and can reply false
-
+	// that matches the snapshot’s last term, then the follower already has all the
+	// information found in the snapshot and can reply false.
 	entry := s.log.getEntry(req.LastIndex)
 
-	if entry != nil && entry.Term == req.LastTerm {
+	if entry != nil && entry.Term() == req.LastTerm {
 		return newSnapshotResponse(false)
 	}
 
+	// Update state.
 	s.setState(Snapshotting)
 
 	return newSnapshotResponse(true)
@@ -1196,29 +1177,26 @@ func (s *server) SnapshotRecoveryRequest(req *SnapshotRecoveryRequest) *Snapshot
 }
 
 func (s *server) processSnapshotRecoveryRequest(req *SnapshotRecoveryRequest) *SnapshotRecoveryResponse {
+	// Recover state sent from request.
+	if err := s.stateMachine.Recovery(req.State); err != nil {
+		return newSnapshotRecoveryResponse(req.LastTerm, false, req.LastIndex)
+	}
 
-	s.stateMachine.Recovery(req.State)
-
-	// clear the peer map
+	// Recover the cluster configuration.
 	s.peers = make(map[string]*Peer)
-
-	// recovery the cluster configuration
 	for _, peer := range req.Peers {
 		s.AddPeer(peer.Name, peer.ConnectionString)
 	}
 
-	//update term and index
+	// Update log state.
 	s.currentTerm = req.LastTerm
-
 	s.log.updateCommitIndex(req.LastIndex)
 
-	snapshotPath := s.SnapshotPath(req.LastIndex, req.LastTerm)
-
-	s.currentSnapshot = &Snapshot{req.LastIndex, req.LastTerm, req.Peers, req.State, snapshotPath}
-
+	// Create local snapshot.
+	s.currentSnapshot = &Snapshot{req.LastIndex, req.LastTerm, req.Peers, req.State, s.SnapshotPath(req.LastIndex, req.LastTerm)}
 	s.saveSnapshot()
 
-	// clear the previous log entries
+	// Clear the previous log entries.
 	s.log.compact(req.LastIndex, req.LastTerm)
 
 	return newSnapshotRecoveryResponse(req.LastTerm, true, req.LastIndex)
@@ -1227,79 +1205,75 @@ func (s *server) processSnapshotRecoveryRequest(req *SnapshotRecoveryRequest) *S
 
 // Load a snapshot at restart
 func (s *server) LoadSnapshot() error {
+	// Open snapshot/ directory.
 	dir, err := os.OpenFile(path.Join(s.path, "snapshot"), os.O_RDONLY, 0)
 	if err != nil {
-
 		return err
 	}
 
+	// Retrieve a list of all snapshots.
 	filenames, err := dir.Readdirnames(-1)
-
 	if err != nil {
 		dir.Close()
 		panic(err)
 	}
-
 	dir.Close()
+
 	if len(filenames) == 0 {
 		return errors.New("no snapshot")
 	}
 
-	// not sure how many snapshot we should keep
+	// Grab the latest snapshot.
 	sort.Strings(filenames)
 	snapshotPath := path.Join(s.path, "snapshot", filenames[len(filenames)-1])
 
-	// should not fail
+	// Read snapshot data.
 	file, err := os.OpenFile(snapshotPath, os.O_RDONLY, 0)
-	defer file.Close()
 	if err != nil {
-		panic(err)
+		return err
 	}
+	defer file.Close()
 
-	// TODO check checksum first
-
-	var snapshotBytes []byte
+	// Check checksum.
 	var checksum uint32
-
 	n, err := fmt.Fscanf(file, "%08x\n", &checksum)
-
 	if err != nil {
 		return err
-	}
-
-	if n != 1 {
+	} else if n != 1 {
 		return errors.New("Bad snapshot file")
 	}
 
-	snapshotBytes, _ = ioutil.ReadAll(file)
-	s.debugln(string(snapshotBytes))
+	// Load remaining snapshot contents.
+	b, err := ioutil.ReadAll(file)
+	if err != nil {
+		return err
+	}
 
 	// Generate checksum.
-	byteChecksum := crc32.ChecksumIEEE(snapshotBytes)
-
+	byteChecksum := crc32.ChecksumIEEE(b)
 	if uint32(checksum) != byteChecksum {
 		s.debugln(checksum, " ", byteChecksum)
 		return errors.New("bad snapshot file")
 	}
 
-	err = json.Unmarshal(snapshotBytes, &s.lastSnapshot)
-
-	if err != nil {
+	// Decode snapshot.
+	if err = json.Unmarshal(b, &s.lastSnapshot); err != nil {
 		s.debugln("unmarshal error: ", err)
 		return err
 	}
 
-	err = s.stateMachine.Recovery(s.lastSnapshot.State)
-
-	if err != nil {
+	// Recover snapshot into state machine.
+	if err = s.stateMachine.Recovery(s.lastSnapshot.State); err != nil {
 		s.debugln("recovery error: ", err)
 		return err
 	}
 
+	// Recover cluster configuration.
 	for _, peer := range s.lastSnapshot.Peers {
 		s.AddPeer(peer.Name, peer.ConnectionString)
 	}
 
+	// Update log state.
 	s.log.startTerm = s.lastSnapshot.LastTerm
 	s.log.startIndex = s.lastSnapshot.LastIndex
 	s.log.updateCommitIndex(s.lastSnapshot.LastIndex)

+ 36 - 29
third_party/github.com/coreos/raft/server_test.go

@@ -1,21 +1,15 @@
 package raft
 
 import (
+	"bytes"
 	"encoding/json"
 	"fmt"
-	"reflect"
 	"strconv"
 	"sync"
 	"testing"
 	"time"
 )
 
-//------------------------------------------------------------------------------
-//
-// Tests
-//
-//------------------------------------------------------------------------------
-
 //--------------------------------------
 // Request Vote
 //--------------------------------------
@@ -199,7 +193,7 @@ func TestServerPromote(t *testing.T) {
 func TestServerAppendEntries(t *testing.T) {
 	s := newTestServer("1", &testTransporter{})
 
-	s.SetHeartbeatTimeout(time.Second * 10)
+	s.SetHeartbeatInterval(time.Second * 10)
 	s.Start()
 	defer s.Stop()
 
@@ -207,7 +201,7 @@ func TestServerAppendEntries(t *testing.T) {
 	e, _ := newLogEntry(nil, nil, 1, 1, &testCommand1{Val: "foo", I: 10})
 	entries := []*LogEntry{e}
 	resp := s.AppendEntries(newAppendEntriesRequest(1, 0, 0, 0, "ldr", entries))
-	if resp.Term != 1 || !resp.Success {
+	if resp.Term() != 1 || !resp.Success() {
 		t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
 	}
 	if index, term := s.(*server).log.commitInfo(); index != 0 || term != 0 {
@@ -219,7 +213,7 @@ func TestServerAppendEntries(t *testing.T) {
 	e2, _ := newLogEntry(nil, nil, 3, 1, &testCommand1{Val: "baz", I: 30})
 	entries = []*LogEntry{e1, e2}
 	resp = s.AppendEntries(newAppendEntriesRequest(1, 1, 1, 1, "ldr", entries))
-	if resp.Term != 1 || !resp.Success {
+	if resp.Term() != 1 || !resp.Success() {
 		t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
 	}
 	if index, term := s.(*server).log.commitInfo(); index != 1 || term != 1 {
@@ -228,7 +222,7 @@ func TestServerAppendEntries(t *testing.T) {
 
 	// Send zero entries and commit everything.
 	resp = s.AppendEntries(newAppendEntriesRequest(2, 3, 1, 3, "ldr", []*LogEntry{}))
-	if resp.Term != 2 || !resp.Success {
+	if resp.Term() != 2 || !resp.Success() {
 		t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
 	}
 	if index, term := s.(*server).log.commitInfo(); index != 3 || term != 1 {
@@ -251,7 +245,7 @@ func TestServerAppendEntriesWithStaleTermsAreRejected(t *testing.T) {
 	e, _ := newLogEntry(nil, nil, 1, 1, &testCommand1{Val: "foo", I: 10})
 	entries := []*LogEntry{e}
 	resp := s.AppendEntries(newAppendEntriesRequest(1, 0, 0, 0, "ldr", entries))
-	if resp.Term != 2 || resp.Success {
+	if resp.Term() != 2 || resp.Success() {
 		t.Fatalf("AppendEntries should have failed: %v/%v", resp.Term, resp.Success)
 	}
 	if index, term := s.(*server).log.commitInfo(); index != 0 || term != 0 {
@@ -270,7 +264,7 @@ func TestServerAppendEntriesRejectedIfAlreadyCommitted(t *testing.T) {
 	e2, _ := newLogEntry(nil, nil, 2, 1, &testCommand1{Val: "foo", I: 15})
 	entries := []*LogEntry{e1, e2}
 	resp := s.AppendEntries(newAppendEntriesRequest(1, 0, 0, 2, "ldr", entries))
-	if resp.Term != 1 || !resp.Success {
+	if resp.Term() != 1 || !resp.Success() {
 		t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
 	}
 
@@ -278,7 +272,7 @@ func TestServerAppendEntriesRejectedIfAlreadyCommitted(t *testing.T) {
 	e, _ := newLogEntry(nil, nil, 2, 1, &testCommand1{Val: "bar", I: 20})
 	entries = []*LogEntry{e}
 	resp = s.AppendEntries(newAppendEntriesRequest(1, 2, 1, 1, "ldr", entries))
-	if resp.Term != 1 || resp.Success {
+	if resp.Term() != 1 || resp.Success() {
 		t.Fatalf("AppendEntries should have failed: %v/%v", resp.Term, resp.Success)
 	}
 }
@@ -289,23 +283,36 @@ func TestServerAppendEntriesOverwritesUncommittedEntries(t *testing.T) {
 	s.Start()
 	defer s.Stop()
 
-	entry1, _ := newLogEntry(nil, nil, 1, 1, &testCommand1{Val: "foo", I: 10})
-	entry2, _ := newLogEntry(nil, nil, 2, 1, &testCommand1{Val: "foo", I: 15})
-	entry3, _ := newLogEntry(nil, nil, 2, 2, &testCommand1{Val: "bar", I: 20})
+	entry1, _ := newLogEntry(s.(*server).log, nil, 1, 1, &testCommand1{Val: "foo", I: 10})
+	entry2, _ := newLogEntry(s.(*server).log, nil, 2, 1, &testCommand1{Val: "foo", I: 15})
+	entry3, _ := newLogEntry(s.(*server).log, nil, 2, 2, &testCommand1{Val: "bar", I: 20})
 
 	// Append single entry + commit.
 	entries := []*LogEntry{entry1, entry2}
 	resp := s.AppendEntries(newAppendEntriesRequest(1, 0, 0, 1, "ldr", entries))
-	if resp.Term != 1 || !resp.Success || s.(*server).log.commitIndex != 1 || !reflect.DeepEqual(s.(*server).log.entries, []*LogEntry{entry1, entry2}) {
+	if resp.Term() != 1 || !resp.Success() || s.(*server).log.commitIndex != 1 {
 		t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
 	}
 
+	for i, entry := range s.(*server).log.entries {
+		if entry.Term() != entries[i].Term() || entry.Index() != entries[i].Index() || !bytes.Equal(entry.Command(), entries[i].Command()) {
+			t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
+		}
+	}
+
 	// Append entry that overwrites the second (uncommitted) entry.
 	entries = []*LogEntry{entry3}
 	resp = s.AppendEntries(newAppendEntriesRequest(2, 1, 1, 2, "ldr", entries))
-	if resp.Term != 2 || !resp.Success || s.(*server).log.commitIndex != 2 || !reflect.DeepEqual(s.(*server).log.entries, []*LogEntry{entry1, entry3}) {
+	if resp.Term() != 2 || !resp.Success() || s.(*server).log.commitIndex != 2 {
 		t.Fatalf("AppendEntries should have succeeded: %v/%v", resp.Term, resp.Success)
 	}
+
+	entries = []*LogEntry{entry1, entry3}
+	for i, entry := range s.(*server).log.entries {
+		if entry.Term() != entries[i].Term() || entry.Index() != entries[i].Index() || !bytes.Equal(entry.Command(), entries[i].Command()) {
+			t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
+		}
+	}
 }
 
 //--------------------------------------
@@ -386,14 +393,14 @@ func TestServerRecoverFromPreviousLogAndConf(t *testing.T) {
 
 		if name == "1" {
 			leader = s
-			s.SetHeartbeatTimeout(testHeartbeatTimeout)
+			s.SetHeartbeatInterval(testHeartbeatInterval)
 			s.Start()
-			time.Sleep(testHeartbeatTimeout)
+			time.Sleep(testHeartbeatInterval)
 		} else {
 			s.SetElectionTimeout(testElectionTimeout)
-			s.SetHeartbeatTimeout(testHeartbeatTimeout)
+			s.SetHeartbeatInterval(testHeartbeatInterval)
 			s.Start()
-			time.Sleep(testHeartbeatTimeout)
+			time.Sleep(testHeartbeatInterval)
 		}
 		if _, err := leader.Do(&DefaultJoinCommand{Name: name}); err != nil {
 			t.Fatalf("Unable to join server[%s]: %v", name, err)
@@ -408,7 +415,7 @@ func TestServerRecoverFromPreviousLogAndConf(t *testing.T) {
 		}
 	}
 
-	time.Sleep(2 * testHeartbeatTimeout)
+	time.Sleep(2 * testHeartbeatInterval)
 
 	for _, name := range names {
 		s := servers[name]
@@ -466,7 +473,7 @@ func TestServerSingleNode(t *testing.T) {
 
 	s.Start()
 
-	time.Sleep(testHeartbeatTimeout)
+	time.Sleep(testHeartbeatInterval)
 
 	// Join the server to itself.
 	if _, err := s.Do(&DefaultJoinCommand{Name: "1"}); err != nil {
@@ -566,14 +573,14 @@ func TestServerMultiNode(t *testing.T) {
 
 		if name == "1" {
 			leader = s
-			s.SetHeartbeatTimeout(testHeartbeatTimeout)
+			s.SetHeartbeatInterval(testHeartbeatInterval)
 			s.Start()
-			time.Sleep(testHeartbeatTimeout)
+			time.Sleep(testHeartbeatInterval)
 		} else {
 			s.SetElectionTimeout(testElectionTimeout)
-			s.SetHeartbeatTimeout(testHeartbeatTimeout)
+			s.SetHeartbeatInterval(testHeartbeatInterval)
 			s.Start()
-			time.Sleep(testHeartbeatTimeout)
+			time.Sleep(testHeartbeatInterval)
 		}
 		if _, err := leader.Do(&DefaultJoinCommand{Name: name}); err != nil {
 			t.Fatalf("Unable to join server[%s]: %v", name, err)

+ 22 - 25
third_party/github.com/coreos/raft/snapshot.go

@@ -1,64 +1,61 @@
 package raft
 
 import (
-	//"bytes"
 	"encoding/json"
 	"fmt"
 	"hash/crc32"
 	"os"
 )
 
-//------------------------------------------------------------------------------
-//
-// Typedefs
-//
-//------------------------------------------------------------------------------
-
-// the in memory SnapShot struct
-// TODO add cluster configuration
+// Snapshot represents an in-memory representation of the current state of the system.
 type Snapshot struct {
 	LastIndex uint64 `json:"lastIndex"`
 	LastTerm  uint64 `json:"lastTerm"`
-	// cluster configuration.
+
+	// Cluster configuration.
 	Peers []*Peer `json:"peers"`
 	State []byte  `json:"state"`
 	Path  string  `json:"path"`
 }
 
-// Save the snapshot to a file
+// save writes the snapshot to file.
 func (ss *Snapshot) save() error {
-	// Write machine state to temporary buffer.
-
-	// open file
+	// Open the file for writing.
 	file, err := os.OpenFile(ss.Path, os.O_CREATE|os.O_WRONLY, 0600)
-
 	if err != nil {
 		return err
 	}
-
 	defer file.Close()
 
+	// Serialize to JSON.
 	b, err := json.Marshal(ss)
+	if err != nil {
+		return err
+	}
 
-	// Generate checksum.
+	// Generate checksum and write it to disk.
 	checksum := crc32.ChecksumIEEE(b)
-
-	// Write snapshot with checksum.
 	if _, err = fmt.Fprintf(file, "%08x\n", checksum); err != nil {
 		return err
 	}
 
+	// Write the snapshot to disk.
 	if _, err = file.Write(b); err != nil {
 		return err
 	}
 
-	// force the change writing to disk
-	file.Sync()
-	return err
+	// Ensure that the snapshot has been flushed to disk before continuing.
+	if err := file.Sync(); err != nil {
+		return err
+	}
+
+	return nil
 }
 
-// remove the file of the snapshot
+// remove deletes the snapshot file.
 func (ss *Snapshot) remove() error {
-	err := os.Remove(ss.Path)
-	return err
+	if err := os.Remove(ss.Path); err != nil {
+		return err
+	}
+	return nil
 }

+ 7 - 12
third_party/github.com/coreos/raft/snapshot_recovery_request.go

@@ -1,10 +1,11 @@
 package raft
 
 import (
-	"github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
-	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 	"io"
 	"io/ioutil"
+
+	"github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 )
 
 // The request sent to a server to start from the snapshot.
@@ -16,12 +17,6 @@ type SnapshotRecoveryRequest struct {
 	State		[]byte
 }
 
-//------------------------------------------------------------------------------
-//
-// Constructors
-//
-//------------------------------------------------------------------------------
-
 // Creates a new Snapshot request.
 func newSnapshotRecoveryRequest(leaderName string, snapshot *Snapshot) *SnapshotRecoveryRequest {
 	return &SnapshotRecoveryRequest{
@@ -37,16 +32,16 @@ func newSnapshotRecoveryRequest(leaderName string, snapshot *Snapshot) *Snapshot
 // written and any error that may have occurred.
 func (req *SnapshotRecoveryRequest) Encode(w io.Writer) (int, error) {
 
-	protoPeers := make([]*protobuf.ProtoSnapshotRecoveryRequest_ProtoPeer, len(req.Peers))
+	protoPeers := make([]*protobuf.SnapshotRecoveryRequest_Peer, len(req.Peers))
 
 	for i, peer := range req.Peers {
-		protoPeers[i] = &protobuf.ProtoSnapshotRecoveryRequest_ProtoPeer{
+		protoPeers[i] = &protobuf.SnapshotRecoveryRequest_Peer{
 			Name:			proto.String(peer.Name),
 			ConnectionString:	proto.String(peer.ConnectionString),
 		}
 	}
 
-	pb := &protobuf.ProtoSnapshotRecoveryRequest{
+	pb := &protobuf.SnapshotRecoveryRequest{
 		LeaderName:	proto.String(req.LeaderName),
 		LastIndex:	proto.Uint64(req.LastIndex),
 		LastTerm:	proto.Uint64(req.LastTerm),
@@ -72,7 +67,7 @@ func (req *SnapshotRecoveryRequest) Decode(r io.Reader) (int, error) {
 
 	totalBytes := len(data)
 
-	pb := &protobuf.ProtoSnapshotRecoveryRequest{}
+	pb := &protobuf.SnapshotRecoveryRequest{}
 	if err = proto.Unmarshal(data, pb); err != nil {
 		return -1, err
 	}

+ 8 - 14
third_party/github.com/coreos/raft/snapshot_recovery_response.go

@@ -1,10 +1,11 @@
 package raft
 
 import (
-	"github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
-	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 	"io"
 	"io/ioutil"
+
+	"github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 )
 
 // The response returned from a server appending entries to the log.
@@ -14,12 +15,6 @@ type SnapshotRecoveryResponse struct {
 	CommitIndex	uint64
 }
 
-//------------------------------------------------------------------------------
-//
-// Constructors
-//
-//------------------------------------------------------------------------------
-
 // Creates a new Snapshot response.
 func newSnapshotRecoveryResponse(term uint64, success bool, commitIndex uint64) *SnapshotRecoveryResponse {
 	return &SnapshotRecoveryResponse{
@@ -29,10 +24,10 @@ func newSnapshotRecoveryResponse(term uint64, success bool, commitIndex uint64)
 	}
 }
 
-// Encodes the SnapshotRecoveryResponse to a buffer. Returns the number of bytes
-// written and any error that may have occurred.
+// Encode writes the response to a writer.
+// Returns the number of bytes written and any error that occurs.
 func (req *SnapshotRecoveryResponse) Encode(w io.Writer) (int, error) {
-	pb := &protobuf.ProtoSnapshotRecoveryResponse{
+	pb := &protobuf.SnapshotRecoveryResponse{
 		Term:		proto.Uint64(req.Term),
 		Success:	proto.Bool(req.Success),
 		CommitIndex:	proto.Uint64(req.CommitIndex),
@@ -45,8 +40,7 @@ func (req *SnapshotRecoveryResponse) Encode(w io.Writer) (int, error) {
 	return w.Write(p)
 }
 
-// Decodes the SnapshotRecoveryResponse from a buffer. Returns the number of bytes read and
-// any error that occurs.
+// Decodes the SnapshotRecoveryResponse from a buffer.
 func (req *SnapshotRecoveryResponse) Decode(r io.Reader) (int, error) {
 	data, err := ioutil.ReadAll(r)
 
@@ -56,7 +50,7 @@ func (req *SnapshotRecoveryResponse) Decode(r io.Reader) (int, error) {
 
 	totalBytes := len(data)
 
-	pb := &protobuf.ProtoSnapshotRecoveryResponse{}
+	pb := &protobuf.SnapshotRecoveryResponse{}
 	if err := proto.Unmarshal(data, pb); err != nil {
 		return -1, err
 	}

+ 5 - 10
third_party/github.com/coreos/raft/snapshot_request.go

@@ -1,10 +1,11 @@
 package raft
 
 import (
-	"github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
-	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 	"io"
 	"io/ioutil"
+
+	"github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 )
 
 // The request sent to a server to start from the snapshot.
@@ -14,12 +15,6 @@ type SnapshotRequest struct {
 	LastTerm	uint64
 }
 
-//------------------------------------------------------------------------------
-//
-// Constructors
-//
-//------------------------------------------------------------------------------
-
 // Creates a new Snapshot request.
 func newSnapshotRequest(leaderName string, snapshot *Snapshot) *SnapshotRequest {
 	return &SnapshotRequest{
@@ -32,7 +27,7 @@ func newSnapshotRequest(leaderName string, snapshot *Snapshot) *SnapshotRequest
 // Encodes the SnapshotRequest to a buffer. Returns the number of bytes
 // written and any error that may have occurred.
 func (req *SnapshotRequest) Encode(w io.Writer) (int, error) {
-	pb := &protobuf.ProtoSnapshotRequest{
+	pb := &protobuf.SnapshotRequest{
 		LeaderName:	proto.String(req.LeaderName),
 		LastIndex:	proto.Uint64(req.LastIndex),
 		LastTerm:	proto.Uint64(req.LastTerm),
@@ -56,7 +51,7 @@ func (req *SnapshotRequest) Decode(r io.Reader) (int, error) {
 
 	totalBytes := len(data)
 
-	pb := &protobuf.ProtoSnapshotRequest{}
+	pb := &protobuf.SnapshotRequest{}
 
 	if err := proto.Unmarshal(data, pb); err != nil {
 		return -1, err

+ 5 - 10
third_party/github.com/coreos/raft/snapshot_response.go

@@ -1,10 +1,11 @@
 package raft
 
 import (
-	"github.com/coreos/etcd/third_party/code.google.com/p/goprotobuf/proto"
-	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 	"io"
 	"io/ioutil"
+
+	"github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto"
+	"github.com/coreos/etcd/third_party/github.com/coreos/raft/protobuf"
 )
 
 // The response returned if the follower entered snapshot state
@@ -12,12 +13,6 @@ type SnapshotResponse struct {
 	Success bool `json:"success"`
 }
 
-//------------------------------------------------------------------------------
-//
-// Constructors
-//
-//------------------------------------------------------------------------------
-
 // Creates a new Snapshot response.
 func newSnapshotResponse(success bool) *SnapshotResponse {
 	return &SnapshotResponse{
@@ -28,7 +23,7 @@ func newSnapshotResponse(success bool) *SnapshotResponse {
 // Encodes the SnapshotResponse to a buffer. Returns the number of bytes
 // written and any error that may have occurred.
 func (resp *SnapshotResponse) Encode(w io.Writer) (int, error) {
-	pb := &protobuf.ProtoSnapshotResponse{
+	pb := &protobuf.SnapshotResponse{
 		Success: proto.Bool(resp.Success),
 	}
 	p, err := proto.Marshal(pb)
@@ -50,7 +45,7 @@ func (resp *SnapshotResponse) Decode(r io.Reader) (int, error) {
 
 	totalBytes := len(data)
 
-	pb := &protobuf.ProtoSnapshotResponse{}
+	pb := &protobuf.SnapshotResponse{}
 	if err := proto.Unmarshal(data, pb); err != nil {
 		return -1, err
 	}

+ 73 - 0
third_party/github.com/coreos/raft/snapshot_test.go

@@ -0,0 +1,73 @@
+package raft
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/mock"
+)
+
+// Ensure that a snapshot occurs when there are existing logs.
+func TestSnapshot(t *testing.T) {
+	runServerWithMockStateMachine(Leader, func(s Server, m *mock.Mock) {
+		m.On("Save").Return([]byte("foo"), nil)
+		m.On("Recovery", []byte("foo")).Return(nil)
+
+		s.Do(&testCommand1{})
+		err := s.TakeSnapshot()
+		assert.NoError(t, err)
+		assert.Equal(t, s.(*server).lastSnapshot.LastIndex, uint64(2))
+
+		// Repeat to make sure new snapshot gets created.
+		s.Do(&testCommand1{})
+		err = s.TakeSnapshot()
+		assert.NoError(t, err)
+		assert.Equal(t, s.(*server).lastSnapshot.LastIndex, uint64(4))
+
+		// Restart server.
+		s.Stop()
+		s.Start()
+
+		// Recover from snapshot.
+		err = s.LoadSnapshot()
+		assert.NoError(t, err)
+	})
+}
+
+// Ensure that a snapshot request can be sent and received.
+func TestSnapshotRequest(t *testing.T) {
+	runServerWithMockStateMachine(Follower, func(s Server, m *mock.Mock) {
+		m.On("Recovery", []byte("bar")).Return(nil)
+
+		// Send snapshot request.
+		resp := s.RequestSnapshot(&SnapshotRequest{LastIndex: 5, LastTerm: 1})
+		assert.Equal(t, resp.Success, true)
+		assert.Equal(t, s.State(), Snapshotting)
+
+		// Send recovery request.
+		resp2 := s.SnapshotRecoveryRequest(&SnapshotRecoveryRequest{
+			LeaderName: "1",
+			LastIndex:  5,
+			LastTerm:   2,
+			Peers:      make([]*Peer, 0),
+			State:      []byte("bar"),
+		})
+		assert.Equal(t, resp2.Success, true)
+	})
+}
+
+func runServerWithMockStateMachine(state string, fn func(s Server, m *mock.Mock)) {
+	var m mockStateMachine
+	s := newTestServer("1", &testTransporter{})
+	s.(*server).stateMachine = &m
+	if err := s.Start(); err != nil {
+		panic("server start error: " + err.Error())
+	}
+	if state == Leader {
+		if _, err := s.Do(&DefaultJoinCommand{Name: s.Name()}); err != nil {
+			panic("unable to join server to self: " + err.Error())
+		}
+	}
+	defer s.Stop()
+	fn(s, &m.Mock)
+}

+ 0 - 6
third_party/github.com/coreos/raft/statemachine.go

@@ -1,11 +1,5 @@
 package raft
 
-//------------------------------------------------------------------------------
-//
-// Typedefs
-//
-//------------------------------------------------------------------------------
-
 // StateMachine is the interface for allowing the host application to save and
 // recovery the state machine. This makes it possible to make snapshots
 // and compact the log.

+ 19 - 0
third_party/github.com/coreos/raft/statemachine_test.go

@@ -0,0 +1,19 @@
+package raft
+
+import (
+	"github.com/stretchr/testify/mock"
+)
+
+type mockStateMachine struct {
+	mock.Mock
+}
+
+func (m *mockStateMachine) Save() ([]byte, error) {
+	args := m.Called()
+	return args.Get(0).([]byte), args.Error(1)
+}
+
+func (m *mockStateMachine) Recovery(b []byte) error {
+	args := m.Called(b)
+	return args.Error(0)
+}

+ 3 - 3
third_party/github.com/coreos/raft/test.go

@@ -8,8 +8,8 @@ import (
 )
 
 const (
-	testHeartbeatTimeout = 50 * time.Millisecond
-	testElectionTimeout  = 200 * time.Millisecond
+	testHeartbeatInterval = 50 * time.Millisecond
+	testElectionTimeout   = 200 * time.Millisecond
 )
 
 const (
@@ -115,7 +115,7 @@ func newTestCluster(names []string, transporter Transporter, lookup map[string]S
 		lookup[name] = server
 	}
 	for _, server := range servers {
-		server.SetHeartbeatTimeout(testHeartbeatTimeout)
+		server.SetHeartbeatInterval(testHeartbeatInterval)
 		server.Start()
 		for _, peer := range servers {
 			server.AddPeer(peer.Name(), "")